rntviewer/src/argparse.cpp
2024-07-25 17:58:32 +02:00

127 lines
2.9 KiB
C++

internal
void print_help(const char *argv0)
{
fprintf(stderr,
"rntviewer v" V_MAJOR "." V_MINOR " by silverweed"
"\n"
"\nUsage: %s [-t] [-s START] [-l LEN] [-w WIDTH] <ntuple_name> <ntuple_file.root>"
"\n\t-t: no graphics, output to terminal"
"\n\t-s: set first displayed byte to START"
"\n\t-l: display LEN bytes (only in terminal mode)"
"\n\t-w: display WIDTH bytes per column"
"\n"
, argv0);
}
struct Cmdline_Args {
b8 print_to_terminal;
b8 show_help_and_exit;
u64 start_addr;
u64 nbytes_displayed;
u16 n_cols;
String8 ntpl_name;
String8 file_name;
};
struct Conv_Res {
u64 num;
b8 error;
};
internal
Conv_Res str_to_u64(String8 s)
{
Conv_Res res {};
if (s.size > 2 && s[0] == '0' && s[1] == 'x') {
// hexadecimal
for (u64 i = 2; i < s.size; ++i) {
u8 c = s.str[i];
if (c >= '0' && c <= '9') {
res.num *= 16;
res.num += c - '0';
} else if (c >= 'A' && c <= 'F') {
res.num *= 16;
res.num += 10 + c - 'A';
} else if (c >= 'a' && c <= 'f') {
res.num *= 16;
res.num += 10 + c - 'a';
} else {
res.error = true;
break;
}
}
} else {
// decimal
for (u64 i = 0; i < s.size; ++i) {
u8 c = s.str[i];
if (c >= '0' && c <= '9') {
res.num *= 10;
res.num += c - '0';
} else {
res.error = true;
break;
}
}
}
return res;
}
internal
void parse_int_arg(i32 &cur_arg_idx, i32 argc, char **argv, u64 &out)
{
const char *arg = argv[cur_arg_idx];
if (cur_arg_idx < argc - 1) {
String8 nxt_arg = str8_from_c(argv[++cur_arg_idx]);
Conv_Res res = str_to_u64(nxt_arg);
if (res.error)
fprintf(stderr, "Invalid integer after %s flag.\n", arg);
else
out = res.num;
} else {
fprintf(stderr, "Argument required after %s flag.\n", arg);
}
}
internal
Cmdline_Args parse_args(i32 argc, char **argv)
{
Cmdline_Args args {};
if (argc < 3) {
args.show_help_and_exit = true;
return args;
}
// TODO: refactor this probably
for (i32 i = 1; i < argc; ++i) {
String8 arg = str8_from_c(argv[i]);
if (arg.str[0] == '-') {
if (arg.size == 2) {
if (arg.str[1] == 't')
args.print_to_terminal = true;
else if (arg.str[1] == 's')
parse_int_arg(i, argc, argv, args.start_addr);
else if (arg.str[1] == 'l')
parse_int_arg(i, argc, argv, args.nbytes_displayed);
else if (arg.str[1] == 'w') {
u64 n_cols = 0;
parse_int_arg(i, argc, argv, n_cols);
args.n_cols = (u16)n_cols;
}
else
args.show_help_and_exit = true;
} else {
args.show_help_and_exit = true;
}
} else if (args.ntpl_name.size) {
if (args.file_name.size)
args.show_help_and_exit = true;
else
args.file_name = arg;
} else {
args.ntpl_name = arg;
}
}
return args;
}