From 4ba0cf1160732ea09fb7a9a88dfc64b64f54dc63 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 4 Apr 2020 06:34:11 -0700 Subject: [PATCH] util: c++-ify command line arguments in the m5 utility. Change-Id: Icfdd95c61ac9937823027563d086e5a690870fb4 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27550 Tested-by: kokoro Reviewed-by: Gabe Black Reviewed-by: Daniel Carvalho Maintainer: Gabe Black --- util/m5/src/addr_call_type.cc | 18 ++++++------ util/m5/src/args.cc | 28 ++++++++----------- util/m5/src/args.hh | 42 ++++++++++++++++++---------- util/m5/src/commands.cc | 52 +++++++++++++++++------------------ util/m5/src/commands.hh | 2 +- util/m5/src/inst_call_type.cc | 4 +-- util/m5/src/m5.cc | 16 +++++------ util/m5/src/semi_call_type.cc | 4 +-- util/m5/src/usage.cc | 5 ++-- util/m5/src/usage.hh | 2 +- 10 files changed, 90 insertions(+), 83 deletions(-) diff --git a/util/m5/src/addr_call_type.cc b/util/m5/src/addr_call_type.cc index 3a10ffab5..963bb2e30 100644 --- a/util/m5/src/addr_call_type.cc +++ b/util/m5/src/addr_call_type.cc @@ -83,25 +83,23 @@ class AddrCallType : public CallType bool checkArgs(Args &args) override { - static const char *prefix = "--addr"; - const size_t prefix_len = strlen(prefix); + static const std::string prefix = "--addr"; uint64_t addr_override; // If the first argument doesn't start with --addr... - if (!args.argc || memcmp(args.argv[0], prefix, prefix_len) != 0) + if (!args.size() || args[0].substr(0, prefix.size()) != prefix) return false; - const char *argv0 = pop_arg(&args); + const std::string &arg = args.pop().substr(prefix.size()); // If there's more text in this argument... - if (strlen(argv0) != prefix_len) { + if (arg.size()) { // If it doesn't start with '=', it's malformed. - if (argv0[prefix_len] != '=') + if (arg[0] != '=') usage(); // Attempt to extract an address after the '='. - const char *temp_argv[] = { &argv0[prefix_len + 1] }; - Args temp_args = { 1, temp_argv }; - if (!parse_int_args(&temp_args, &addr_override, 1)) + Args temp_args({ arg.substr(1) }); + if (!parse_int_args(temp_args, &addr_override, 1)) usage(); // If we found an address, use it to override m5op_addr. m5op_addr = addr_override; @@ -109,7 +107,7 @@ class AddrCallType : public CallType } // If an address override wasn't part of the first argument, check if // it's the second argument. If not, then there's no override. - if (args.argc && parse_int_args(&args, &addr_override, 1)) { + if (args.size() && parse_int_args(args, &addr_override, 1)) { m5op_addr = addr_override; return true; } diff --git a/util/m5/src/args.cc b/util/m5/src/args.cc index 96689b802..b6bd1c8f7 100644 --- a/util/m5/src/args.cc +++ b/util/m5/src/args.cc @@ -44,40 +44,36 @@ #include "args.hh" -int -parse_int_args(Args *args, uint64_t ints[], int len) +bool +parse_int_args(Args &args, uint64_t ints[], int len) { - if (args->argc > len) - return 0; - // On 32 bit platforms we need to use strtoull to do the conversion #ifdef __LP64__ #define strto64 strtoul #else #define strto64 strtoull #endif - for (int i = 0; i < len; ++i) { - const char *arg = pop_arg(args); - ints[i] = arg ? strto64(arg, NULL, 0) : 0; - } + for (int i = 0; i < len; ++i) + ints[i] = strto64(args.pop("0").c_str(), NULL, 0); #undef strto64 - return 1; + return true; } -int -pack_arg_into_regs(Args *args, uint64_t regs[], int num_regs) +bool +pack_arg_into_regs(Args &args, uint64_t regs[], int num_regs) { const size_t RegSize = sizeof(regs[0]); const size_t MaxLen = num_regs * RegSize; - const char *arg = pop_arg(args); + const std::string &sarg = args.pop(); + const char *arg = sarg.c_str(); memset(regs, 0, MaxLen); - size_t len = arg ? strlen(arg) : 0; + size_t len = sarg.size(); if (len > MaxLen) - return 0; + return false; while (len) { for (int offset = 0; offset < RegSize && len; offset++, len--) { @@ -86,5 +82,5 @@ pack_arg_into_regs(Args *args, uint64_t regs[], int num_regs) } regs++; } - return 1; + return true; } diff --git a/util/m5/src/args.hh b/util/m5/src/args.hh index 3fc22a295..1afd2f28a 100644 --- a/util/m5/src/args.hh +++ b/util/m5/src/args.hh @@ -43,23 +43,37 @@ #include #include +#include +#include +#include -struct Args +class Args { - int argc; - const char **argv; -}; + private: + std::vector args; + size_t offset = 0; -static inline const char * -pop_arg(Args *args) -{ - if (!args->argc) - return NULL; - args->argc--; - return (args->argv++)[0]; -} + public: + Args(int argc, const char **argv) + { + for (int i = 0; i < argc; i++) + args.push_back(argv[i]); + } + Args(std::initializer_list strings) : args(strings) {} + + const std::string & + pop(const std::string &def = "") { + if (!size()) + return def; + return args[offset++]; + } + + size_t size() { return args.size() - offset; } + + const std::string &operator [] (size_t idx) { return args[offset + idx]; } +}; -int parse_int_args(Args *args, uint64_t ints[], int len); -int pack_arg_into_regs(Args *args, uint64_t regs[], int num_regs); +bool parse_int_args(Args &args, uint64_t ints[], int len); +bool pack_arg_into_regs(Args &args, uint64_t regs[], int num_regs); #endif // __ARGS_HH__ diff --git a/util/m5/src/commands.cc b/util/m5/src/commands.cc index 2690f0fe2..9c103fbbd 100644 --- a/util/m5/src/commands.cc +++ b/util/m5/src/commands.cc @@ -102,9 +102,9 @@ write_file(const DispatchTable &dt, const char *filename, } static void -do_exit(const DispatchTable &dt, Args *args) +do_exit(const DispatchTable &dt, Args &args) { - if (args->argc > 1) + if (args.size() > 1) usage(); uint64_t ints[1]; @@ -114,19 +114,19 @@ do_exit(const DispatchTable &dt, Args *args) } static void -do_fail(const DispatchTable &dt, Args *args) +do_fail(const DispatchTable &dt, Args &args) { - if (args->argc < 1 || args->argc > 2) + if (args.size() < 1 || args.size() > 2) usage(); uint64_t ints[2] = { 0, 0 }; - if (!parse_int_args(args, ints, args->argc)) + if (!parse_int_args(args, ints, args.size())) usage(); (*dt.m5_fail)(ints[1], ints[0]); } static void -do_reset_stats(const DispatchTable &dt, Args *args) +do_reset_stats(const DispatchTable &dt, Args &args) { uint64_t ints[2]; if (!parse_int_args(args, ints, 2)) @@ -135,7 +135,7 @@ do_reset_stats(const DispatchTable &dt, Args *args) } static void -do_dump_stats(const DispatchTable &dt, Args *args) +do_dump_stats(const DispatchTable &dt, Args &args) { uint64_t ints[2]; if (!parse_int_args(args, ints, 2)) @@ -144,7 +144,7 @@ do_dump_stats(const DispatchTable &dt, Args *args) } static void -do_dump_reset_stats(const DispatchTable &dt, Args *args) +do_dump_reset_stats(const DispatchTable &dt, Args &args) { uint64_t ints[2]; if (!parse_int_args(args, ints, 2)) @@ -153,30 +153,28 @@ do_dump_reset_stats(const DispatchTable &dt, Args *args) } static void -do_read_file(const DispatchTable &dt, Args *args) +do_read_file(const DispatchTable &dt, Args &args) { - if (args->argc > 0) + if (args.size() > 0) usage(); read_file(dt, STDOUT_FILENO); } static void -do_write_file(const DispatchTable &dt, Args *args) +do_write_file(const DispatchTable &dt, Args &args) { - if (args->argc != 1 && args->argc != 2) + if (args.size() != 1 && args.size() != 2) usage(); - const char *filename = pop_arg(args); - const char *host_filename = pop_arg(args); - if (!host_filename) - host_filename = filename; + const std::string &filename = args.pop(); + const std::string &host_filename = args.pop(filename); - write_file(dt, filename, host_filename); + write_file(dt, filename.c_str(), host_filename.c_str()); } static void -do_checkpoint(const DispatchTable &dt, Args *args) +do_checkpoint(const DispatchTable &dt, Args &args) { uint64_t ints[2]; if (!parse_int_args(args, ints, 2)) @@ -185,30 +183,30 @@ do_checkpoint(const DispatchTable &dt, Args *args) } static void -do_addsymbol(const DispatchTable &dt, Args *args) +do_addsymbol(const DispatchTable &dt, Args &args) { - if (args->argc != 2) + if (args.size() != 2) usage(); - uint64_t addr = strtoul(pop_arg(args), NULL, 0); - const char *symbol = pop_arg(args); - (*dt.m5_add_symbol)(addr, symbol); + uint64_t addr = strtoul(args.pop().c_str(), NULL, 0); + const std::string &symbol = args.pop(); + (*dt.m5_add_symbol)(addr, symbol.c_str()); } static void -do_loadsymbol(const DispatchTable &dt, Args *args) +do_loadsymbol(const DispatchTable &dt, Args &args) { - if (args->argc > 0) + if (args.size() > 0) usage(); (*dt.m5_load_symbol)(); } static void -do_initparam(const DispatchTable &dt, Args *args) +do_initparam(const DispatchTable &dt, Args &args) { - if (args->argc > 1) + if (args.size() > 1) usage(); uint64_t key_str[2]; diff --git a/util/m5/src/commands.hh b/util/m5/src/commands.hh index 83a3335c7..013e20d4e 100644 --- a/util/m5/src/commands.hh +++ b/util/m5/src/commands.hh @@ -38,7 +38,7 @@ struct CommandInfo const char *name; // A function which processes command line arguments and passes them to // the underlying function through the dispatch table. - void (*func)(const DispatchTable &dt, Args *args); + void (*func)(const DispatchTable &dt, Args &args); // Help text for this command. const char *usage; }; diff --git a/util/m5/src/inst_call_type.cc b/util/m5/src/inst_call_type.cc index 49f87abcc..e19f6018b 100644 --- a/util/m5/src/inst_call_type.cc +++ b/util/m5/src/inst_call_type.cc @@ -47,8 +47,8 @@ class InstCallType : public CallType bool checkArgs(Args &args) override { - if (args.argc && strcmp(args.argv[0], "--inst") == 0) { - pop_arg(&args); + if (args.size() && args[0] == "--inst") { + args.pop(); return true; } return false; diff --git a/util/m5/src/m5.cc b/util/m5/src/m5.cc index 283dada3f..59930e30c 100644 --- a/util/m5/src/m5.cc +++ b/util/m5/src/m5.cc @@ -49,25 +49,25 @@ int main(int argc, const char *argv[]) { - Args args = { argc, argv }; + Args args(argc, argv); - if (!args.argc) + if (!args.size()) usage(); - progname = pop_arg(&args); + progname = args.pop("{progname}"); const DispatchTable &dt = CallType::detect(args).getDispatch(); - const char *command = pop_arg(&args); - - if (!command) + if (!args.size()) usage(); + const std::string &command = args.pop(); + for (int i = 0; i < num_commands; ++i) { - if (strcmp(command, command_table[i].name) != 0) + if (command != command_table[i].name) continue; - command_table[i].func(dt, &args); + command_table[i].func(dt, args); exit(0); } diff --git a/util/m5/src/semi_call_type.cc b/util/m5/src/semi_call_type.cc index 5c9787ff5..25b830c2d 100644 --- a/util/m5/src/semi_call_type.cc +++ b/util/m5/src/semi_call_type.cc @@ -54,8 +54,8 @@ class SemiCallType : public CallType bool checkArgs(Args &args) override { - if (args.argc && strcmp(args.argv[0], "--semi") == 0) { - pop_arg(&args); + if (args.size() && args[0] == "--semi") { + args.pop(); return true; } return false; diff --git a/util/m5/src/usage.cc b/util/m5/src/usage.cc index a472b1e7c..a0546cd52 100644 --- a/util/m5/src/usage.cc +++ b/util/m5/src/usage.cc @@ -46,12 +46,13 @@ #include "commands.hh" #include "usage.hh" -const char *progname = "{progname}"; +std::string progname; void usage() { - fprintf(stderr, "Usage: %s [call type] [arguments]\n", progname); + fprintf(stderr, "Usage: %s [call type] [arguments]\n", + progname.c_str()); fprintf(stderr, "\n"); fprintf(stderr, "Call types:\n"); fprintf(stderr, CallType::usageSummary().c_str()); diff --git a/util/m5/src/usage.hh b/util/m5/src/usage.hh index b1023eab2..fc908bb62 100644 --- a/util/m5/src/usage.hh +++ b/util/m5/src/usage.hh @@ -41,7 +41,7 @@ #ifndef __USAGE_HH__ #define __USAGE_HH__ -extern const char *progname; +extern std::string progname; void usage(); -- 2.30.2