getopt method
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;
}