Example #1
0
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);
      }
    }
  }
Example #2
0
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);
}
Example #3
0
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;
  }