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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#ifndef __USAGE_HH__
|
||||
#define __USAGE_HH__
|
||||
|
||||
extern const char *progname;
|
||||
extern std::string progname;
|
||||
|
||||
void usage();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user