172 lines
5.8 KiB
Plaintext
172 lines
5.8 KiB
Plaintext
# argparse.nas
|
|
# 2023/12/7 by ValKmjolnir
|
|
|
|
use std.padding;
|
|
|
|
var new = func(description) {
|
|
var _arg = globals.arg;
|
|
var parser = {
|
|
description: description,
|
|
subparser: [],
|
|
command_list: [],
|
|
add_command: func(long, short, help, need_arg = false, need_nargs = false) {
|
|
return _add_command(parser, long, short, help, need_arg, need_nargs);
|
|
},
|
|
add_subparser: func(name, help) {
|
|
return _add_subparser(parser, name, help);
|
|
},
|
|
parse_args: func() {
|
|
var result_hash = {};
|
|
_parse(parser, _arg, result_hash);
|
|
return result_hash;
|
|
}
|
|
};
|
|
parser.add_command("--help", "-h", "Get help info and exit");
|
|
return parser;
|
|
}
|
|
|
|
var _new_sub_parser = func(description) {
|
|
var parser = {
|
|
description: description,
|
|
subparser: [],
|
|
command_list: [],
|
|
add_command: func(long, short, help, need_arg = false, need_nargs = false) {
|
|
return _add_command(parser, long, short, help, need_arg, need_nargs);
|
|
},
|
|
add_subparser: func(name, help) {
|
|
return _add_subparser(parser, name, help);
|
|
}
|
|
};
|
|
parser.add_command("--help", "-h", "Get help info and exit");
|
|
return parser;
|
|
}
|
|
|
|
var _help = func(parser) {
|
|
println(parser.description, "\n");
|
|
if (size(parser.subparser)>0) {
|
|
println("Subcommand:");
|
|
var max_pad_length = 0;
|
|
var info_pairs = [];
|
|
foreach(var cmd; parser.subparser) {
|
|
var info = " "~cmd.name;
|
|
append(info_pairs, {info: info, help: cmd.parser.description});
|
|
info_length = size(info);
|
|
max_pad_length = max_pad_length>info_length? max_pad_length:info_length;
|
|
}
|
|
foreach(var pair; info_pairs) {
|
|
println(padding.rightpad(pair.info, max_pad_length), " ", pair.help);
|
|
}
|
|
println();
|
|
}
|
|
if (size(parser.command_list)>0) {
|
|
println("Options:");
|
|
var max_pad_length = 0;
|
|
var info_pairs = [];
|
|
foreach(var cmd; parser.command_list) {
|
|
if (cmd.need_nargs) {
|
|
var info = " "~cmd.full_name~" [args...] "~cmd.short_name~" [args...]";
|
|
append(info_pairs, {info: info, help: cmd.help});
|
|
} elsif (cmd.need_arg) {
|
|
var info = " "~cmd.full_name~" arg "~cmd.short_name~" arg";
|
|
append(info_pairs, {info: info, help: cmd.help});
|
|
} else {
|
|
var info = " "~cmd.full_name~" "~cmd.short_name;
|
|
append(info_pairs, {info: info, help: cmd.help});
|
|
}
|
|
var info_length = size(info);
|
|
max_pad_length = max_pad_length>info_length? max_pad_length:info_length;
|
|
}
|
|
foreach(var pair; info_pairs) {
|
|
println(padding.rightpad(pair.info, max_pad_length), " ", pair.help);
|
|
}
|
|
}
|
|
}
|
|
|
|
var _in_list = func(arginfo, command_list) {
|
|
foreach(var cmd; command_list) {
|
|
if (arginfo==cmd.full_name or arginfo==cmd.short_name) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
var _parse = func(parser, args, result_hash) {
|
|
if (size(args)==0) {
|
|
println("Require more command, use \"--help\" to get help.\n");
|
|
_help(parser);
|
|
exit(0);
|
|
}
|
|
foreach(var subparser; parser.subparser) {
|
|
if (subparser.name==args[0]) {
|
|
result_hash[subparser.name] = true;
|
|
_parse(subparser.parser, size(args)>1? args[1:]:[], result_hash);
|
|
return;
|
|
}
|
|
}
|
|
for(var i = 0; i<size(args); i += 1) {
|
|
var this_arg = args[i];
|
|
var find_command_flag = false;
|
|
foreach(var cmd; parser.command_list) {
|
|
if (this_arg=="--help" or this_arg=="-h") {
|
|
_help(parser);
|
|
exit(0);
|
|
}
|
|
if (this_arg==cmd.full_name or this_arg==cmd.short_name) {
|
|
find_command_flag = true;
|
|
if (cmd.need_nargs) {
|
|
i += 1;
|
|
var args_collect = [];
|
|
while (i<size(args) and !_in_list(args[i], parser.command_list)) {
|
|
append(args_collect, args[i]);
|
|
i += 1;
|
|
}
|
|
i -= 1;
|
|
if (!size(args_collect)) {
|
|
println("Require argument(s) after command `", this_arg, "`.\n");
|
|
_help(parser);
|
|
exit(0);
|
|
}
|
|
result_hash[cmd.full_name] = args_collect;
|
|
} elsif (cmd.need_arg) {
|
|
i += 1;
|
|
if (i<size(args) and !_in_list(args[i], parser.command_list)) {
|
|
result_hash[cmd.full_name] = args[i];
|
|
} else {
|
|
println("Require argument after command `", this_arg, "`.\n");
|
|
_help(parser);
|
|
exit(0);
|
|
}
|
|
} else {
|
|
result_hash[cmd.full_name] = true;
|
|
}
|
|
}
|
|
}
|
|
if (!find_command_flag) {
|
|
println("Invalid command `", this_arg, "`.\n");
|
|
_help(parser);
|
|
exit(0);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
var _add_command = func(parser, long, short, help, need_arg , need_nargs) {
|
|
var new_command = {
|
|
full_name: long,
|
|
short_name: short,
|
|
help: help,
|
|
need_arg: need_arg,
|
|
need_nargs: need_nargs
|
|
};
|
|
append(parser.command_list, new_command);
|
|
}
|
|
|
|
var _add_subparser = func(parser, name, help) {
|
|
var new_subparser = {
|
|
name: name,
|
|
parser: _new_sub_parser(help)
|
|
};
|
|
append(parser.subparser, new_subparser);
|
|
return new_subparser.parser;
|
|
} |