diff --git a/hecl/blender/CBlenderConnection.cpp b/hecl/blender/CBlenderConnection.cpp index bbd3b6978..381c30c38 100644 --- a/hecl/blender/CBlenderConnection.cpp +++ b/hecl/blender/CBlenderConnection.cpp @@ -198,7 +198,7 @@ bool CBlenderConnection::openBlend(const std::string& path) return false; } -bool CBlenderConnection::cookBlend(std::function bufGetter, +bool CBlenderConnection::cookBlend(std::function bufGetter, const std::string& expectedType, const std::string& platform, bool bigEndian) @@ -222,8 +222,8 @@ bool CBlenderConnection::cookBlend(std::function bufGetter, _readLine(lineBuf, sizeof(lineBuf))) { uint32_t sz; - _readBuf(&sz, 4); - void* buf = bufGetter(sz); + _readBuf((char*)&sz, 4); + char* buf = bufGetter(sz); _readBuf(buf, sz); } if (!strcmp("SUCCESS", lineBuf)) diff --git a/hecl/blender/CBlenderConnection.hpp b/hecl/blender/CBlenderConnection.hpp index 8c7bcef3d..9e8049a02 100644 --- a/hecl/blender/CBlenderConnection.hpp +++ b/hecl/blender/CBlenderConnection.hpp @@ -38,7 +38,7 @@ public: CP_MODERN = 0, CP_GX = 1, }; - bool cookBlend(std::function bufGetter, + bool cookBlend(std::function bufGetter, const std::string& expectedType, const std::string& platform, bool bigEndian=false); diff --git a/hecl/driver/CToolAdd.hpp b/hecl/driver/CToolAdd.hpp index d053d75d7..104a18918 100644 --- a/hecl/driver/CToolAdd.hpp +++ b/hecl/driver/CToolAdd.hpp @@ -2,6 +2,7 @@ #define CTOOL_ADD #include "CToolBase.hpp" +#include class CToolAdd final : public CToolBase { @@ -15,8 +16,41 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-add - Add working files to the HECL index\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl add [...]\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command stages a file or glob-pattern of files within the project database " + "for inclusion in the "); + help.wrapBold("hecl cook"); + help.wrap(" process.\n\n" + "Files added in this manner automatically become 'explicit' database " + "objects. 'Explicit objects' will not be removed in housekeeping tasks automatically " + "performed by HECL's library functions, unless the user (re)moves the file " + "using the filesystem.\n\n" + "For details on explicit vs. implicit objects, view the "); + help.wrapBold("hecl cook"); + help.wrap(" documentation.\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("...", "input file(s)"); + help.beginWrap(); + help.wrap("Working file(s) containing production data to be cooked by HECL. " + "Glob-strings may be specified (e.g. "); + help.wrapBold("*.blend"); + help.wrap(") to automatically add all matching files to the database.\n"); + help.endWrap(); } std::string toolName() const {return "add";} diff --git a/hecl/driver/CToolBase.hpp b/hecl/driver/CToolBase.hpp index a1d9b32f8..087b66f05 100644 --- a/hecl/driver/CToolBase.hpp +++ b/hecl/driver/CToolBase.hpp @@ -4,6 +4,10 @@ #include #include #include +#include +#include +#include +#include struct SToolPassInfo { @@ -26,4 +30,161 @@ public: virtual int run()=0; }; +#define RED "\033[0;31m" +#define GREEN "\033[0;32m" +#define CYAN "\033[0;36m" +#define BOLD "\033[1m" +#define NORMAL "\033[0m" + +#define WRAP_INDENT 4 + +extern bool XTERM_COLOR; + +class CHelpOutput +{ +public: + typedef void(*THelpFunc)(CHelpOutput&); +private: + FILE* m_sout; + THelpFunc m_helpFunc; + int m_lineWidth; + std::string m_wrapBuffer; + + void _wrapBuf(std::string& string) + { + int counter; + std::string::iterator it = string.begin(); + + while (it != string.end()) + { + std::string::iterator v=it; + + /* copy string until the end of the line is reached */ + for (counter=WRAP_INDENT ; counter < m_lineWidth ; ++counter) + { + if (*it == '\n') + { + counter = WRAP_INDENT; + ++it; + } + if (counter == WRAP_INDENT) + it = string.insert(it, WRAP_INDENT, ' ') + WRAP_INDENT; + if (it >= string.end()) + return; + if (*it != '\n') + ++it; + } + /* check for whitespace */ + if (isspace(*it)) + { + *it = '\n'; + counter = WRAP_INDENT; + ++it; + } + else + { + /* check for nearest whitespace back in string */ + for (std::string::iterator k=it ; k!=string.begin() ; --k) + { + if (isspace(*k)) + { + counter = WRAP_INDENT; + if (k < v) + { + k = it; + string.insert(k, '\n'); + } + else + *k = '\n'; + it = k + 1; + break; + } + } + } + } + } + +public: + + CHelpOutput(THelpFunc helpFunc) + : m_sout(NULL), m_helpFunc(helpFunc) + { + struct winsize w; + m_lineWidth = 80; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) + m_lineWidth = w.ws_col; + if (m_lineWidth < 10) + m_lineWidth = 10; + } + + void go() + { + m_sout = popen("less -R", "w"); + if (m_sout) + { + m_helpFunc(*this); + pclose(m_sout); + } + else + { + m_sout = stdout; + m_helpFunc(*this); + } + } + + void print(const char* str) + { + fputs(str, m_sout); + } + + void printBold(const char* str) + { + if (XTERM_COLOR) + fprintf(m_sout, BOLD "%s" NORMAL, str); + else + fputs(str, m_sout); + } + + void secHead(const char* headName) + { + if (XTERM_COLOR) + fprintf(m_sout, BOLD "%s" NORMAL "\n", headName); + else + fprintf(m_sout, "%s\n", headName); + } + + void optionHead(const char* flag, const char* synopsis) + { + if (XTERM_COLOR) + fprintf(m_sout, BOLD "%s" NORMAL " (%s)\n", flag, synopsis); + else + fprintf(m_sout, "%s (%s)\n", flag, synopsis); + } + + void beginWrap() + { + m_wrapBuffer.clear(); + } + + void wrap(const char* str) + { + m_wrapBuffer += str; + } + + void wrapBold(const char* str) + { + m_wrapBuffer += BOLD; + m_wrapBuffer += str; + m_wrapBuffer += NORMAL; + } + + void endWrap() + { + _wrapBuf(m_wrapBuffer); + m_wrapBuffer += '\n'; + fputs(m_wrapBuffer.c_str(), m_sout); + m_wrapBuffer.clear(); + } +}; + #endif // CTOOL_BASE diff --git a/hecl/driver/CToolClean.hpp b/hecl/driver/CToolClean.hpp index e96e1f675..de8b9df3b 100644 --- a/hecl/driver/CToolClean.hpp +++ b/hecl/driver/CToolClean.hpp @@ -2,6 +2,7 @@ #define CTOOL_CLEAN #include "CToolBase.hpp" +#include class CToolClean final : public CToolBase { @@ -15,8 +16,47 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-clean - Delete cached cooked objects referenced via working files\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl clean [-ri] [...]\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command performs an immediate deletion of cooked objects cached " + "within the project database. It may operate on a subset of objects or the " + "entire project.\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("...", "clean path(s)"); + help.beginWrap(); + help.wrap("When one or more paths are specified in the command, the clean process will " + "restrict object deletion to only the working file(s) specified. If "); + help.wrapBold("-r"); + help.wrap(" is also specifed, directories may be provided as well. If no path(s) specified, " + "the entire project is cleaned.\n"); + help.endWrap(); + + help.optionHead("-r", "recursion"); + help.beginWrap(); + help.wrap("Enables recursive file-matching for cleaning entire directories of working files.\n"); + help.endWrap(); + + help.optionHead("-i", "follow implicit links"); + help.beginWrap(); + help.wrap("Enables implicit object traversal and cleaning. This is only useful if one or more paths " + "are specified. For objects supporting implicit-gathering, this will query those " + "objects for their current implicit links and ensure the linked-objects are cleaned " + "as well.\n"); + help.endWrap(); } std::string toolName() const {return "clean";} diff --git a/hecl/driver/CToolCook.hpp b/hecl/driver/CToolCook.hpp index 04a6dec0c..d8b3f2169 100644 --- a/hecl/driver/CToolCook.hpp +++ b/hecl/driver/CToolCook.hpp @@ -2,6 +2,7 @@ #define CTOOL_COOK #include "CToolBase.hpp" +#include class CToolCook final : public CToolBase { @@ -15,8 +16,58 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-cook - Cook objects within the project database\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl cook [-r] [...]\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command initiates a cooking pass on the project database. Cooking " + "is analogous to compiling in software development. The resulting object buffers " + "are cached within the project database. HECL performs the following " + "tasks for each object during the cook process:\n\n"); + help.wrapBold("- Object Gather: "); + help.wrap("Files added with "); + help.wrapBold("hecl add"); + help.wrap(" are queried for their dependent files (e.g. "); + help.wrapBold(".blend"); + help.wrap(" files return any linked "); + help.wrapBold(".png"); + help.wrap(" images). If the dependent files are unable to be found, the cook process aborts.\n\n"); + help.wrapBold("- Modtime Comparison: "); + help.wrap("Files that have previously finished a cook pass are inspected for their time of " + "last modification. If the file hasn't changed since its previous cook-pass, the " + "process is skipped. If the file has been moved or deleted, the object is automatically " + "removed from the project database.\n\n"); + help.wrapBold("- Cook: "); + help.wrap("A type-specific procedure compiles the file's contents into an efficient format " + "for use by the runtime. A data-buffer is provided to HECL.\n\n"); + help.wrapBold("- Hash and Compress: "); + help.wrap("The data-buffer is hashed and compressed before being cached in the object database.\n\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("...", "input file(s)"); + help.beginWrap(); + help.wrap("Specifies working file(s) containing production data to be cooked by HECL. " + "Glob-strings may be specified (e.g. "); + help.wrapBold("*.blend"); + help.wrap(") to automatically cook all matching current-directory files in the project database. " + "If no path specified, all files in the project database are cooked.\n"); + help.endWrap(); + + help.optionHead("-r", "recursion"); + help.beginWrap(); + help.wrap("Enables recursive file-matching for cooking entire directories of working files.\n"); + help.endWrap(); } std::string toolName() const {return "cook";} diff --git a/hecl/driver/CToolGroup.hpp b/hecl/driver/CToolGroup.hpp index 71ab9e419..4648f44e1 100644 --- a/hecl/driver/CToolGroup.hpp +++ b/hecl/driver/CToolGroup.hpp @@ -2,6 +2,7 @@ #define CTOOL_GROUP #include "CToolBase.hpp" +#include class CToolGroup final : public CToolBase { @@ -15,8 +16,44 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-group - Fork a project directory as an explicit group\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl group [-D] \n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command turns a nested subdirectory of the project into a HECL group. " + "Groups play an important role in the resulting structure of the packaged " + "database. All objects in HECL belong to a group of some sort since the runtime " + "only provides loading functions for groups. Ungrouped " + "objects in the project root are individually added to 'loose groups'.\n\n With "); + help.wrapBold("hecl group"); + help.wrap(", explicit groups may be defined (e.g. a stage, level, area, loadable segment). "); + help.wrap("Groups are defined by filesystem directories relative to the project root " + "and may be loaded within the runtime using the relative path as a lookup-string. " + "Sub-directories that aren't explicitly made into a group inherit the group-status " + "of the parent directory.\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("", "group directory path"); + help.beginWrap(); + help.wrap("Directory to fork as an explicit group\n"); + help.endWrap(); + + help.optionHead("-D", "delete group"); + help.beginWrap(); + help.wrap("Remove's directory's status as an explicit group; restoring its inheritance " + "from the parent directory.\n"); + help.endWrap(); } std::string toolName() const {return "group";} diff --git a/hecl/driver/CToolHelp.hpp b/hecl/driver/CToolHelp.hpp index d9b6b740d..b8514381c 100644 --- a/hecl/driver/CToolHelp.hpp +++ b/hecl/driver/CToolHelp.hpp @@ -4,9 +4,12 @@ #include "CToolBase.hpp" #include #include +#include class CToolHelp final : public CToolBase { + + public: CToolHelp(const SToolPassInfo& info) : CToolBase(info) @@ -19,54 +22,64 @@ public: { } - static void Help() + + + static void Help(CHelpOutput& 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"); + help.printBold("................................___________ \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) { + /* Select tool's help-text streamer */ + CHelpOutput::THelpFunc helpFunc = NULL; if (toolName == "init") - CToolInit::Help(); + helpFunc = CToolInit::Help; else if (toolName == "add") - CToolAdd::Help(); + helpFunc = CToolAdd::Help; else if (toolName == "remove" || toolName == "rm") - CToolRemove::Help(); + helpFunc = CToolRemove::Help; else if (toolName == "group") - CToolGroup::Help(); + helpFunc = CToolGroup::Help; else if (toolName == "cook") - CToolCook::Help(); + helpFunc = CToolCook::Help; else if (toolName == "clean") - CToolClean::Help(); - else if (toolName == "package") - CToolPackage::Help(); + helpFunc = CToolClean::Help; + else if (toolName == "package" || toolName == "pack") + helpFunc = CToolPackage::Help; else if (toolName == "help") - CToolHelp::Help(); + helpFunc = CToolHelp::Help; else + { throw std::invalid_argument("unrecognized tool '" + toolName + "' - can't help"); + return; + } + + CHelpOutput ho(helpFunc); + ho.go(); } std::string toolName() const {return "help";} diff --git a/hecl/driver/CToolInit.hpp b/hecl/driver/CToolInit.hpp index 7e867282f..0f11ae85d 100644 --- a/hecl/driver/CToolInit.hpp +++ b/hecl/driver/CToolInit.hpp @@ -2,6 +2,7 @@ #define CTOOL_INIT #include "CToolBase.hpp" +#include class CToolInit final : public CToolBase { @@ -15,8 +16,31 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-init - Initialize a brand-new project database\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl init []\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("Creates a "); + help.wrapBold(".hecl"); + help.wrap(" directory within the selected directory with an initialized database index. " + "This constitutes an empty HECL project, ready for making stuff!!\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("", "group directory path"); + help.beginWrap(); + help.wrap("Directory to create new project database in. If not specified, current directory is used.\n"); + help.endWrap(); } std::string toolName() const {return "init";} diff --git a/hecl/driver/CToolPackage.hpp b/hecl/driver/CToolPackage.hpp index 9e5e6a27c..a6035a630 100644 --- a/hecl/driver/CToolPackage.hpp +++ b/hecl/driver/CToolPackage.hpp @@ -4,6 +4,7 @@ #include #include #include "CToolBase.hpp" +#include class CToolPackage final : public CToolBase { @@ -17,8 +18,45 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-pack\n" + "hecl-package - Package objects within the project database\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl package [-a] [-o ] []\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command initiates a packaging pass on the project database. Packaging " + "is analogous to linking in software development. All objects necessary to " + "generate a complete package are gathered, grouped, and indexed within an .hlpk file.\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("", "input directory"); + help.beginWrap(); + help.wrap("Specifies a project subdirectory to root the resulting package from. " + "If any dependent-files fall outside this subdirectory, they will implicitly " + "be gathered and packaged.\n"); + help.endWrap(); + + help.optionHead("-o ", "output package file"); + help.beginWrap(); + help.wrap("Specifies a target path to write the package. If not specified, the package " + "is written into /out//.hlpk\n"); + help.endWrap(); + + help.optionHead("-a", "auto cook"); + help.beginWrap(); + help.wrap("Any referenced objects that haven't already been cooked are automatically cooked as " + "part of the packaging process. If this flag is omitted, the packaging process will abort.\n"); + help.endWrap(); } std::string toolName() const {return "package";} diff --git a/hecl/driver/CToolRemove.hpp b/hecl/driver/CToolRemove.hpp index 2664967df..7e8c1428d 100644 --- a/hecl/driver/CToolRemove.hpp +++ b/hecl/driver/CToolRemove.hpp @@ -2,6 +2,7 @@ #define CTOOL_REMOVE #include "CToolBase.hpp" +#include class CToolRemove final : public CToolBase { @@ -15,8 +16,39 @@ public: { } - static void Help() + static void Help(CHelpOutput& help) { + help.secHead("NAME"); + help.beginWrap(); + help.wrap("hecl-rm\n"); + help.wrap("hecl-remove - Remove working files from the HECL index\n"); + help.endWrap(); + + help.secHead("SYNOPSIS"); + help.beginWrap(); + help.wrap("hecl remove [-r] [...]\n"); + help.endWrap(); + + help.secHead("DESCRIPTION"); + help.beginWrap(); + help.wrap("This command removes a file, directory, or glob-pattern of files from the project database. " + "Once a file is removed, any cooked cache objects are deleted automatically. "); + help.wrapBold("The working file itself is not deleted from the filesystem.\n"); + help.endWrap(); + + help.secHead("OPTIONS"); + help.optionHead("...", "input file(s)"); + help.beginWrap(); + help.wrap("Working file(s) to be removed from the project database. " + "Glob-strings may be specified (e.g. "); + help.wrapBold("*.blend"); + help.wrap(") to automatically remove all matching files from the database.\n"); + help.endWrap(); + + help.optionHead("-r", "recursion"); + help.beginWrap(); + help.wrap("Enables recursive file-matching for removing entire directories of working files.\n"); + help.endWrap(); } std::string toolName() const {return "remove";} diff --git a/hecl/driver/main.cpp b/hecl/driver/main.cpp index 128a183dc..5048dd031 100644 --- a/hecl/driver/main.cpp +++ b/hecl/driver/main.cpp @@ -1,7 +1,9 @@ #include #include +#include #include #include +#include #include #include "CToolBase.hpp" @@ -14,47 +16,43 @@ #include "CToolPackage.hpp" #include "CToolHelp.hpp" +bool XTERM_COLOR = false; + /* Main usage message */ static void printHelp(const char* pname) { + if (XTERM_COLOR) + printf(BOLD "HECL" NORMAL); + else + printf("HECL"); #if HECL_GIT - printf("HECL Commit " #HECL_GIT " (" #HECL_BRANCH ")\n" + printf(" 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" + printf(" Version " #HECL_VER "\n" "Usage: %s init|add|remove|group|cook|clean|package|help\n", pname); #else - printf("HECL\n" + printf("\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 regOPEN("-o([^\"]*|\\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 regNOWS("\\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; -} #include "../blender/CBlenderConnection.hpp" int main(int argc, const char** argv) { - CBlenderConnection bconn(false); - return 0; + /* Xterm check */ + const char* term = getenv("TERM"); + if (!strncmp(term, "xterm", 5)) + XTERM_COLOR = true; + + //CBlenderConnection bconn(false); + //return 0; /* Basic usage check */ if (argc == 1) @@ -73,45 +71,71 @@ int main(int argc, const char** argv) info.pname = argv[0]; /* Concatenate args */ - std::string args; + std::list args; for (int i=2 ; i::const_iterator it = args.begin() ; it != args.end() ;) { - if (info.output.empty()) - info.output = *openIt; - whiddleArgs(args, regOPEN); + const std::string& arg = *it; + std::smatch oMatch; + if (std::regex_search(arg, oMatch, regOPEN)) + { + const std::string& token = oMatch[1].str(); + if (token.size()) + { + if (info.output.empty()) + info.output = oMatch[1].str(); + it = args.erase(it); + } + else + { + it = args.erase(it); + if (it == args.end()) + break; + if (info.output.empty()) + info.output = *it; + it = args.erase(it); + } + continue; + } + ++it; } /* Count verbosity */ - for (std::sregex_token_iterator it(args.begin(), args.end(), regVERBOSE, 1); - it != std::sregex_token_iterator() ; ++it) + for (std::list::const_iterator it = args.begin() ; it != args.end() ;) { - const std::string& str = *it; - ++info.verbosityLevel; - info.verbosityLevel += str.length(); + const std::string& arg = *it; + std::smatch vMatch; + if (std::regex_search(arg, vMatch, regVERBOSE)) + { + ++info.verbosityLevel; + info.verbosityLevel += vMatch[1].str().size(); + it = args.erase(it); + continue; + } + ++it; } - whiddleArgs(args, regVERBOSE); /* Check force argument */ - if (std::regex_search(args, regFORCE)) + for (std::list::const_iterator it = args.begin() ; it != args.end() ;) { - info.force = true; - whiddleArgs(args, regFORCE); + const std::string& arg = *it; + if (std::regex_search(arg, regFORCE)) + { + info.force = true; + it = args.erase(it); + continue; + } + ++it; } /* Gather remaining args */ - for (std::sregex_token_iterator it(args.begin(), args.end(), regNOWS); - it != std::sregex_token_iterator() ; ++it) - { - const std::string& str = *it; - info.args.push_back(str); - } + for (const std::string& arg : args) + info.args.push_back(arg); } /* Construct selected tool */ @@ -132,7 +156,7 @@ int main(int argc, const char** argv) tool = new CToolCook(info); else if (toolName == "clean") tool = new CToolClean(info); - else if (toolName == "package") + else if (toolName == "package" || toolName == "pack") tool = new CToolPackage(info); else if (toolName == "help") tool = new CToolHelp(info);