diff --git a/hecl/driver/CToolAdd.hpp b/hecl/driver/CToolAdd.hpp index 58b04dd00..d053d75d7 100644 --- a/hecl/driver/CToolAdd.hpp +++ b/hecl/driver/CToolAdd.hpp @@ -3,16 +3,28 @@ #include "CToolBase.hpp" -class CToolAdd : public CToolBase +class CToolAdd final : public CToolBase { public: - CToolAdd(const std::vector& args) - : CToolBase(argc, argv) + CToolAdd(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolAdd() { } + + static void Help() + { + } + + std::string toolName() const {return "add";} + + int run() + { + return 0; + } }; #endif // CTOOL_ADD diff --git a/hecl/driver/CToolBase.hpp b/hecl/driver/CToolBase.hpp index bb645c8b4..a1d9b32f8 100644 --- a/hecl/driver/CToolBase.hpp +++ b/hecl/driver/CToolBase.hpp @@ -1,14 +1,29 @@ #ifndef CTOOL_BASE #define CTOOL_BASE +#include +#include +#include + +struct SToolPassInfo +{ + std::string pname; + std::vector args; + std::string output; + unsigned verbosityLevel = 0; + bool force = false; +}; + class CToolBase { protected: - const std::vector& m_args; + const SToolPassInfo& m_info; public: - CToolBase(const std::vector& args) - : m_args(args) {} + CToolBase(const SToolPassInfo& info) + : m_info(info) {} virtual ~CToolBase() {} + virtual std::string toolName() const=0; + virtual int run()=0; }; #endif // CTOOL_BASE diff --git a/hecl/driver/CToolClean.hpp b/hecl/driver/CToolClean.hpp index 1dfa2b4ab..e96e1f675 100644 --- a/hecl/driver/CToolClean.hpp +++ b/hecl/driver/CToolClean.hpp @@ -3,16 +3,28 @@ #include "CToolBase.hpp" -class CToolClean : public CToolBase +class CToolClean final : public CToolBase { public: - CToolClean(const std::vector& args) - : CToolBase(args) + CToolClean(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolClean() { } + + static void Help() + { + } + + std::string toolName() const {return "clean";} + + int run() + { + return 0; + } }; #endif // CTOOL_CLEAN diff --git a/hecl/driver/CToolCook.hpp b/hecl/driver/CToolCook.hpp index 8bbfbc1b4..04a6dec0c 100644 --- a/hecl/driver/CToolCook.hpp +++ b/hecl/driver/CToolCook.hpp @@ -3,16 +3,28 @@ #include "CToolBase.hpp" -class CToolCook : public CToolBase +class CToolCook final : public CToolBase { public: - CToolCook(const std::vector& args) - : CToolBase(args) + CToolCook(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolCook() { } + + static void Help() + { + } + + std::string toolName() const {return "cook";} + + int run() + { + return 0; + } }; #endif // CTOOL_COOK diff --git a/hecl/driver/CToolGroup.hpp b/hecl/driver/CToolGroup.hpp index a28c0a89e..71ab9e419 100644 --- a/hecl/driver/CToolGroup.hpp +++ b/hecl/driver/CToolGroup.hpp @@ -3,16 +3,28 @@ #include "CToolBase.hpp" -class CToolGroup : public CToolBase +class CToolGroup final : public CToolBase { public: - CToolGroup(const std::vector& args) - : CToolBase(args) + CToolGroup(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolGroup() { } + + static void Help() + { + } + + std::string toolName() const {return "group";} + + int run() + { + return 0; + } }; #endif // CTOOL_GROUP diff --git a/hecl/driver/CToolHelp.hpp b/hecl/driver/CToolHelp.hpp index 0553f3538..e1cb09ca9 100644 --- a/hecl/driver/CToolHelp.hpp +++ b/hecl/driver/CToolHelp.hpp @@ -2,17 +2,80 @@ #define CTOOL_HELP #include "CToolBase.hpp" +#include +#include -class CToolHelp : public CToolBase +class CToolHelp final : public CToolBase { public: - CToolHelp(const std::vector& args) - : CToolBase(args) + CToolHelp(const SToolPassInfo& info) + : CToolBase(info) { + if (!m_info.args.size()) + throw std::invalid_argument("help requires a tool name argument"); } + ~CToolHelp() { } + + static void Help() + { + printf("................................___________ \n" + "...........................,.-'\"...........``~., \n" + "........................,.-\".......................\"-., \n" + "....................,/..................................\":, \n" + "..................,?........................................, \n" + "................/...........................................,}\n" + "............../........................................,:`^`..}\n" + "............./.......................................,:\"...../\n" + "............?.....__..................................:`....../\n" + ".........../__.(...\"~-,_...........................,:`....../\n" + "........../(_....\"~,_....\"~,_.....................,:`...._/ \n" + "..........{.._$;_....\"=,_.....\"-,_......,.-~-,},.~\";/....} \n" + "...........((...*~_......\"=-._...\";,,./`........../\"..../ \n" + "...,,,___.`~,......\"~.,....................`......}....../ \n" + "............(....`=-,,...`.........................(...;_,,-\" \n" + "............/.`~,......`-.................................../ \n" + ".............`~.*-,.....................................|,./...,__ \n" + ",,_..........}.>-._...................................|.......`=~-, \n" + ".....`=~-,__......`,................................. \n" + "...................`=~-,,.,........................... \n" + ".........................`:,,..........................`\n" + "...........................`=-,...............,%%`>--==`` \n" + ".................................._.........._,-%%...` \n" + "...................................,\n"); + } + + static void ToolHelp(const std::string& toolName) + { + if (toolName == "init") + CToolInit::Help(); + else if (toolName == "add") + CToolAdd::Help(); + else if (toolName == "remove" || toolName == "rm") + CToolRemove::Help(); + else if (toolName == "group") + CToolGroup::Help(); + else if (toolName == "cook") + CToolCook::Help(); + else if (toolName == "clean") + CToolClean::Help(); + else if (toolName == "package") + CToolPackage::Help(); + else if (toolName == "help") + CToolHelp::Help(); + else + throw std::invalid_argument("unrecognized tool '" + toolName + "' - can't help"); + } + + std::string toolName() const {return "help";} + + int run() + { + ToolHelp(m_info.args[0]); + return 0; + } }; #endif // CTOOL_HELP diff --git a/hecl/driver/CToolInit.hpp b/hecl/driver/CToolInit.hpp index f049e7f50..7e867282f 100644 --- a/hecl/driver/CToolInit.hpp +++ b/hecl/driver/CToolInit.hpp @@ -3,16 +3,28 @@ #include "CToolBase.hpp" -class CToolInit : public CToolBase +class CToolInit final : public CToolBase { public: - CToolInit(const std::vector& args) - : CToolBase(args) + CToolInit(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolInit() { } + + static void Help() + { + } + + std::string toolName() const {return "init";} + + int run() + { + return 0; + } }; #endif // CTOOL_INIT diff --git a/hecl/driver/CToolPackage.hpp b/hecl/driver/CToolPackage.hpp index be33b7e5c..9e5e6a27c 100644 --- a/hecl/driver/CToolPackage.hpp +++ b/hecl/driver/CToolPackage.hpp @@ -5,16 +5,28 @@ #include #include "CToolBase.hpp" -class CToolPackage : public CToolBase +class CToolPackage final : public CToolBase { public: - CToolPackage(const std::vector& args) - : CToolBase(args) + CToolPackage(const SToolPassInfo& info) + : CToolBase(info) { } + ~CToolPackage() { } + + static void Help() + { + } + + std::string toolName() const {return "package";} + + int run() + { + return 0; + } }; #endif // CTOOL_PACKAGE diff --git a/hecl/driver/CToolRemove.hpp b/hecl/driver/CToolRemove.hpp new file mode 100644 index 000000000..2664967df --- /dev/null +++ b/hecl/driver/CToolRemove.hpp @@ -0,0 +1,30 @@ +#ifndef CTOOL_REMOVE +#define CTOOL_REMOVE + +#include "CToolBase.hpp" + +class CToolRemove final : public CToolBase +{ +public: + CToolRemove(const SToolPassInfo& info) + : CToolBase(info) + { + } + + ~CToolRemove() + { + } + + static void Help() + { + } + + std::string toolName() const {return "remove";} + + int run() + { + return 0; + } +}; + +#endif // CTOOL_REMOVE diff --git a/hecl/driver/driver.pro b/hecl/driver/driver.pro index d814259dc..af6163eaa 100644 --- a/hecl/driver/driver.pro +++ b/hecl/driver/driver.pro @@ -26,5 +26,6 @@ HEADERS += \ CToolGroup.hpp \ CToolCook.hpp \ CToolClean.hpp \ - CToolAdd.hpp + CToolAdd.hpp \ + CToolRemove.hpp diff --git a/hecl/driver/main.cpp b/hecl/driver/main.cpp index 318478441..fd5b95b2c 100644 --- a/hecl/driver/main.cpp +++ b/hecl/driver/main.cpp @@ -1,24 +1,57 @@ #include #include +#include +#include #include -#define MAIN_CPP #include "CToolBase.hpp" #include "CToolInit.hpp" #include "CToolAdd.hpp" +#include "CToolRemove.hpp" #include "CToolGroup.hpp" #include "CToolCook.hpp" #include "CToolClean.hpp" #include "CToolPackage.hpp" #include "CToolHelp.hpp" -void printHelp(const char* pname) +/* Main usage message */ +static void printHelp(const char* pname) { - printf("Usage: %s init|add|group|cook|clean|package|help\n", pname); +#if HECL_GIT + printf("HECL Commit " #HECL_GIT " (" #HECL_BRANCH ")\n" + "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); +#elif HECL_VER + printf("HECL Version " #HECL_VER "\n" + "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); +#else + printf("HECL\n" + "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); +#endif +} + +/* Regex patterns */ +static const std::regex regOPEN("-o\\s*(\\S+)", std::regex::ECMAScript|std::regex::optimize); +static const std::regex regVERBOSE("-v(v*)", std::regex::ECMAScript|std::regex::optimize); +static const std::regex regFORCE("-f", std::regex::ECMAScript|std::regex::optimize); +static const std::regex regWS("\\S+", std::regex::ECMAScript|std::regex::optimize); + +/* Iterates string segments around matched arguments and + * filters args string accordingly */ +static void whiddleArgs(std::string& args, const std::regex& regex) +{ + std::string remArgs; + for (std::sregex_token_iterator it(args.begin(), args.end(), regex, -1); + it != std::sregex_token_iterator() ; ++it) + { + const std::string& str = *it; + remArgs += str; + } + args = remArgs; } int main(int argc, const char** argv) { + /* Basic usage check */ if (argc == 1) { printHelp(argv[0]); @@ -30,8 +63,100 @@ int main(int argc, const char** argv) return 0; } - if (!strcasecmp(argv[1], "init")) + /* Assemble common tool pass info */ + SToolPassInfo info; + info.pname = argv[0]; + /* Concatenate args */ + std::string args; + for (int i=2 ; itoolName().c_str(), info.verbosityLevel); + + /* Run tool */ + int retval; + try + { + retval = tool->run(); + } + catch (std::exception& ex) + { + fprintf(stderr, "Error running HECL tool '%s':\n%s\n", toolName.c_str(), ex.what()); + delete tool; + return -1; + } + + delete tool; + return retval; } diff --git a/hecl/extra/hecl_autocomplete.sh b/hecl/extra/hecl_autocomplete.sh index 65be42b3e..50fbcf850 100755 --- a/hecl/extra/hecl_autocomplete.sh +++ b/hecl/extra/hecl_autocomplete.sh @@ -3,7 +3,7 @@ _hecl () { local word=${COMP_WORDS[COMP_CWORD]} - local filecmds=(init add group cook clean package) + local filecmds=(init add remove group cook clean package) if [ $COMP_CWORD == 1 ] then @@ -12,7 +12,7 @@ _hecl () elif [ $COMP_CWORD == 2 ] then case ${COMP_WORDS[1]} in - init|add|group|cook|clean|package) + init|add|remove|group|cook|clean|package) COMPREPLY=($(compgen -f -- "${word}")) ;; help) diff --git a/hecl/hecl.pro b/hecl/hecl.pro index 00e42c0dc..ce1310afb 100644 --- a/hecl/hecl.pro +++ b/hecl/hecl.pro @@ -10,6 +10,7 @@ exists ($$PWD/llvm) { } HEADERS += \ + include/HECL.hpp \ include/HECLBackend.hpp \ include/HECLDatabase.hpp \ include/HECLFrontend.hpp \ diff --git a/hecl/include/HECL.hpp b/hecl/include/HECL.hpp new file mode 100644 index 000000000..a0919e759 --- /dev/null +++ b/hecl/include/HECL.hpp @@ -0,0 +1,70 @@ +#ifndef HECL_HPP +#define HECL_HPP + +#include + +namespace HECL +{ + +#include "../extern/blowfish/blowfish.h" + +/** + * @brief Severity of a log event + */ +enum LogType +{ + LOG_INFO, + LOG_WARN, + LOG_ERROR +}; + +/** + * @brief Logger callback type + */ +typedef std::function TLogger; + +/** + * @brief FourCC representation used within HECL's database + * + * FourCCs are efficient, mnemonic four-char-sequences used to represent types + * while fitting comfortably in a 32-bit word. HECL uses a four-char array + * to remain endian-independent. + */ +class FourCC +{ + union + { + char fcc[4]; + uint32_t num; + }; +public: + FourCC(const char* name) + : num(*(uint32_t*)name) {} + inline bool operator==(FourCC& other) {return num == other.num;} + inline bool operator!=(FourCC& other) {return num != other.num;} + inline std::string toString() {return std::string(fcc, 4);} +}; + +/** + * @brief Hash representation used for all storable and comparable objects + * + * Hashes are used within HECL to avoid redundant storage of objects; + * providing a rapid mechanism to compare for equality. + */ +class ObjectHash +{ + int64_t hash; +public: + ObjectHash(const void* buf, size_t len) + : hash(Blowfish_hash(buf, len)) {} + inline bool operator==(ObjectHash& other) {return hash == other.hash;} + inline bool operator!=(ObjectHash& other) {return hash != other.hash;} + inline bool operator<(ObjectHash& other) {return hash < other.hash;} + inline bool operator>(ObjectHash& other) {return hash > other.hash;} + inline bool operator<=(ObjectHash& other) {return hash <= other.hash;} + inline bool operator>=(ObjectHash& other) {return hash >= other.hash;} +}; + +} + +#endif // HECL_HPP diff --git a/hecl/include/HECLDatabase.hpp b/hecl/include/HECLDatabase.hpp index af906bd1b..17b96c9d7 100644 --- a/hecl/include/HECLDatabase.hpp +++ b/hecl/include/HECLDatabase.hpp @@ -7,65 +7,13 @@ #include #include -#include "../extern/blowfish/blowfish.h" +#include "HECL.hpp" namespace HECLDatabase { class IDatabase; -/** - * @brief Severity of a log event - */ -enum LogType -{ - LOG_INFO, - LOG_WARN, - LOG_ERROR -}; - -/** - * @brief FourCC representation used within HECL's database - * - * FourCCs are efficient, mnemonic four-char-sequences used to represent types - * while fitting comfortably in a 32-bit word. HECL uses a four-char array - * to remain endian-independent. - */ -class FourCC -{ - union - { - char fcc[4]; - uint32_t num; - }; -public: - FourCC(const char* name) - : num(*(uint32_t*)name) {} - inline bool operator==(FourCC& other) {return num == other.num;} - inline bool operator!=(FourCC& other) {return num != other.num;} - inline std::string toString() {return std::string(fcc, 4);} -}; - -/** - * @brief Hash representation used for all storable and comparable objects - * - * Hashes are used within HECL to avoid redundant storage of objects; - * providing a rapid mechanism to compare for equality. - */ -class ObjectHash -{ - int64_t hash; -public: - ObjectHash(const void* buf, size_t len) - : hash(Blowfish_hash(buf, len)) {} - inline bool operator==(ObjectHash& other) {return hash == other.hash;} - inline bool operator!=(ObjectHash& other) {return hash != other.hash;} - inline bool operator<(ObjectHash& other) {return hash < other.hash;} - inline bool operator>(ObjectHash& other) {return hash > other.hash;} - inline bool operator<=(ObjectHash& other) {return hash <= other.hash;} - inline bool operator>=(ObjectHash& other) {return hash >= other.hash;} -}; - /** * @brief The IDataObject class * @@ -126,8 +74,8 @@ public: virtual const IDataObject* at(size_t idx) const=0; inline const IDataObject* operator[](size_t idx) {return at(idx);} - virtual std::vector::const_iterator begin() const=0; - virtual std::vector::const_iterator end() const=0; + virtual std::vector::const_iterator begin() const=0; + virtual std::vector::const_iterator end() const=0; }; /** @@ -269,7 +217,7 @@ public: * @brief Register an optional callback to report log-messages using * @param logger logger-callback */ - virtual void registerLogger(std::function logger)=0; + virtual void registerLogger(HECL::TLogger logger)=0; /** * @brief Get the path of the project's root-directory diff --git a/hecl/lib/database/CLooseDatabase.hpp b/hecl/lib/database/CLooseDatabase.hpp index 247043c5d..92efb957e 100644 --- a/hecl/lib/database/CLooseDatabase.hpp +++ b/hecl/lib/database/CLooseDatabase.hpp @@ -18,8 +18,7 @@ class CLooseDatabase final : public IDatabase Access m_access; public: CLooseDatabase(const std::string& path, Access access) - : m_mainSql((path+"/main.db").c_str(), (m_access == READONLY) ? true : false), - m_cookedSql((path+"/cooked.db").c_str(), (m_access == READONLY) ? true : false), + : m_sql(path.c_str(), (access == READONLY) ? true : false), m_access(access) { @@ -51,12 +50,12 @@ public: const IDataObject* addDataBlob(const std::string& name, const void* data, size_t length) { /* Hash data */ - ObjectHash hash(data, length); + HECL::ObjectHash hash(data, length); /* Compress data into file */ FILE* fp = fopen("", "wb"); - m_mainSql.insertObject(name, "DUMB", hash, length, length); + m_sql.insertObject(name, "DUMB", hash, length, length); } const IDataObject* addDataBlob(const void* data, size_t length) diff --git a/hecl/lib/database/CSQLite.hpp b/hecl/lib/database/CSQLite.hpp index 4974949cd..369f2a803 100644 --- a/hecl/lib/database/CSQLite.hpp +++ b/hecl/lib/database/CSQLite.hpp @@ -132,7 +132,9 @@ public: return retval; } - bool insertObject(const std::string& name, const FourCC& type, const ObjectHash& hash, + bool insertObject(const std::string& name, + const HECL::FourCC& type, + const HECL::ObjectHash& hash, size_t compLen, size_t decompLen) { }