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 <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>
This commit is contained in:
Gabe Black
2020-04-04 06:34:11 -07:00
parent 276a449171
commit 4ba0cf1160
10 changed files with 90 additions and 83 deletions

View 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;
}

View File

@@ -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;
}

View File

@@ -43,23 +43,37 @@
#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;
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]; }
};
static inline const char *
pop_arg(Args *args)
{
if (!args->argc)
return NULL;
args->argc--;
return (args->argv++)[0];
}
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__

View 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];

View 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;
};

View 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;

View File

@@ -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);
}

View 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;

View File

@@ -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] <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());

View File

@@ -41,7 +41,7 @@
#ifndef __USAGE_HH__
#define __USAGE_HH__
extern const char *progname;
extern std::string progname;
void usage();