diff --git a/CHANGELOG b/CHANGELOG index ec49771375..207a4648d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ v2.5.0 (XXXX-XX-XX) ------------------- +* fixed issue #1226: arangod log issues + * added AQL optimizer rule "move-calculations-down" * use exclusive native SRWLocks on Windows instead of native mutexes diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 5e6a35dcf8..554505115d 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -53,21 +53,21 @@ using JsonHelper = triagens::basics::JsonHelper; /// expressions but must never be freed //////////////////////////////////////////////////////////////////////////////// -TRI_json_t const Expression::NullJson = { TRI_JSON_NULL, false }; +TRI_json_t const Expression::NullJson = { TRI_JSON_NULL, { false } }; //////////////////////////////////////////////////////////////////////////////// /// @brief "constant" global object for TRUE which can be shared by all /// expressions but must never be freed //////////////////////////////////////////////////////////////////////////////// -TRI_json_t const Expression::TrueJson = { TRI_JSON_BOOLEAN, true }; +TRI_json_t const Expression::TrueJson = { TRI_JSON_BOOLEAN, { true } }; //////////////////////////////////////////////////////////////////////////////// /// @brief "constant" global object for FALSE which can be shared by all /// expressions but must never be freed //////////////////////////////////////////////////////////////////////////////// -TRI_json_t const Expression::FalseJson = { TRI_JSON_BOOLEAN, false }; +TRI_json_t const Expression::FalseJson = { TRI_JSON_BOOLEAN, { false } }; // ----------------------------------------------------------------------------- // --SECTION-- constructors / destructors diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index 7956ae0d79..1d6fc01593 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -424,7 +424,7 @@ void ArangoServer::buildApplicationServer () { string ignoreOpt; - additional[ApplicationServer::OPTIONS_HIDDEN] + additional["Hidden Options"] ("ruby.gc-interval", &ignoreOpt, "Ruby garbage collection interval (each x requests)") ("ruby.action-directory", &ignoreOpt, "path to the Ruby action directory") ("ruby.modules-path", &ignoreOpt, "one or more directories separated by (semi-) colons") @@ -451,7 +451,7 @@ void ArangoServer::buildApplicationServer () { // ............................................................................. // command-line only options - additional[ApplicationServer::OPTIONS_CMDLINE] + additional["General Options:help-default"] ("console", "do not start as server, start a JavaScript emergency console instead") ("upgrade", "perform a database upgrade") ("check-version", "checks the versions of the database and exit") @@ -461,7 +461,7 @@ void ArangoServer::buildApplicationServer () { // set language of default collator // ............................................................................. - additional[ApplicationServer::OPTIONS_SERVER] + additional["Server Options:help-default"] ("temp-path", &_tempPath, "temporary path") ("default-language", &_defaultLanguage, "ISO-639 language code") ; @@ -479,7 +479,7 @@ void ArangoServer::buildApplicationServer () { } // other options - additional[ApplicationServer::OPTIONS_HIDDEN] + additional["Hidden Options"] ("no-upgrade", "skip a database upgrade") ("start-service", "used to start as windows service") ("no-server", "do not start the server, if console is requested") @@ -491,7 +491,7 @@ void ArangoServer::buildApplicationServer () { #ifndef _WIN32 - additional[ApplicationServer::OPTIONS_CMDLINE + ":help-extended"] + additional["General Options:help-admin"] ("daemon", "run as daemon") ("pid-file", &_pidFile, "pid-file in daemon mode") ("supervisor", "starts a supervisor and runs as daemon") @@ -501,12 +501,12 @@ void ArangoServer::buildApplicationServer () { #endif #ifdef __APPLE__ - additional[ApplicationServer::OPTIONS_CMDLINE + ":help-extended"] + additional["General Options:help-admin"] ("voice", "enable voice based welcome") ; #endif - additional[ApplicationServer::OPTIONS_HIDDEN] + additional["Hidden Options"] ("development-mode", "start server in development mode") ; @@ -514,12 +514,12 @@ void ArangoServer::buildApplicationServer () { // javascript options // ............................................................................. - additional["JAVASCRIPT Options:help-admin"] + additional["Javascript Options:help-admin"] ("javascript.script", &_scriptFile, "do not start as server, run script instead") ("javascript.script-parameter", &_scriptParameters, "script parameter") ; - additional["JAVASCRIPT Options:help-devel"] + additional["Hidden Options"] ("javascript.unit-tests", &_unitTests, "do not start as server, run unit tests instead") ; @@ -527,11 +527,11 @@ void ArangoServer::buildApplicationServer () { // database options // ............................................................................. - additional["DIRECTORY Options:help-admin"] + additional["Database Options:help-admin"] ("database.directory", &_databasePath, "path to the database directory") ; - additional["DATABASE Options:help-admin"] + additional["Database Options:help-admin"] ("database.maximal-journal-size", &_defaultMaximalSize, "default maximal journal size, can be overwritten when creating a collection") ("database.wait-for-sync", &_defaultWaitForSync, "default wait-for-sync behavior, can be overwritten when creating a collection") ("database.force-sync-properties", &_forceSyncProperties, "force syncing of collection properties to disk, will use waitForSync value of collection when turned off") @@ -557,7 +557,7 @@ void ArangoServer::buildApplicationServer () { // for this server we display our own options such as port to use // ............................................................................. - additional[ApplicationServer::OPTIONS_SERVER + ":help-admin"] + additional["Server Options:help-admin"] ("server.authenticate-system-only", &_authenticateSystemOnly, "use HTTP authentication only for requests to /_api and /_admin") ("server.disable-authentication", &_disableAuthentication, "disable authentication for ALL client requests") #ifdef TRI_HAVE_LINUX_SOCKETS @@ -565,22 +565,22 @@ void ArangoServer::buildApplicationServer () { #endif ("server.disable-replication-applier", &_disableReplicationApplier, "start with replication applier turned off") ("server.allow-use-database", &ALLOW_USE_DATABASE_IN_REST_ACTIONS, "allow change of database in REST actions, only needed for unittests") + ("server.threads", &_dispatcherThreads, "number of threads for basic operations") ; bool disableStatistics = false; #if TRI_ENABLE_FIGURES - additional[ApplicationServer::OPTIONS_SERVER + ":help-admin"] + additional["Server Options:help-admin"] ("server.disable-statistics", &disableStatistics, "turn off statistics gathering") ; #endif - additional["THREAD Options:help-admin"] - ("server.threads", &_dispatcherThreads, "number of threads for basic operations") + additional["Javascript Options:help-admin"] ("javascript.v8-contexts", &_v8Contexts, "number of V8 contexts that are created for executing JavaScript actions") ; - additional["Server Options:help-extended"] + additional["Server Options:help-admin"] ("scheduler.maximal-queue-size", &_dispatcherQueueSize, "maximum size of queue for asynchronous operations") ; @@ -882,6 +882,7 @@ int ArangoServer::startupServer () { httpOptions._queue = "STANDARD"; if (startServer) { + // start with enabled maintenance mode HttpHandlerFactory::setMaintenance(true); diff --git a/arangod/V8Server/ApplicationV8.cpp b/arangod/V8Server/ApplicationV8.cpp index 409ce3d6df..5272f64f43 100644 --- a/arangod/V8Server/ApplicationV8.cpp +++ b/arangod/V8Server/ApplicationV8.cpp @@ -972,7 +972,7 @@ bool ApplicationV8::prepareNamedContexts (const string& name, //////////////////////////////////////////////////////////////////////////////// void ApplicationV8::setupOptions (map& options) { - options["JAVASCRIPT Options:help-admin"] + options["Javascript Options:help-admin"] ("javascript.gc-interval", &_gcInterval, "JavaScript request-based garbage collection interval (each x requests)") ("javascript.gc-frequency", &_gcFrequency, "JavaScript time-based garbage collection frequency (each x seconds)") ("javascript.app-path", &_appPath, "directory for Foxx applications (normal mode)") @@ -981,7 +981,7 @@ void ApplicationV8::setupOptions (map ("javascript.v8-options", &_v8Options, "options to pass to v8") ; - options[ApplicationServer::OPTIONS_HIDDEN] + options["Hidden Options"] ("javascript.frontend-development", &_frontendDevelopmentMode, "allows rebuild frontend assets") // deprecated options diff --git a/lib/Admin/ApplicationAdminServer.cpp b/lib/Admin/ApplicationAdminServer.cpp index 0467e4a800..5c82f1e3ab 100644 --- a/lib/Admin/ApplicationAdminServer.cpp +++ b/lib/Admin/ApplicationAdminServer.cpp @@ -148,7 +148,7 @@ void ApplicationAdminServer::addHandlers (HttpHandlerFactory* factory, string co void ApplicationAdminServer::setupOptions (map& options) { // deprecated options - options[ApplicationServer::OPTIONS_HIDDEN] + options["Hidden Options"] ("server.admin-directory", &UnusedAdminDirectory, "directory containing the ADMIN front-end (deprecated)") ("server.disable-admin-interface", &UnusedDisableAdminInterface, "turn off the HTML admin interface (deprecated)") ; diff --git a/lib/ApplicationServer/ApplicationServer.cpp b/lib/ApplicationServer/ApplicationServer.cpp index 483828a56f..53f61ff235 100644 --- a/lib/ApplicationServer/ApplicationServer.cpp +++ b/lib/ApplicationServer/ApplicationServer.cpp @@ -59,35 +59,21 @@ static string DeprecatedParameter; // --SECTION-- public constants // ----------------------------------------------------------------------------- -//////////////////////////////////////////////////////////////////////////////// -/// @brief Command Line Options -//////////////////////////////////////////////////////////////////////////////// - -string const ApplicationServer::OPTIONS_CMDLINE = "Command Line Options"; - //////////////////////////////////////////////////////////////////////////////// /// @brief Hidden Options //////////////////////////////////////////////////////////////////////////////// -string const ApplicationServer::OPTIONS_HIDDEN = "Hidden Options"; +namespace { + const string OPTIONS_HIDDEN = "Hidden Options"; +} //////////////////////////////////////////////////////////////////////////////// -/// @brief Logger Options +/// @brief Command Line Options //////////////////////////////////////////////////////////////////////////////// -string const ApplicationServer::OPTIONS_LOGGER = "Logging Options"; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Server Options -//////////////////////////////////////////////////////////////////////////////// - -string const ApplicationServer::OPTIONS_SERVER = "Server Options"; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief SSL Options -//////////////////////////////////////////////////////////////////////////////// - -string const ApplicationServer::OPTIONS_SSL = "SSL Options"; +namespace { + const string OPTIONS_CMDLINE = "General Options"; +} // ----------------------------------------------------------------------------- // --SECTION-- constructors and destructors @@ -365,15 +351,6 @@ bool ApplicationServer::parse (int argc, return false; } - // check for help - set help = _options.needHelp("help"); - - if (! help.empty()) { - // output help, but do not yet exit (we'll exit a little later so we can also - // check the specified configuration for errors) - cout << argv[0] << " " << _title << endl << endl << _description.usage(help) << endl; - } - // check for version request if (_options.has("version")) { cout << _version << endl; @@ -400,6 +377,15 @@ bool ApplicationServer::parse (int argc, ok = readConfigurationFile(); + // check for help + set help = _options.needHelp("help"); + + if (! help.empty()) { + // output help, but do not yet exit (we'll exit a little later so we can also + // check the specified configuration for errors) + cout << argv[0] << " " << _title << "\n\n" << _description.usage(help) << endl; + } + if (! ok) { return false; } @@ -426,7 +412,7 @@ bool ApplicationServer::parse (int argc, setupLogging(false, false, false); // ............................................................................. - // parse phase 2 + // select random generate // ............................................................................. try { @@ -460,6 +446,9 @@ bool ApplicationServer::parse (int argc, LOG_FATAL_AND_EXIT("cannot select random generator, giving up"); } + // ............................................................................. + // parse phase 2 + // ............................................................................. for (vector::iterator i = _features.begin(); i != _features.end(); ++i) { ok = (*i)->parsePhase2(_options); @@ -764,7 +753,7 @@ void ApplicationServer::setupOptions (map& op // command line options // ............................................................................. - options[OPTIONS_CMDLINE] + options["General Options:help-default"] ("version,v", "print version string and exit") ("help,h", "produce a usage message and exit") ("configuration,c", &_configFile, "read configuration file") @@ -772,7 +761,7 @@ void ApplicationServer::setupOptions (map& op #if defined(TRI_HAVE_SETUID) || defined(TRI_HAVE_SETGID) - options[OPTIONS_CMDLINE + ":help-extended"] + options["General Options:help-admin"] #ifdef TRI_HAVE_GETPPID ("exit-on-parent-death", &_exitOnParentDeath, "exit if parent dies") #endif @@ -785,13 +774,13 @@ void ApplicationServer::setupOptions (map& op // logger options // ............................................................................. - options[OPTIONS_LOGGER] + options["Logging Options:help-default:help-log"] ("log.file", &_logFile, "log to file") ("log.requests-file", &_logRequestsFile, "log requests to file") ("log.level,l", &_logLevel, "log level") ; - options[OPTIONS_LOGGER + ":help-log"] + options["Logging Options:help-log"] ("log.application", &_logApplicationName, "application name for syslog") ("log.facility", &_logFacility, "facility name for syslog (OS dependent)") ("log.source-filter", &_logSourceFilter, "only debug and trace messages emitted by specific C source file") @@ -804,7 +793,7 @@ void ApplicationServer::setupOptions (map& op ("log.tty", &_logTty, "additional log file if started on tty") ; - options[OPTIONS_HIDDEN] + options["Hidden Options"] ("log", &_logLevel, "log level for severity 'human'") ("log.syslog", &DeprecatedParameter, "use syslog facility (deprecated)") ("log.hostname", &DeprecatedParameter, "host name for syslog") @@ -820,7 +809,7 @@ void ApplicationServer::setupOptions (map& op // application server options // ............................................................................. - options[OPTIONS_SERVER + ":help-extended"] + options["Server Options:help-admin"] ("random.generator", &_randomGenerator, "1 = mersenne, 2 = random, 3 = urandom, 4 = combined") #ifdef TRI_HAVE_SETUID ("server.uid", &_uid, "switch to user-id after reading config files") diff --git a/lib/ApplicationServer/ApplicationServer.h b/lib/ApplicationServer/ApplicationServer.h index 7ef1a840dd..40c8b1cbf8 100644 --- a/lib/ApplicationServer/ApplicationServer.h +++ b/lib/ApplicationServer/ApplicationServer.h @@ -59,42 +59,6 @@ namespace triagens { ApplicationServer (const ApplicationServer&); ApplicationServer& operator= (const ApplicationServer&); -// ----------------------------------------------------------------------------- -// --SECTION-- public constants -// ----------------------------------------------------------------------------- - - public: - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Command Line Options -//////////////////////////////////////////////////////////////////////////////// - - static std::string const OPTIONS_CMDLINE; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Hidden Options -//////////////////////////////////////////////////////////////////////////////// - - static std::string const OPTIONS_HIDDEN; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Logger Options -//////////////////////////////////////////////////////////////////////////////// - - static std::string const OPTIONS_LOGGER; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Server Options -//////////////////////////////////////////////////////////////////////////////// - - static std::string const OPTIONS_SERVER; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief SSL Options -//////////////////////////////////////////////////////////////////////////////// - - static std::string const OPTIONS_SSL; - // ----------------------------------------------------------------------------- // --SECTION-- constructors and destructors // ----------------------------------------------------------------------------- diff --git a/lib/Basics/ProgramOptionsDescription.cpp b/lib/Basics/ProgramOptionsDescription.cpp index de2ef8a005..65695539dc 100644 --- a/lib/Basics/ProgramOptionsDescription.cpp +++ b/lib/Basics/ProgramOptionsDescription.cpp @@ -56,6 +56,9 @@ ProgramOptionsDescription::ProgramOptionsDescription () _optionTypes(), _long2short(), _helpTexts(), + _defaultTexts(), + _currentTexts(), + _values(), _stringOptions(), _vectorStringOptions(), _int32Options(), @@ -79,32 +82,8 @@ ProgramOptionsDescription::ProgramOptionsDescription () /// @brief constructor //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription::ProgramOptionsDescription (string const& name) - : _name(""), - _helpOptions(), - _subDescriptions(), - _hiddenSubDescriptions(), - _optionNames(), - _optionTypes(), - _long2short(), - _helpTexts(), - _stringOptions(), - _vectorStringOptions(), - _int32Options(), - _vectorInt32Options(), - _int64Options(), - _vectorInt64Options(), - _uint32Options(), - _vectorUInt32Options(), - _uint64Options(), - _vectorUInt64Options(), - _doubleOptions(), - _vectorDoubleOptions(), - _boolOptions(), -#if __WORDSIZE == 32 - _timeOptions(), -#endif - _positionals(0) { +ProgramOptionsDescription::ProgramOptionsDescription (const string& name) + : ProgramOptionsDescription() { setName(name); } @@ -121,6 +100,9 @@ ProgramOptionsDescription::ProgramOptionsDescription (ProgramOptionsDescription _optionTypes(that._optionTypes), _long2short(that._long2short), _helpTexts(that._helpTexts), + _defaultTexts(that._defaultTexts), + _currentTexts(that._currentTexts), + _values(that._values), _stringOptions(that._stringOptions), _vectorStringOptions(that._vectorStringOptions), _int32Options(that._int32Options), @@ -144,7 +126,7 @@ ProgramOptionsDescription::ProgramOptionsDescription (ProgramOptionsDescription /// @brief assignment constructor //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator= (ProgramOptionsDescription const& that) { +ProgramOptionsDescription& ProgramOptionsDescription::operator= (const ProgramOptionsDescription& that) { if (this != &that) { _name = that._name; _helpOptions = that._helpOptions; @@ -154,6 +136,9 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator= (ProgramOptionsD _optionTypes = that._optionTypes; _long2short = that._long2short; _helpTexts = that._helpTexts; + _defaultTexts = that._defaultTexts; + _currentTexts = that._currentTexts; + _values = that._values; _stringOptions = that._stringOptions; _vectorStringOptions = that._vectorStringOptions; _int32Options = that._int32Options; @@ -180,7 +165,7 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator= (ProgramOptionsD // --SECTION-- public methods // ----------------------------------------------------------------------------- -void ProgramOptionsDescription::setName (string const& name) { +void ProgramOptionsDescription::setName (const string& name) { vector n = StringUtils::split(name, ':'); if (! n.empty()) { @@ -211,12 +196,13 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (ProgramOptions /// @brief adds a new flag //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, const string& text) { string name = check(full); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_FLAG; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -225,19 +211,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds a string argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, string* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, string* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_STRING; _stringOptions[name] = value; - - if (value->empty()) { - _helpTexts[name] = text; - } - else { - _helpTexts[name] = text + " (default: \"" + *value + "\")"; - } + _helpTexts[name] = text; + _defaultTexts[name] = (value->empty()) ? "" : ("\"" + *value + "\""); + _currentTexts[name] = [] (void* p) -> string { return ((string*)p)->empty() ? "" : "\"" + (* (string*) p) + "\""; }; + _values[name] = (void*) value; return *this; } @@ -246,13 +229,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds a string vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_STRING; _vectorStringOptions[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = value->empty() ? "" : StringUtils::join(*value, ", "); + _currentTexts[name] = [] (void* p) -> string { return ((vector*)p)->empty() ? "" : "\"" + StringUtils::join(* (vector*) p, " ,") + "\""; }; + _values[name] = (void*) value; return *this; } @@ -261,13 +247,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an int32_t argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, int32_t* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, int32_t* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_INT32; _int32Options[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::itoa(*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::itoa(*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::itoa(* (int32_t*) p); }; + _values[name] = (void*) value; return *this; } @@ -276,13 +265,14 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an int32_t vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_INT32; _vectorInt32Options[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -291,13 +281,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an int64_t argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, int64_t* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, int64_t* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_INT64; _int64Options[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::itoa(*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::itoa(*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::itoa(* (int64_t*) p); }; + _values[name] = (void*) value; return *this; } @@ -306,13 +299,14 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an int64_t vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_INT64; _vectorInt64Options[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -321,13 +315,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an uint32_t argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, uint32_t* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, uint32_t* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_UINT32; _uint32Options[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::itoa(*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::itoa(*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::itoa(* (uint32_t*) p); }; + _values[name] = (void*) value; return *this; } @@ -336,13 +333,14 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an uint32_t vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_UINT32; _vectorUInt32Options[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -351,13 +349,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an uint64_t argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, uint64_t* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, uint64_t* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_UINT64; _uint64Options[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::itoa(*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::itoa(*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::itoa(* (uint64_t*) p); }; + _values[name] = (void*) value; return *this; } @@ -366,13 +367,14 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds an uint64_t vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_UINT64; _vectorUInt64Options[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -381,13 +383,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds a double argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, double* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, double* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_DOUBLE; _doubleOptions[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::ftoa(*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::ftoa(*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::ftoa(* (double*) p); }; + _values[name] = (void*) value; return *this; } @@ -396,13 +401,14 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds a double vector argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, vector* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, vector* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_VECTOR_DOUBLE; _vectorDoubleOptions[name] = value; _helpTexts[name] = text; + _defaultTexts[name] = ""; return *this; } @@ -411,13 +417,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& /// @brief adds a boolean argument //////////////////////////////////////////////////////////////////////////////// -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, bool* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, bool* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_BOOL; _boolOptions[name] = value; - _helpTexts[name] = text + " (default: " + (*value ? "true" : "false") + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = (*value ? "true" : "false"); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : string(((* (bool*) p) ? "true" : "false")); }; + _values[name] = (void*) value; return *this; } @@ -428,13 +437,16 @@ ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& #if __WORDSIZE == 32 -ProgramOptionsDescription& ProgramOptionsDescription::operator() (string const& full, time_t* value, string const& text) { +ProgramOptionsDescription& ProgramOptionsDescription::operator() (const string& full, time_t* value, const string& text) { string name = check(full, value); _optionNames.push_back(name); _optionTypes[name] = OPTION_TYPE_TIME; _timeOptions[name] = value; - _helpTexts[name] = text + " (default: " + StringUtils::itoa((int64_t)*value) + ")"; + _helpTexts[name] = text; + _defaultTexts[name] = StringUtils::itoa((int64_t)*value); + _currentTexts[name] = [] (void* p) -> string { return p == nullptr ? "" : StringUtils::itoa((int64_t)(* (time_t*) p)); }; + _values[name] = (void*) value; return *this; } @@ -470,184 +482,54 @@ string ProgramOptionsDescription::usage () const { /// @brief returns the usage message //////////////////////////////////////////////////////////////////////////////// -string ProgramOptionsDescription::usage (set const& help, bool addHelpOptions) const { - string desc; +string ProgramOptionsDescription::usage (set help) const { + // footer with info about specific sections + string footer; + + // we want all help, therefore use all help sections bool helpAll = help.find("--HELP-ALL--") != help.end(); - bool helpStandard = help.find("--HELP--") != help.end(); + help.erase("--HELP-ALL--"); + help.erase("--HELP--"); - // extract help-able sub-descriptions - vector subDescriptions; - - for (vector::const_iterator i = _subDescriptions.begin(); i != _subDescriptions.end(); ++i) { - ProgramOptionsDescription pod = *i; - set ho = pod._helpOptions; - - if (ho.empty() || helpAll) { - subDescriptions.push_back(pod); - } - else { - set is; - set_intersection(ho.begin(), ho.end(), help.begin(), help.end(), std::inserter(is, is.end())); - - if (! is.empty()) { - subDescriptions.push_back(pod); - } - } + if (help.empty()) { + help.insert("help-default"); } - // write help only if help options match - if (! _helpOptions.empty() || helpStandard || helpAll) { - // produce a headline - if (! _name.empty() && ! (subDescriptions.empty() && _optionNames.empty())) { - if (_helpOptions.empty()) { - desc = _name + ":\n"; - } - else { - desc = "Extended " + _name + ":\n"; - } - } + set ho = helpOptions(); - // construct the parameters - size_t tWidth = TRI_ColumnsWidth(); + // remove help default + set hd = ho; + hd.erase("help-default"); - if (tWidth < 40) { - tWidth = 40; - } - - - // collect the maximal width of the option names - size_t oWidth = 0; - - map names; - - for (vector::const_iterator i = _optionNames.begin(); i != _optionNames.end(); ++i) { - string const& option = *i; - option_type_e type = _optionTypes.find(option)->second; - - string name; - - switch (type) { - case OPTION_TYPE_FLAG: - name = option; - break; - - case OPTION_TYPE_STRING: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_STRING: - name = option + " "; - break; - - case OPTION_TYPE_INT32: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_INT64: - name = option + " "; - break; - - case OPTION_TYPE_INT64: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_INT32: - name = option + " "; - break; - - case OPTION_TYPE_UINT32: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_UINT32: - name = option + " "; - break; - - case OPTION_TYPE_UINT64: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_UINT64: - name = option + " "; - break; - - case OPTION_TYPE_DOUBLE: - name = option + " "; - break; - - case OPTION_TYPE_VECTOR_DOUBLE: - name = option + " "; - break; - - case OPTION_TYPE_TIME: - name = option + "