diff --git a/.travis.yml b/.travis.yml index ac0c28a1b..c3835f23b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,15 @@ compiler: os: - linux +matrix: + fast_finish: true env: - - CMAKE_BUILD_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=on -DWITH_LUA52:BOOL=off -DWITH_LUA53:BOOL=off" - - CMAKE_BUILD_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=off -DWITH_LUA52:BOOL=on -DWITH_LUA53:BOOL=off" - - CMAKE_BUILD_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=off -DWITH_LUA52:BOOL=off -DWITH_LUA53:BOOL=on" + - CMAKE_CONFIGURE_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=on -DWITH_LUA52:BOOL=off -DWITH_LUA53:BOOL=off" + - CMAKE_CONFIGURE_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=off -DWITH_LUA52:BOOL=on -DWITH_LUA53:BOOL=off" + - CMAKE_CONFIGURE_OPTIONS="-DWITH_NEL_TESTS:BOOL=off -DWITH_LUA51:BOOL=off -DWITH_LUA52:BOOL=off -DWITH_LUA53:BOOL=on" + - CMAKE_CONFIGURE_OPTIONS="-DCPPTEST_LIBRARY_DEBUG:STRING=/usr/lib/libcpptest.so" + CMAKE_BUILD_OPTIONS="--target nel_unit_test -- -j 2" + RUN="build/bin/nel_unit_test" addons: apt: @@ -30,10 +35,12 @@ addons: before_script: - mkdir build - cmake --version + - cmake -Hcode -Bbuild $CMAKE_CONFIGURE_OPTIONS + - cat build/CMakeCache.txt script: - - cmake -Hcode -Bbuild $CMAKE_BUILD_OPTIONS - - cmake --build build -- -j 2 + - cmake --build build $CMAKE_BUILD_OPTIONS + - $RUN notifications: irc: diff --git a/code/nel/include/nel/misc/cmd_args.h b/code/nel/include/nel/misc/cmd_args.h index 26e097eee..25195b64d 100644 --- a/code/nel/include/nel/misc/cmd_args.h +++ b/code/nel/include/nel/misc/cmd_args.h @@ -40,6 +40,8 @@ public: std::string helpName; // name of argument in help. Eg: std::string helpDescription; // description of argument in help. Eg: Specifies the directory where to write generated files + bool onlyOnce; // only one argument of this type is used, if several are provided, only the last one is kept + bool required; // at least one argument of this type must be provided bool found; // all values for this argument std::vector values; // all values for this argument @@ -55,12 +57,15 @@ public: /// longName is "print" of the argument is --print /// helpName is the name that will be displayed in help if it's a required argument /// helpDescription is the description of the argument that will be displayed in help - void addArg(const std::string &shortName, const std::string &longName, const std::string &helpName, const std::string &helpDescription); + /// onlyOnce can be set to false, if we allows to use this argument more than once + void addArg(const std::string &shortName, const std::string &longName, const std::string &helpName, const std::string &helpDescription, bool onlyOnce = true); - /// Add a required argument to arguments list. + /// Add a additional argument to arguments list. /// helpName is the name that will be displayed in help if it's a required argument /// helpDescription is the description of the argument that will be displayed in help - void addArg(const std::string &helpName, const std::string &helpDescription); + /// onlyOnce can be set to false, if we allows to use this argument more than once + /// required can be set to false, if this argument is required + void addAdditionalArg(const std::string &name, const std::string &helpDescription, bool onlyOnce = true, bool required = true); /// Parse the command line from main() parameters argc and argv and process default arguments. bool parse(int argc, char **argv); @@ -93,21 +98,39 @@ public: std::vector getLongArg(const std::string &argName) const; /// return true if there are arguments that are required - bool needRequiredArg() const; + bool needAdditionalArg() const; - /// return true if required or optional args are present on the commandline - bool haveRequiredArg() const; + /// return true if any additional args are present on the commandline + bool haveAdditionalArg() const; - /// Returns all additional required parameters - std::vector getRequiredArg() const; + /// return true if a specific additional arg is present on the commandline + bool haveAdditionalArg(const std::string &name) const; + + /// Returns values of a specific additional arg + std::vector getAdditionalArg(const std::string &name) const; /// Display help of the program. void displayHelp(); /// Display version of the program. void displayVersion(); + + /// Returns program name or path passed as first parameter to parse() method + std::string getProgramName() const { return _ProgramName; } + std::string getProgramPath() const { return _ProgramPath; } + + /// Set or get description to display in help + void setDescription(const std::string &description) { _Description = description; } + std::string getDescription() const { return _Description; } + + /// Set or get version to display in -v + void setVersion(const std::string &version) { _Version = version; } + std::string getVersion() const { return _Version; } protected: - std::string _ProgramName; + std::string _ProgramName; // filename of the program + std::string _ProgramPath; // full path of the program + std::string _Description; // description of the program + std::string _Version; // version of the program /// Array of arguments pass from the command line TArgs _Args; diff --git a/code/nel/src/misc/cmd_args.cpp b/code/nel/src/misc/cmd_args.cpp index bbdee0e11..f44bc15b1 100644 --- a/code/nel/src/misc/cmd_args.cpp +++ b/code/nel/src/misc/cmd_args.cpp @@ -33,6 +33,10 @@ namespace NLMISC CCmdArgs::CCmdArgs() { +#ifdef NL_VERSION + _Version = NL_VERSION; +#endif + // add help addArg("h", "help", "", "Display this help"); @@ -45,24 +49,28 @@ void CCmdArgs::addArg(const TArg &arg) _Args.push_back(arg); } -void CCmdArgs::addArg(const std::string &shortName, const std::string &longName, const std::string &helpName, const std::string &helpDescription) +void CCmdArgs::addArg(const std::string &shortName, const std::string &longName, const std::string &helpName, const std::string &helpDescription, bool onlyOnce) { TArg arg; arg.shortName = shortName; arg.longName = longName; arg.helpName = helpName; arg.helpDescription = helpDescription; + arg.onlyOnce = onlyOnce; arg.found = false; + arg.required = false; addArg(arg); } -void CCmdArgs::addArg(const std::string &helpName, const std::string &helpDescription) +void CCmdArgs::addAdditionalArg(const std::string &helpName, const std::string &helpDescription, bool onlyOnce, bool required) { TArg arg; arg.helpName = helpName; arg.helpDescription = helpDescription; + arg.onlyOnce = onlyOnce; arg.found = false; + arg.required = required; addArg(arg); } @@ -125,7 +133,7 @@ std::vector CCmdArgs::getLongArg(const std::string &argName) const return std::vector(); } -bool CCmdArgs::needRequiredArg() const +bool CCmdArgs::needAdditionalArg() const { // process each argument for(uint i = 0; i < _Args.size(); ++i) @@ -133,14 +141,14 @@ bool CCmdArgs::needRequiredArg() const const TArg &arg = _Args[i]; // they don't have any short or long name, but need a name in help - if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty()) + if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && arg.required) return true; } return false; } -bool CCmdArgs::haveRequiredArg() const +bool CCmdArgs::haveAdditionalArg() const { // process each argument for(uint i = 0; i < _Args.size(); ++i) @@ -148,14 +156,14 @@ bool CCmdArgs::haveRequiredArg() const const TArg &arg = _Args[i]; // they don't have any short or long name, but need a name in help - if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty()) - return !arg.values.empty(); + if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && arg.found) + return false; } return false; } -std::vector CCmdArgs::getRequiredArg() const +bool CCmdArgs::haveAdditionalArg(const std::string &name) const { // process each argument for(uint i = 0; i < _Args.size(); ++i) @@ -163,7 +171,22 @@ std::vector CCmdArgs::getRequiredArg() const const TArg &arg = _Args[i]; // they don't have any short or long name, but need a name in help - if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty()) + if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && arg.helpName == name && arg.found) + return false; + } + + return false; +} + +std::vector CCmdArgs::getAdditionalArg(const std::string &name) const +{ + // process each argument + for(uint i = 0; i < _Args.size(); ++i) + { + const TArg &arg = _Args[i]; + + // they don't have any short or long name, but need a name in help + if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && arg.helpName == name) return arg.values; } @@ -174,6 +197,15 @@ std::vector CCmdArgs::getRequiredArg() const bool CCmdArgs::parse(const std::string &args) { std::vector argv; + +#ifdef NL_OS_WINDOWS + char str[4096]; + uint len = GetModuleFileNameA(NULL, str, 4096); + + if (len && len < 4096) + argv.push_back(str); +#endif + std::string::size_type pos1 = 0, pos2 = 0; do @@ -230,6 +262,7 @@ bool CCmdArgs::parse(const std::vector &argv) // first argument is always the program name _ProgramName = CFile::getFilename(argv.front()); + _ProgramPath = CPath::standardizePath(CFile::getPath(argv.front())); // arguments count uint argc = argv.size(); @@ -272,6 +305,8 @@ bool CCmdArgs::parse(const std::vector &argv) name = name.substr(0, 1); } + bool found = false; + // process each argument definition for(uint j = 0; j < _Args.size(); ++j) { @@ -280,8 +315,15 @@ bool CCmdArgs::parse(const std::vector &argv) // only process arguments of the right type if ((useLongName && name != arg.longName) || (!useLongName && name != arg.shortName)) continue; + // already get the only once argument + if (arg.found && arg.onlyOnce) + { + // the last one is the only kept, so discard previous ones + arg.values.clear(); + } + // argument is found - arg.found = true; + found = arg.found = true; // another argument is required if (!arg.helpName.empty()) @@ -302,6 +344,11 @@ bool CCmdArgs::parse(const std::vector &argv) break; } + + if (!found) + { + printf("Warning: Argument %s not recognized, skip it!\n", name.c_str()); + } } else { @@ -313,6 +360,11 @@ bool CCmdArgs::parse(const std::vector &argv) // only process arguments that don't have a name if (!arg.shortName.empty() || !arg.longName.empty()) continue; + // already get the only once argument + if (arg.found && arg.onlyOnce) continue; + + arg.found = true; + // in fact, if there are more than one required arguments, all arguments are added in first one to simplify arg.values.push_back(name); @@ -329,7 +381,7 @@ bool CCmdArgs::parse(const std::vector &argv) } // process help if requested or if required arguments are missing - if (haveLongArg("help") || (needRequiredArg() && !haveRequiredArg())) + if (haveLongArg("help") || (needAdditionalArg() && !haveAdditionalArg())) { displayHelp(); return false; @@ -363,14 +415,6 @@ void CCmdArgs::displayHelp() } } - sint last = -1; - - // look for last required argument - for(uint i = 0; i < _Args.size(); ++i) - { - if (_Args[i].shortName.empty()) last = (sint)i; - } - // display required arguments for(uint i = 0; i < _Args.size(); ++i) { @@ -379,18 +423,24 @@ void CCmdArgs::displayHelp() // they don't have any short or long name, but need a name in help if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty()) { - printf(" <%s>", arg.helpName.c_str()); + printf(" %c%s", arg.required ? '<':'[', arg.helpName.c_str()); - // if last argument, it can support additional arguments - if ((sint)i == last) - { - printf(" [%s...]", arg.helpName.c_str()); - } + // if support more than once argument + if (!arg.onlyOnce) printf("..."); + + printf("%c", arg.required ? '>':']'); } } printf("\n"); + if (!_Description.empty()) + { + printf("\n%s", _Description.c_str()); + } + + printf("\nWhere options are:\n"); + // display details on each argument for(uint i = 0; i < _Args.size(); ++i) { @@ -399,19 +449,23 @@ void CCmdArgs::displayHelp() // not an optional argument if (arg.shortName.empty() && arg.longName.empty()) continue; - // a tab - printf("\t"); + // 2 spaces + printf(" "); + + std::vector syntaxes; // display short argument if (!arg.shortName.empty()) { - printf("-%s", arg.shortName.c_str()); - // and it's required argument if (!arg.helpName.empty()) { - printf(" <%s>", arg.helpName.c_str()); - printf(" or -%s<%s>", arg.shortName.c_str(), arg.helpName.c_str()); + syntaxes.push_back(toString("-%s <%s>", arg.shortName.c_str(), arg.helpName.c_str())); + syntaxes.push_back(toString("-%s<%s>", arg.shortName.c_str(), arg.helpName.c_str())); + } + else + { + syntaxes.push_back(toString("-%s", arg.shortName.c_str())); } } @@ -420,29 +474,29 @@ void CCmdArgs::displayHelp() { if (!arg.helpName.empty()) { - // prepend a coma if a short argument was already displayed - if (!arg.shortName.empty()) - { - printf(", "); - } - // display first syntax for long argument, --arg - printf("--%s <%s>", arg.longName.c_str(), arg.helpName.c_str()); + syntaxes.push_back(toString("--%s <%s>", arg.longName.c_str(), arg.helpName.c_str())); } - // prepend " or " if 3 formats for argument - if (!arg.shortName.empty() || !arg.helpName.empty()) - { - printf(" or "); - } - - // display second syntax for long argument, --arg= - printf("--%s", arg.longName.c_str()); - if (!arg.helpName.empty()) { - printf("=<%s>", arg.helpName.c_str()); + // display second syntax for long argument, --arg= + syntaxes.push_back(toString("--%s=<%s>", arg.longName.c_str(), arg.helpName.c_str())); } + else + { + syntaxes.push_back(toString("--%s", arg.longName.c_str())); + } + } + + for(uint j = 0; j < syntaxes.size(); ++j) + { + if (j > 0) + { + printf("%s ", (j == syntaxes.size() - 1) ? " or":","); + } + + printf("%s", syntaxes[j].c_str()); } // display argument description @@ -462,7 +516,7 @@ void CCmdArgs::displayHelp() // only display required arguments if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && !arg.helpDescription.empty()) { - printf("\t%s : %s\n", arg.helpName.c_str(), arg.helpDescription.c_str()); + printf(" %s : %s\n", arg.helpName.c_str(), arg.helpDescription.c_str()); } } } @@ -471,7 +525,7 @@ void CCmdArgs::displayVersion() { // display a verbose version string #ifdef BUILD_DATE - printf("%s %s (built on %s)\nCopyright (C) %s\n", _ProgramName.c_str(), NL_VERSION, BUILD_DATE, COPYRIGHT); + printf("%s %s (built on %s)\nCopyright (C) %s\n", _ProgramName.c_str(), _Version.c_str(), BUILD_DATE, COPYRIGHT); #endif } diff --git a/code/nel/tools/3d/panoply_preview/tool_main.cpp b/code/nel/tools/3d/panoply_preview/tool_main.cpp index 8cf0eec63..9c12f6f65 100644 --- a/code/nel/tools/3d/panoply_preview/tool_main.cpp +++ b/code/nel/tools/3d/panoply_preview/tool_main.cpp @@ -37,6 +37,20 @@ #include #include +#ifdef QT_STATICPLUGIN + +#include + +#if defined(Q_OS_WIN32) + Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) +#elif defined(Q_OS_MAC) + Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin) +#elif defined(Q_OS_UNIX) + Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) +#endif + +#endif + // NeL includes #include #include diff --git a/code/nel/tools/3d/tile_edit_qt/main.cpp b/code/nel/tools/3d/tile_edit_qt/main.cpp index 4a6ff4cbf..2b00dcbb8 100644 --- a/code/nel/tools/3d/tile_edit_qt/main.cpp +++ b/code/nel/tools/3d/tile_edit_qt/main.cpp @@ -16,6 +16,8 @@ #endif +#include "../shared_widgets/common.h" + int main(int argc, char *argv[]) { @@ -25,11 +27,12 @@ int main(int argc, char *argv[]) // the specific initialization routines you do not need. NLMISC::CApplicationContext myApplicationContext; + NLQT::preApplication(); Q_INIT_RESOURCE(tile_edit_qt); QApplication app(argc, argv); - CTile_edit_dlg *tileEdit = new CTile_edit_dlg; - tileEdit->show(); + CTile_edit_dlg tileEdit; + tileEdit.show(); return app.exec(); } \ No newline at end of file diff --git a/code/nel/tools/misc/crash_report/crash_report.cpp b/code/nel/tools/misc/crash_report/crash_report.cpp index f9191fde7..08063d78e 100644 --- a/code/nel/tools/misc/crash_report/crash_report.cpp +++ b/code/nel/tools/misc/crash_report/crash_report.cpp @@ -25,6 +25,8 @@ #include #include +#include "../../3d/shared_widgets/common.h" + class CCmdLineParser { public: @@ -105,6 +107,7 @@ int main(int argc, char **argv) } #endif + NLQT::preApplication(); QApplication app(argc, argv); QApplication::setWindowIcon(QIcon(":/icons/nevraxpill.ico")); diff --git a/code/nel/tools/nel_unit_test/nel_unit_test.cpp b/code/nel/tools/nel_unit_test/nel_unit_test.cpp index da11922cb..8289ea490 100644 --- a/code/nel/tools/nel_unit_test/nel_unit_test.cpp +++ b/code/nel/tools/nel_unit_test/nel_unit_test.cpp @@ -132,7 +132,7 @@ int main(int argc, char *argv[]) if (html) { std::ofstream fout(outputFileName); - html->generate(fout, true, "NeLTest"); + html->generate(fout, true, "NeL"); } } catch (...) diff --git a/code/nel/tools/nel_unit_test/ut_misc_string_common.h b/code/nel/tools/nel_unit_test/ut_misc_string_common.h index 43bfb76e1..099cf35f8 100644 --- a/code/nel/tools/nel_unit_test/ut_misc_string_common.h +++ b/code/nel/tools/nel_unit_test/ut_misc_string_common.h @@ -443,11 +443,13 @@ struct CUTMiscStringCommon : public Test::Suite // min limit -1 ret = NLMISC::fromString("-9223372036854775809", val); - TEST_ASSERT(!ret && val == 0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(LLONG_MIN == val); // max limit +1 ret = NLMISC::fromString("9223372036854775808", val); - TEST_ASSERT(!ret && val == 0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(LLONG_MAX == val); // with period ret = NLMISC::fromString("1.2", val); @@ -498,16 +500,19 @@ struct CUTMiscStringCommon : public Test::Suite TEST_ASSERT(ret && val == 0); // max limit - ret = NLMISC::fromString("4294967295", val); - TEST_ASSERT(ret && val == 4294967295); + ret = NLMISC::fromString("18446744073709551615", val); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(ULLONG_MAX == val); // min limit -1 ret = NLMISC::fromString("-1", val); - TEST_ASSERT(!ret && val == 0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(ULLONG_MAX == val); // max limit +1 - ret = NLMISC::fromString("4294967296", val); - TEST_ASSERT(!ret && val == 0); + ret = NLMISC::fromString("18446744073709551616", val); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(ULLONG_MAX == val); // with period ret = NLMISC::fromString("1.2", val); @@ -559,23 +564,28 @@ struct CUTMiscStringCommon : public Test::Suite // min limit ret = NLMISC::fromString("-2147483648", val); - TEST_ASSERT(ret && val == INT_MIN); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(INT_MIN == val); // max limit ret = NLMISC::fromString("2147483647", val); - TEST_ASSERT(ret && val == INT_MAX); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(INT_MAX == val); // min limit -1 ret = NLMISC::fromString("-2147483649", val); - TEST_ASSERT(!ret && val == 0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(INT_MIN == val); // max limit +1 ret = NLMISC::fromString("2147483648", val); - TEST_ASSERT(!ret && val == 0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(INT_MAX == val); // with period ret = NLMISC::fromString("1.2", val); - TEST_ASSERT(ret && val == 1); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(1.2f == val); // with coma ret = NLMISC::fromString("1,2", val); @@ -623,19 +633,23 @@ struct CUTMiscStringCommon : public Test::Suite // min limit ret = NLMISC::fromString("2.2250738585072014e-308", val); - TEST_ASSERT(ret && val == DBL_MIN); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(DBL_MIN == val); // max limit ret = NLMISC::fromString("1.7976931348623158e+308", val); - TEST_ASSERT(ret && val == DBL_MAX); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(DBL_MAX == val); // min limit -1 ret = NLMISC::fromString("3e-408", val); - TEST_ASSERT(!ret && val == 0.0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(0 == val); // max limit +1 ret = NLMISC::fromString("2e+308", val); - TEST_ASSERT(!ret && val == 0.0); + TEST_ASSERT_MSG(ret, "should succeed"); + TEST_ASSERT(INFINITY == val); // with period ret = NLMISC::fromString("1.2", val); @@ -670,60 +684,59 @@ struct CUTMiscStringCommon : public Test::Suite bool val; // true value + val = false; ret = NLMISC::fromString("1", val); - TEST_ASSERT(ret && val); + TEST_ASSERT(val); + TEST_ASSERT_MSG(ret, "should succeed"); - // false value + val = false; + NLMISC::fromString("t", val); + TEST_ASSERT(val); + + val = false; + NLMISC::fromString("y", val); + TEST_ASSERT(val); + + val = false; + NLMISC::fromString("T", val); + TEST_ASSERT(val); + + val = false; + NLMISC::fromString("Y", val); + TEST_ASSERT(val); + + val = true; ret = NLMISC::fromString("0", val); - TEST_ASSERT(ret && !val); + TEST_ASSERT(!val); + TEST_ASSERT_MSG(ret, "should succeed"); + + val = true; + NLMISC::fromString("f", val); + TEST_ASSERT(!val); + + val = true; + NLMISC::fromString("n", val); + TEST_ASSERT(!val); + + val = true; + NLMISC::fromString("F", val); + TEST_ASSERT(!val); + + val = true; + NLMISC::fromString("N", val); + TEST_ASSERT(!val); // bad character ret = NLMISC::fromString("a", val); - TEST_ASSERT(!ret && val); + TEST_ASSERT_MSG(!ret, "should not succeed"); - // right character and bad character - ret = NLMISC::fromString("1a", val); - TEST_ASSERT(!ret && val); + val = true; + NLMISC::fromString("a", val); + TEST_ASSERT_MSG(val, "should not modify the value"); - // min limit - ret = NLMISC::fromString("-2147483648", val); - TEST_ASSERT(!ret && val); - - // max limit - ret = NLMISC::fromString("2147483647", val); - TEST_ASSERT(!ret && val); - - // min limit -1 - ret = NLMISC::fromString("-2147483649", val); - TEST_ASSERT(!ret && val); - - // max limit +1 - ret = NLMISC::fromString("2147483648", val); - TEST_ASSERT(!ret && val); - - // with period - ret = NLMISC::fromString("1.2", val); - TEST_ASSERT(!ret && val); - - // with coma - ret = NLMISC::fromString("1,2", val); - TEST_ASSERT(!ret && val); - - // with spaces before - ret = NLMISC::fromString(" 10", val); - TEST_ASSERT(!ret && val); - - // with spaces after - ret = NLMISC::fromString("10 ", val); - TEST_ASSERT(!ret && val); - - // with 0s before - ret = NLMISC::fromString("001", val); - TEST_ASSERT(!ret && val); - - // with + before - ret = NLMISC::fromString("+1", val); - TEST_ASSERT(!ret && val); + val = false; + NLMISC::fromString("a", val); + TEST_ASSERT_MSG(!val, "should not modify the value"); } }; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index c220358c5..4f9f2aa09 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -637,12 +637,16 @@ static void addPaths(IProgressCallback &progress, const std::vector // check in same directory as bundle (Steam) directoryPrefixes.push_back(CPath::standardizePath(getAppBundlePath() + "/..")); #elif defined(NL_OS_UNIX) + // TODO: check in same directory as executable if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix())); #endif - float total = (float)(directoryPrefixes.size() * paths.size()); - float current = 0.f, next = 0.f; + std::vector directoriesToProcess; + // reserve maximum memory space for all combinations + directoriesToProcess.reserve(directoryPrefixes.size() * paths.size()); + + // first pass, build a vector with all existing directories to process in second pass for (uint j = 0; j < directoryPrefixes.size(); j++) { std::string directoryPrefix = directoryPrefixes[j]; @@ -651,26 +655,35 @@ static void addPaths(IProgressCallback &progress, const std::vector { std::string directory = NLMISC::expandEnvironmentVariables(paths[i]); - // only prepend default directory if path is relative + // only prepend prefix if path is relative if (!directory.empty() && !directoryPrefix.empty() && !CPath::isAbsolutePath(directory)) - { directory = directoryPrefix + directory; - } - // update next progress value - next += 1.f; - - progress.progress (current/total); - progress.pushCropedValues (current/total, next/total); - - // next is current value - current = next; - - CPath::addSearchPath(directory, recurse, false, &progress); - - progress.popCropedValues (); + // only process existing directories + if (CFile::isExists(directory)) + directoriesToProcess.push_back(directory); } } + + uint total = (uint)directoriesToProcess.size(); + uint current = 0, next = 0; + + // second pass, add search paths + for (uint i = 0, len = directoriesToProcess.size(); i < len; ++i) + { + // update next progress value + ++next; + + progress.progress((float)current/(float)total); + progress.pushCropedValues((float)current/(float)total, (float)next/(float)total); + + // next is current value + current = next; + + CPath::addSearchPath(directoriesToProcess[i], recurse, false, &progress); + + progress.popCropedValues(); + } } void addSearchPaths(IProgressCallback &progress) diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp index fee925d64..1c596e837 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/main.cpp @@ -31,7 +31,15 @@ int main(int argc, char *argv[]) { NLMISC::CApplicationContext appContext; - CPath::addSearchPath("L:\\primitives\\", true, false); + const char *leveldesignPath = getenv("RYZOM_LEVELDESIGN"); + + if (leveldesignPath == NULL) + { + printf("Error: You need to define RYZOM_LEVELDESIGN environment variable that points to previous L:\\ equivalent under Windows\n"); + return -1; + } + + CPath::addSearchPath(NLMISC::CPath::standardizePath(leveldesignPath), true, false); bool test = false; if (argc == 4 && string(argv[3]) == "-test") @@ -43,35 +51,35 @@ int main(int argc, char *argv[]) printf("%s [-test]", argv[0]); return -1; } - + string sourceDocName; if (!test) sourceDocName = argv[2]; else sourceDocName = "test_compilateur.primitive"; - + // remove the path sourceDocName = CFile::getFilename(sourceDocName); // init ligo NLLIGO::CLigoConfig LigoConfig; CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; - + nlinfo("Reading ligo configuration file..."); if (!LigoConfig.readPrimitiveClass (argv[1], false)) { nlwarning("Can't read '%s' !", argv[1]); return -1; } - + NLLIGO::Register(); nlinfo("Reading primitive file..."); - + CPrimitives primDoc; CPrimitiveContext::instance().CurrentPrimitive = &primDoc; loadXmlPrimitiveFile(primDoc, sourceDocName, LigoConfig); - + CMissionCompiler mc; if (test) @@ -91,7 +99,7 @@ int main(int argc, char *argv[]) script = script.replace(NL.c_str(), "\n"); const char *tmp = ::getenv("TEMP"); - + FILE *fp = ::fopen((string(tmp)+"/compiled_mission.script").c_str(), "w"); ::fwrite(script.data(), script.size(), 1, fp); ::fclose(fp); @@ -111,7 +119,7 @@ int main(int argc, char *argv[]) } return 0; } - + nlinfo("Compiling missions..."); try { @@ -158,14 +166,14 @@ int main(int argc, char *argv[]) TPrimitiveSet scripts; CPrimitiveSet filter; filter.buildSet(primDoc->RootNode, TPrimitiveClassPredicate("mission"), scripts); - + // for each script, check if it was generated, and if so, check the name // of the source primitive file. for (uint i=0; i *script; if (scripts[i]->getPropertyByName("script", script) && !script->empty()) - { + { // Format should be : #compiled from if (script->front().find("compiled from")) { @@ -200,14 +208,14 @@ int main(int argc, char *argv[]) if (bots.empty()) { - nlwarning("Can't find bot '%s' in primitive '%s' !", + nlwarning("Can't find bot '%s' in primitive '%s' !", mission.getGiverName().c_str(), fileName.c_str()); throw EParseException(NULL, "Can't find giver in primitive"); } else if (bots.size() > 1) { - nlwarning("Found more than one bot named '%s' in primitive '%s' !", + nlwarning("Found more than one bot named '%s' in primitive '%s' !", mission.getGiverName().c_str(), fileName.c_str()); throw EParseException(NULL, "More than one bot with giver name in primitive");