getopt_long method
Parses long options in addition to short options.
Implementation
int getopt_long(int argc, List<String> argv, String optstring, List<Option> longopts, [List<int>? longindex]) {
_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;
}
// Handle long options
if (arg.startsWith('--')) {
String opt = arg.substring(2);
String? eqArg;
int eqIdx = opt.indexOf('=');
if (eqIdx != -1) {
eqArg = opt.substring(eqIdx + 1);
opt = opt.substring(0, eqIdx);
}
int matchIdx = -1;
bool ambiguous = false;
for (int i = 0; i < longopts.length; i++) {
if (longopts[i].name == opt) {
matchIdx = i;
ambiguous = false;
break;
} else if (longopts[i].name.startsWith(opt)) {
if (matchIdx == -1) {
matchIdx = i;
} else {
ambiguous = true;
}
}
}
if (ambiguous) {
_printError(argv[0], "option '--$opt' is ambiguous");
_optind++;
return '?'.codeUnitAt(0);
}
if (matchIdx != -1) {
if (longindex != null && longindex.isNotEmpty) {
longindex[0] = matchIdx;
}
var option = longopts[matchIdx];
if (option.has_arg == required_argument) {
if (eqArg != null) {
_optarg = eqArg;
_optind++;
} else if (_optind + 1 < argc) {
_optarg = argv[_optind + 1];
_optind += 2;
} else {
_printError(argv[0], "option '--${option.name}' requires an argument");
_optind++;
return optstring.startsWith(':') ? ':'.codeUnitAt(0) : '?'.codeUnitAt(0);
}
} else if (option.has_arg == optional_argument) {
if (eqArg != null) {
_optarg = eqArg;
} else {
_optarg = null;
}
_optind++;
} else {
// no_argument
if (eqArg != null) {
_printError(argv[0], "option '--${option.name}' doesn't allow an argument");
_optind++;
return '?'.codeUnitAt(0);
}
_optind++;
}
if (option.flag != null && option.flag!.isNotEmpty) {
option.flag![0] = option.val;
return 0;
}
return option.val;
}
// If we are here, long option not found
_printError(argv[0], "unrecognized option '--$opt'");
_optind++;
return '?'.codeUnitAt(0);
}
// Fall back to short options
return getopt(argc, argv, optstring);
}