inline Try<Warnings> FlagsBase::load( const Option<std::string>& prefix, int argc, const char* const *argv, bool unknowns, bool duplicates) { Multimap<std::string, Option<std::string>> values; // Grab the program name from argv[0]. programName_ = argc > 0 ? Path(argv[0]).basename() : ""; // Read flags from the command line. for (int i = 1; i < argc; i++) { const std::string arg(strings::trim(argv[i])); // Stop parsing flags after '--' is encountered. if (arg == "--") { break; } // Skip anything that doesn't look like a flag. if (arg.find("--") != 0) { continue; } std::string name; Option<std::string> value = None(); size_t eq = arg.find_first_of("="); if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name name = arg.substr(2); } else if (eq == std::string::npos) { // --name name = arg.substr(2); } else { // --name=value name = arg.substr(2, eq - 2); value = arg.substr(eq + 1); } name = strings::lower(name); values.put(name, value); } if (prefix.isSome()) { // Merge in flags from the environment. Command-line // flags take precedence over environment flags. foreachpair (const std::string& name, const Option<std::string>& value, extract(prefix.get())) { if (!values.contains(name)) { values.put(name, value); } } }
inline Try<Warnings> FlagsBase::load( const Option<std::string>& prefix, int argc, const char* const *argv, bool unknowns, bool duplicates) { Multimap<std::string, Option<std::string>> values; // Grab the program name from argv[0]. programName_ = argc > 0 ? Path(argv[0]).basename() : ""; // Read flags from the command line. for (int i = 1; i < argc; i++) { const std::string arg(strings::trim(argv[i])); // Stop parsing flags after '--' is encountered. if (arg == "--") { break; } // Skip anything that doesn't look like a flag. if (arg.find("--") != 0) { continue; } std::string name; Option<std::string> value = None(); size_t eq = arg.find_first_of("="); if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name name = arg.substr(2); } else if (eq == std::string::npos) { // --name name = arg.substr(2); } else { // --name=value name = arg.substr(2, eq - 2); value = arg.substr(eq + 1); } name = strings::lower(name); values.put(name, value); } return load(values, unknowns, duplicates, prefix); }
inline Try<Warnings> FlagsBase::load( const Option<std::string>& prefix, int* argc, char*** argv, bool unknowns, bool duplicates) { Multimap<std::string, Option<std::string>> values; // Grab the program name from argv, without removing it. programName_ = *argc > 0 ? Path(*(argv[0])).basename() : ""; // Keep the arguments that are not being processed as flags. std::vector<char*> args; // Read flags from the command line. for (int i = 1; i < *argc; i++) { const std::string arg(strings::trim((*argv)[i])); // Stop parsing flags after '--' is encountered. if (arg == "--") { // Save the rest of the arguments. for (int j = i + 1; j < *argc; j++) { args.push_back((*argv)[j]); } break; } // Skip anything that doesn't look like a flag. if (arg.find("--") != 0) { args.push_back((*argv)[i]); continue; } std::string name; Option<std::string> value = None(); size_t eq = arg.find_first_of("="); if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name name = arg.substr(2); } else if (eq == std::string::npos) { // --name name = arg.substr(2); } else { // --name=value name = arg.substr(2, eq - 2); value = arg.substr(eq + 1); } name = strings::lower(name); values.put(name, value); } Try<Warnings> result = load(values, unknowns, duplicates, prefix); // Update 'argc' and 'argv' if we successfully loaded the flags. if (!result.isError()) { CHECK_LE(args.size(), (size_t) *argc); int i = 1; // Start at '1' to skip argv[0]. foreach (char* arg, args) { (*argv)[i++] = arg; } *argc = i; // Now null terminate the array. Note that we'll "leak" the // arguments that were processed here but it's not like they would // have gotten deleted in normal operations anyway. (*argv)[i++] = nullptr; }