Merge with develop

This commit is contained in:
kervala 2016-01-18 21:32:01 +01:00
parent 3be3e94aec
commit 63984e4a2a
10 changed files with 297 additions and 159 deletions

View file

@ -6,10 +6,15 @@ compiler:
os: os:
- linux - linux
matrix:
fast_finish: true
env: env:
- CMAKE_BUILD_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=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_CONFIGURE_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=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: addons:
apt: apt:
@ -30,10 +35,12 @@ addons:
before_script: before_script:
- mkdir build - mkdir build
- cmake --version - cmake --version
- cmake -Hcode -Bbuild $CMAKE_CONFIGURE_OPTIONS
- cat build/CMakeCache.txt
script: script:
- cmake -Hcode -Bbuild $CMAKE_BUILD_OPTIONS - cmake --build build $CMAKE_BUILD_OPTIONS
- cmake --build build -- -j 2 - $RUN
notifications: notifications:
irc: irc:

View file

@ -40,6 +40,8 @@ public:
std::string helpName; // name of argument in help. Eg: <output directory> std::string helpName; // name of argument in help. Eg: <output directory>
std::string helpDescription; // description of argument in help. Eg: Specifies the directory where to write generated files 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 bool found; // all values for this argument
std::vector<std::string> values; // all values for this argument std::vector<std::string> values; // all values for this argument
@ -55,12 +57,15 @@ public:
/// longName is "print" of the argument is --print /// longName is "print" of the argument is --print
/// helpName is the name that will be displayed in help if it's a required argument /// 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 /// 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 /// 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 /// 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. /// Parse the command line from main() parameters argc and argv and process default arguments.
bool parse(int argc, char **argv); bool parse(int argc, char **argv);
@ -93,21 +98,39 @@ public:
std::vector<std::string> getLongArg(const std::string &argName) const; std::vector<std::string> getLongArg(const std::string &argName) const;
/// return true if there are arguments that are required /// 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 /// return true if any additional args are present on the commandline
bool haveRequiredArg() const; bool haveAdditionalArg() const;
/// Returns all additional required parameters /// return true if a specific additional arg is present on the commandline
std::vector<std::string> getRequiredArg() const; bool haveAdditionalArg(const std::string &name) const;
/// Returns values of a specific additional arg
std::vector<std::string> getAdditionalArg(const std::string &name) const;
/// Display help of the program. /// Display help of the program.
void displayHelp(); void displayHelp();
/// Display version of the program. /// Display version of the program.
void displayVersion(); 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: 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 /// Array of arguments pass from the command line
TArgs _Args; TArgs _Args;

View file

@ -33,6 +33,10 @@ namespace NLMISC
CCmdArgs::CCmdArgs() CCmdArgs::CCmdArgs()
{ {
#ifdef NL_VERSION
_Version = NL_VERSION;
#endif
// add help // add help
addArg("h", "help", "", "Display this help"); addArg("h", "help", "", "Display this help");
@ -45,24 +49,28 @@ void CCmdArgs::addArg(const TArg &arg)
_Args.push_back(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; TArg arg;
arg.shortName = shortName; arg.shortName = shortName;
arg.longName = longName; arg.longName = longName;
arg.helpName = helpName; arg.helpName = helpName;
arg.helpDescription = helpDescription; arg.helpDescription = helpDescription;
arg.onlyOnce = onlyOnce;
arg.found = false; arg.found = false;
arg.required = false;
addArg(arg); 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; TArg arg;
arg.helpName = helpName; arg.helpName = helpName;
arg.helpDescription = helpDescription; arg.helpDescription = helpDescription;
arg.onlyOnce = onlyOnce;
arg.found = false; arg.found = false;
arg.required = required;
addArg(arg); addArg(arg);
} }
@ -125,7 +133,7 @@ std::vector<std::string> CCmdArgs::getLongArg(const std::string &argName) const
return std::vector<std::string>(); return std::vector<std::string>();
} }
bool CCmdArgs::needRequiredArg() const bool CCmdArgs::needAdditionalArg() const
{ {
// process each argument // process each argument
for(uint i = 0; i < _Args.size(); ++i) for(uint i = 0; i < _Args.size(); ++i)
@ -133,14 +141,14 @@ bool CCmdArgs::needRequiredArg() const
const TArg &arg = _Args[i]; const TArg &arg = _Args[i];
// they don't have any short or long name, but need a name in help // 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 true;
} }
return false; return false;
} }
bool CCmdArgs::haveRequiredArg() const bool CCmdArgs::haveAdditionalArg() const
{ {
// process each argument // process each argument
for(uint i = 0; i < _Args.size(); ++i) for(uint i = 0; i < _Args.size(); ++i)
@ -148,14 +156,14 @@ bool CCmdArgs::haveRequiredArg() const
const TArg &arg = _Args[i]; const TArg &arg = _Args[i];
// they don't have any short or long name, but need a name in help // 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.found)
return !arg.values.empty(); return false;
} }
return false; return false;
} }
std::vector<std::string> CCmdArgs::getRequiredArg() const bool CCmdArgs::haveAdditionalArg(const std::string &name) const
{ {
// process each argument // process each argument
for(uint i = 0; i < _Args.size(); ++i) for(uint i = 0; i < _Args.size(); ++i)
@ -163,7 +171,22 @@ std::vector<std::string> CCmdArgs::getRequiredArg() const
const TArg &arg = _Args[i]; const TArg &arg = _Args[i];
// they don't have any short or long name, but need a name in help // 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<std::string> 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; return arg.values;
} }
@ -174,6 +197,15 @@ std::vector<std::string> CCmdArgs::getRequiredArg() const
bool CCmdArgs::parse(const std::string &args) bool CCmdArgs::parse(const std::string &args)
{ {
std::vector<std::string> argv; std::vector<std::string> 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; std::string::size_type pos1 = 0, pos2 = 0;
do do
@ -230,6 +262,7 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
// first argument is always the program name // first argument is always the program name
_ProgramName = CFile::getFilename(argv.front()); _ProgramName = CFile::getFilename(argv.front());
_ProgramPath = CPath::standardizePath(CFile::getPath(argv.front()));
// arguments count // arguments count
uint argc = argv.size(); uint argc = argv.size();
@ -272,6 +305,8 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
name = name.substr(0, 1); name = name.substr(0, 1);
} }
bool found = false;
// process each argument definition // process each argument definition
for(uint j = 0; j < _Args.size(); ++j) for(uint j = 0; j < _Args.size(); ++j)
{ {
@ -280,8 +315,15 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
// only process arguments of the right type // only process arguments of the right type
if ((useLongName && name != arg.longName) || (!useLongName && name != arg.shortName)) continue; 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 // argument is found
arg.found = true; found = arg.found = true;
// another argument is required // another argument is required
if (!arg.helpName.empty()) if (!arg.helpName.empty())
@ -302,6 +344,11 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
break; break;
} }
if (!found)
{
printf("Warning: Argument %s not recognized, skip it!\n", name.c_str());
}
} }
else else
{ {
@ -313,6 +360,11 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
// only process arguments that don't have a name // only process arguments that don't have a name
if (!arg.shortName.empty() || !arg.longName.empty()) continue; 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 // in fact, if there are more than one required arguments, all arguments are added in first one to simplify
arg.values.push_back(name); arg.values.push_back(name);
@ -329,7 +381,7 @@ bool CCmdArgs::parse(const std::vector<std::string> &argv)
} }
// process help if requested or if required arguments are missing // process help if requested or if required arguments are missing
if (haveLongArg("help") || (needRequiredArg() && !haveRequiredArg())) if (haveLongArg("help") || (needAdditionalArg() && !haveAdditionalArg()))
{ {
displayHelp(); displayHelp();
return false; 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 // display required arguments
for(uint i = 0; i < _Args.size(); ++i) 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 // 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())
{ {
printf(" <%s>", arg.helpName.c_str()); printf(" %c%s", arg.required ? '<':'[', arg.helpName.c_str());
// if last argument, it can support additional arguments // if support more than once argument
if ((sint)i == last) if (!arg.onlyOnce) printf("...");
{
printf(" [%s...]", arg.helpName.c_str()); printf("%c", arg.required ? '>':']');
}
} }
} }
printf("\n"); printf("\n");
if (!_Description.empty())
{
printf("\n%s", _Description.c_str());
}
printf("\nWhere options are:\n");
// display details on each argument // display details on each argument
for(uint i = 0; i < _Args.size(); ++i) for(uint i = 0; i < _Args.size(); ++i)
{ {
@ -399,19 +449,23 @@ void CCmdArgs::displayHelp()
// not an optional argument // not an optional argument
if (arg.shortName.empty() && arg.longName.empty()) continue; if (arg.shortName.empty() && arg.longName.empty()) continue;
// a tab // 2 spaces
printf("\t"); printf(" ");
std::vector<std::string> syntaxes;
// display short argument // display short argument
if (!arg.shortName.empty()) if (!arg.shortName.empty())
{ {
printf("-%s", arg.shortName.c_str());
// and it's required argument // and it's required argument
if (!arg.helpName.empty()) if (!arg.helpName.empty())
{ {
printf(" <%s>", arg.helpName.c_str()); syntaxes.push_back(toString("-%s <%s>", arg.shortName.c_str(), 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()));
}
else
{
syntaxes.push_back(toString("-%s", arg.shortName.c_str()));
} }
} }
@ -420,29 +474,29 @@ void CCmdArgs::displayHelp()
{ {
if (!arg.helpName.empty()) 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 <value> // display first syntax for long argument, --arg <value>
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=<value>
printf("--%s", arg.longName.c_str());
if (!arg.helpName.empty()) if (!arg.helpName.empty())
{ {
printf("=<%s>", arg.helpName.c_str()); // display second syntax for long argument, --arg=<value>
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 // display argument description
@ -462,7 +516,7 @@ void CCmdArgs::displayHelp()
// only display required arguments // only display required arguments
if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && !arg.helpDescription.empty()) 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 // display a verbose version string
#ifdef BUILD_DATE #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 #endif
} }

View file

@ -37,6 +37,20 @@
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <QStyleFactory> #include <QStyleFactory>
#ifdef QT_STATICPLUGIN
#include <QtPlugin>
#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 // NeL includes
#include <nel/misc/debug.h> #include <nel/misc/debug.h>
#include <nel/misc/common.h> #include <nel/misc/common.h>

View file

@ -16,6 +16,8 @@
#endif #endif
#include "../shared_widgets/common.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -25,11 +27,12 @@ int main(int argc, char *argv[])
// the specific initialization routines you do not need. // the specific initialization routines you do not need.
NLMISC::CApplicationContext myApplicationContext; NLMISC::CApplicationContext myApplicationContext;
NLQT::preApplication();
Q_INIT_RESOURCE(tile_edit_qt); Q_INIT_RESOURCE(tile_edit_qt);
QApplication app(argc, argv); QApplication app(argc, argv);
CTile_edit_dlg *tileEdit = new CTile_edit_dlg; CTile_edit_dlg tileEdit;
tileEdit->show(); tileEdit.show();
return app.exec(); return app.exec();
} }

View file

@ -25,6 +25,8 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "../../3d/shared_widgets/common.h"
class CCmdLineParser class CCmdLineParser
{ {
public: public:
@ -105,6 +107,7 @@ int main(int argc, char **argv)
} }
#endif #endif
NLQT::preApplication();
QApplication app(argc, argv); QApplication app(argc, argv);
QApplication::setWindowIcon(QIcon(":/icons/nevraxpill.ico")); QApplication::setWindowIcon(QIcon(":/icons/nevraxpill.ico"));

View file

@ -132,7 +132,7 @@ int main(int argc, char *argv[])
if (html) if (html)
{ {
std::ofstream fout(outputFileName); std::ofstream fout(outputFileName);
html->generate(fout, true, "NeLTest"); html->generate(fout, true, "NeL");
} }
} }
catch (...) catch (...)

View file

@ -443,11 +443,13 @@ struct CUTMiscStringCommon : public Test::Suite
// min limit -1 // min limit -1
ret = NLMISC::fromString("-9223372036854775809", val); ret = NLMISC::fromString("-9223372036854775809", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(LLONG_MIN == val);
// max limit +1 // max limit +1
ret = NLMISC::fromString("9223372036854775808", val); ret = NLMISC::fromString("9223372036854775808", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(LLONG_MAX == val);
// with period // with period
ret = NLMISC::fromString("1.2", val); ret = NLMISC::fromString("1.2", val);
@ -498,16 +500,19 @@ struct CUTMiscStringCommon : public Test::Suite
TEST_ASSERT(ret && val == 0); TEST_ASSERT(ret && val == 0);
// max limit // max limit
ret = NLMISC::fromString("4294967295", val); ret = NLMISC::fromString("18446744073709551615", val);
TEST_ASSERT(ret && val == 4294967295); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(ULLONG_MAX == val);
// min limit -1 // min limit -1
ret = NLMISC::fromString("-1", val); ret = NLMISC::fromString("-1", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(ULLONG_MAX == val);
// max limit +1 // max limit +1
ret = NLMISC::fromString("4294967296", val); ret = NLMISC::fromString("18446744073709551616", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(ULLONG_MAX == val);
// with period // with period
ret = NLMISC::fromString("1.2", val); ret = NLMISC::fromString("1.2", val);
@ -559,23 +564,28 @@ struct CUTMiscStringCommon : public Test::Suite
// min limit // min limit
ret = NLMISC::fromString("-2147483648", val); ret = NLMISC::fromString("-2147483648", val);
TEST_ASSERT(ret && val == INT_MIN); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(INT_MIN == val);
// max limit // max limit
ret = NLMISC::fromString("2147483647", val); 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 // min limit -1
ret = NLMISC::fromString("-2147483649", val); ret = NLMISC::fromString("-2147483649", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(INT_MIN == val);
// max limit +1 // max limit +1
ret = NLMISC::fromString("2147483648", val); ret = NLMISC::fromString("2147483648", val);
TEST_ASSERT(!ret && val == 0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(INT_MAX == val);
// with period // with period
ret = NLMISC::fromString("1.2", val); ret = NLMISC::fromString("1.2", val);
TEST_ASSERT(ret && val == 1); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(1.2f == val);
// with coma // with coma
ret = NLMISC::fromString("1,2", val); ret = NLMISC::fromString("1,2", val);
@ -623,19 +633,23 @@ struct CUTMiscStringCommon : public Test::Suite
// min limit // min limit
ret = NLMISC::fromString("2.2250738585072014e-308", val); 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 // max limit
ret = NLMISC::fromString("1.7976931348623158e+308", val); 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 // min limit -1
ret = NLMISC::fromString("3e-408", val); 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 // max limit +1
ret = NLMISC::fromString("2e+308", val); ret = NLMISC::fromString("2e+308", val);
TEST_ASSERT(!ret && val == 0.0); TEST_ASSERT_MSG(ret, "should succeed");
TEST_ASSERT(INFINITY == val);
// with period // with period
ret = NLMISC::fromString("1.2", val); ret = NLMISC::fromString("1.2", val);
@ -670,60 +684,59 @@ struct CUTMiscStringCommon : public Test::Suite
bool val; bool val;
// true value // true value
val = false;
ret = NLMISC::fromString("1", val); 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); 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 // bad character
ret = NLMISC::fromString("a", val); ret = NLMISC::fromString("a", val);
TEST_ASSERT(!ret && val); TEST_ASSERT_MSG(!ret, "should not succeed");
// right character and bad character val = true;
ret = NLMISC::fromString("1a", val); NLMISC::fromString("a", val);
TEST_ASSERT(!ret && val); TEST_ASSERT_MSG(val, "should not modify the value");
// min limit val = false;
ret = NLMISC::fromString("-2147483648", val); NLMISC::fromString("a", val);
TEST_ASSERT(!ret && val); TEST_ASSERT_MSG(!val, "should not modify the value");
// 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);
} }
}; };

View file

@ -637,12 +637,16 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
// check in same directory as bundle (Steam) // check in same directory as bundle (Steam)
directoryPrefixes.push_back(CPath::standardizePath(getAppBundlePath() + "/..")); directoryPrefixes.push_back(CPath::standardizePath(getAppBundlePath() + "/.."));
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
// TODO: check in same directory as executable
if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix())); if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix()));
#endif #endif
float total = (float)(directoryPrefixes.size() * paths.size()); std::vector<std::string> directoriesToProcess;
float current = 0.f, next = 0.f;
// 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++) for (uint j = 0; j < directoryPrefixes.size(); j++)
{ {
std::string directoryPrefix = directoryPrefixes[j]; std::string directoryPrefix = directoryPrefixes[j];
@ -651,26 +655,35 @@ static void addPaths(IProgressCallback &progress, const std::vector<std::string>
{ {
std::string directory = NLMISC::expandEnvironmentVariables(paths[i]); 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)) if (!directory.empty() && !directoryPrefix.empty() && !CPath::isAbsolutePath(directory))
{
directory = directoryPrefix + directory; directory = directoryPrefix + directory;
}
// update next progress value // only process existing directories
next += 1.f; if (CFile::isExists(directory))
directoriesToProcess.push_back(directory);
progress.progress (current/total);
progress.pushCropedValues (current/total, next/total);
// next is current value
current = next;
CPath::addSearchPath(directory, recurse, false, &progress);
progress.popCropedValues ();
} }
} }
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) void addSearchPaths(IProgressCallback &progress)

View file

@ -31,7 +31,15 @@ int main(int argc, char *argv[])
{ {
NLMISC::CApplicationContext appContext; 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; bool test = false;
if (argc == 4 && string(argv[3]) == "-test") if (argc == 4 && string(argv[3]) == "-test")
@ -43,35 +51,35 @@ int main(int argc, char *argv[])
printf("%s <world_edit_class> <primitive_file> [-test]", argv[0]); printf("%s <world_edit_class> <primitive_file> [-test]", argv[0]);
return -1; return -1;
} }
string sourceDocName; string sourceDocName;
if (!test) if (!test)
sourceDocName = argv[2]; sourceDocName = argv[2];
else else
sourceDocName = "test_compilateur.primitive"; sourceDocName = "test_compilateur.primitive";
// remove the path // remove the path
sourceDocName = CFile::getFilename(sourceDocName); sourceDocName = CFile::getFilename(sourceDocName);
// init ligo // init ligo
NLLIGO::CLigoConfig LigoConfig; NLLIGO::CLigoConfig LigoConfig;
CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig; CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
nlinfo("Reading ligo configuration file..."); nlinfo("Reading ligo configuration file...");
if (!LigoConfig.readPrimitiveClass (argv[1], false)) if (!LigoConfig.readPrimitiveClass (argv[1], false))
{ {
nlwarning("Can't read '%s' !", argv[1]); nlwarning("Can't read '%s' !", argv[1]);
return -1; return -1;
} }
NLLIGO::Register(); NLLIGO::Register();
nlinfo("Reading primitive file..."); nlinfo("Reading primitive file...");
CPrimitives primDoc; CPrimitives primDoc;
CPrimitiveContext::instance().CurrentPrimitive = &primDoc; CPrimitiveContext::instance().CurrentPrimitive = &primDoc;
loadXmlPrimitiveFile(primDoc, sourceDocName, LigoConfig); loadXmlPrimitiveFile(primDoc, sourceDocName, LigoConfig);
CMissionCompiler mc; CMissionCompiler mc;
if (test) if (test)
@ -91,7 +99,7 @@ int main(int argc, char *argv[])
script = script.replace(NL.c_str(), "\n"); script = script.replace(NL.c_str(), "\n");
const char *tmp = ::getenv("TEMP"); const char *tmp = ::getenv("TEMP");
FILE *fp = ::fopen((string(tmp)+"/compiled_mission.script").c_str(), "w"); FILE *fp = ::fopen((string(tmp)+"/compiled_mission.script").c_str(), "w");
::fwrite(script.data(), script.size(), 1, fp); ::fwrite(script.data(), script.size(), 1, fp);
::fclose(fp); ::fclose(fp);
@ -111,7 +119,7 @@ int main(int argc, char *argv[])
} }
return 0; return 0;
} }
nlinfo("Compiling missions..."); nlinfo("Compiling missions...");
try try
{ {
@ -158,14 +166,14 @@ int main(int argc, char *argv[])
TPrimitiveSet scripts; TPrimitiveSet scripts;
CPrimitiveSet<TPrimitiveClassPredicate> filter; CPrimitiveSet<TPrimitiveClassPredicate> filter;
filter.buildSet(primDoc->RootNode, TPrimitiveClassPredicate("mission"), scripts); filter.buildSet(primDoc->RootNode, TPrimitiveClassPredicate("mission"), scripts);
// for each script, check if it was generated, and if so, check the name // for each script, check if it was generated, and if so, check the name
// of the source primitive file. // of the source primitive file.
for (uint i=0; i<scripts.size(); ++i) for (uint i=0; i<scripts.size(); ++i)
{ {
vector<string> *script; vector<string> *script;
if (scripts[i]->getPropertyByName("script", script) && !script->empty()) if (scripts[i]->getPropertyByName("script", script) && !script->empty())
{ {
// Format should be : #compiled from <source_primitive_name> // Format should be : #compiled from <source_primitive_name>
if (script->front().find("compiled from")) if (script->front().find("compiled from"))
{ {
@ -200,14 +208,14 @@ int main(int argc, char *argv[])
if (bots.empty()) 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(), mission.getGiverName().c_str(),
fileName.c_str()); fileName.c_str());
throw EParseException(NULL, "Can't find giver in primitive"); throw EParseException(NULL, "Can't find giver in primitive");
} }
else if (bots.size() > 1) 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(), mission.getGiverName().c_str(),
fileName.c_str()); fileName.c_str());
throw EParseException(NULL, "More than one bot with giver name in primitive"); throw EParseException(NULL, "More than one bot with giver name in primitive");