util: c++-ify command line arguments in the m5 utility.
authorGabe Black <gabeblack@google.com>
Sat, 4 Apr 2020 13:34:11 +0000 (06:34 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 26 Jun 2020 02:36:48 +0000 (02:36 +0000)
Change-Id: Icfdd95c61ac9937823027563d086e5a690870fb4
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27550
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>

util/m5/src/addr_call_type.cc
util/m5/src/args.cc
util/m5/src/args.hh
util/m5/src/commands.cc
util/m5/src/commands.hh
util/m5/src/inst_call_type.cc
util/m5/src/m5.cc
util/m5/src/semi_call_type.cc
util/m5/src/usage.cc
util/m5/src/usage.hh

index 3a10ffab5830657c904acd4d0e2f47142fc7d8c7..963bb2e308271c228fbbf7d9c9b4edbebe6b3464 100644 (file)
@@ -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;
         }
index 96689b8023f93a16c6a5da6d9ca56b513b0a7624..b6bd1c8f75efb6824fe4c0a09e43913db5673f67 100644 (file)
 
 #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;
 }
index 3fc22a295d8b57598d78dc10be26e0e335b582ff..1afd2f28a5d65ef93989eee409aa2ee874fc3e25 100644 (file)
 
 #include <cstddef>
 #include <cstdint>
+#include <initializer_list>
+#include <string>
+#include <vector>
 
-struct Args
+class Args
 {
-    int argc;
-    const char **argv;
-};
+  private:
+    std::vector<std::string> 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<std::string> 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__
index 2690f0fe251905166dc663d0499479944a1b4e55..9c103fbbd5cd4a94c03d97b6a559f2e623d893a8 100644 (file)
@@ -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];
index 83a3335c7ed502bd4e1cefb07ac594f573726ac8..013e20d4e8c350c712d4f395645b449fe5b35175 100644 (file)
@@ -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;
 };
index 49f87abcc20e65f8e64ad32a9d3a4f3842565d3a..e19f6018b9b4736c6e7cb489f8a7670f09ed94eb 100644 (file)
@@ -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;
index 283dada3f9579f9572e3a11e7dcafd9b93d50e6c..59930e30c57aa279d8fc725170578a0d8c3443df 100644 (file)
 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);
     }
 
index 5c9787ff593a2ef4119994cbd3f38f1f485314ca..25b830c2d0437692dd59d1cd96c89c22f6edad2b 100644 (file)
@@ -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;
index a472b1e7cc109abb03eca430978aa842087d0fbf..a0546cd52db2882175e2ea1fb69e4400cf66fed2 100644 (file)
 #include "commands.hh"
 #include "usage.hh"
 
-const char *progname = "{progname}";
+std::string progname;
 
 void
 usage()
 {
-    fprintf(stderr, "Usage: %s [call type] <command> [arguments]\n", progname);
+    fprintf(stderr, "Usage: %s [call type] <command> [arguments]\n",
+            progname.c_str());
     fprintf(stderr, "\n");
     fprintf(stderr, "Call types:\n");
     fprintf(stderr, CallType::usageSummary().c_str());
index b1023eab2687c0574246d32e7883f57af983ec7a..fc908bb6254a7ec405d8fd4eac7c6a2c60dd6270 100644 (file)
@@ -41,7 +41,7 @@
 #ifndef __USAGE_HH__
 #define __USAGE_HH__
 
-extern const char *progname;
+extern std::string progname;
 
 void usage();