getopt method

int getopt(
  1. int argc,
  2. List<String> argv,
  3. String optstring
)

Parses command-line arguments.

Implementation

int getopt(int argc, List<String> argv, String optstring) {
  _optarg = null;

  if (_optind >= argc || _optind < 0) {
    return -1;
  }

  String arg = argv[_optind];

  if (arg.isEmpty || arg[0] != '-' || arg == '-') {
    return -1;
  }

  if (arg == '--') {
    _optind++;
    return -1;
  }

  if (_optpos >= arg.length) {
    _optpos = 1;
    return -1; // Should not happen if correctly formed, but just in case
  }

  String optchar = arg[_optpos];
  int optcharCode = optchar.codeUnitAt(0);
  int idx = optstring.indexOf(optchar);

  if (idx == -1) {
    _optopt = optcharCode;
    _printError(argv[0], "invalid option -- '$optchar'");
    if (_optpos + 1 < arg.length) {
      _optpos++;
    } else {
      _optind++;
      _optpos = 1;
    }
    return '?'.codeUnitAt(0);
  }

  bool hasArg = idx + 1 < optstring.length && optstring[idx + 1] == ':';
  bool optionalArg = hasArg && idx + 2 < optstring.length && optstring[idx + 2] == ':';

  if (hasArg) {
    if (_optpos + 1 < arg.length) {
      // Argument is attached, like -fFile
      _optarg = arg.substring(_optpos + 1);
      _optind++;
      _optpos = 1;
    } else if (_optind + 1 < argc) {
      // Argument is the next argv element
      _optarg = argv[_optind + 1];
      _optind += 2;
      _optpos = 1;
    } else {
      // Missing required argument
      if (optionalArg) {
        _optarg = null;
        _optind++;
        _optpos = 1;
      } else {
        _optopt = optcharCode;
        if (optstring.startsWith(':')) {
          return ':'.codeUnitAt(0);
        } else {
          _printError(argv[0], "option requires an argument -- '$optchar'");
          return '?'.codeUnitAt(0);
        }
      }
    }
  } else {
    if (_optpos + 1 < arg.length) {
      _optpos++;
    } else {
      _optind++;
      _optpos = 1;
    }
  }

  return optcharCode;
}