From 3fd94abcd3d3aef1455841cbfe4cb5506f26a6a7 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Tue, 23 Sep 2014 11:11:38 +0200 Subject: [PATCH 1/2] cmdline: parse parameters in GNU mode This change sets the option parser to GNU mode, that is, allows further option parameters after non-option parameters, e.g.: dump-trace foo.tc -s instead of dump-trace -s foo.tc As Fail* currently works on GNU platforms only, this behavior is the one presumably expected from users. Change-Id: I9c55eaf4560cde81ebd0b94214201c8ad02c2b74 --- src/core/util/CommandLine.cc | 15 ++++++++++----- src/core/util/CommandLine.hpp | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/util/CommandLine.cc b/src/core/util/CommandLine.cc index 33f6c333..6116beb0 100644 --- a/src/core/util/CommandLine.cc +++ b/src/core/util/CommandLine.cc @@ -43,8 +43,13 @@ bool CommandLine::parse() { option::Descriptor desc = {0, 0, 0, 0, 0, 0}; this->options.push_back(desc); - // Generate the options stats - option::Stats stats(this->options.data(), argv.size(), argv.data()); + // Copy argv to preserve original argument order + // (for proper re-parsing after adding more options) + argv_reordered = argv; + + // Generate the options stats (GNU mode) + option::Stats stats(true, this->options.data(), + argv_reordered.size(), argv_reordered.data()); if (parsed_options) delete[] parsed_options; @@ -56,9 +61,9 @@ bool CommandLine::parse() { parsed_options = new option::Option[stats.options_max]; parsed_buffer = new option::Option[stats.buffer_max]; - m_parser = new option::Parser(this->options.data(), argv.size(), argv.data(), - parsed_options, parsed_buffer); - + m_parser = new option::Parser(true, this->options.data(), + argv_reordered.size(), argv_reordered.data(), + parsed_options, parsed_buffer); // Pop the terminating entry this->options.pop_back(); diff --git a/src/core/util/CommandLine.hpp b/src/core/util/CommandLine.hpp index 21dfd2a3..a89ad9c8 100644 --- a/src/core/util/CommandLine.hpp +++ b/src/core/util/CommandLine.hpp @@ -30,7 +30,7 @@ public: private: static CommandLine m_instance; - std::vector argv; + std::vector argv, argv_reordered; std::vector options; option::Option *parsed_options, *parsed_buffer; option::Parser *m_parser; From b0e13b17c995b82fdf0126c6393e1025b24ffc3f Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Thu, 18 Sep 2014 15:07:05 +0200 Subject: [PATCH 2/2] tools: abort at unknown cmdline parameters This change makes all C++-based tools in tools/ abort when they encounter an unknown commandline parameter (both option or non-option). This has already caused some confusion, as in some cases unexpected behaviour can be the result. For example, "prune-trace -t mytrace.tc -d database" up to now ignored the "-t" parameter, took "mytrace.tc" as the first non-option parameter (and ignored it); as no option parameter may follow the non-option parameters, all other options were ignored as well. Change-Id: Ia0812a518c4760fa28ed54979c81f43fa7aa096e --- tools/compute-hops/main.cc | 10 ++++++++-- tools/convert-trace/main.cc | 13 ++++++++++--- tools/dump-hops/DumpHops.cc | 11 +++++++++-- tools/dump-trace/DumpTrace.cc | 11 +++++++++-- tools/import-trace/main.cc | 13 ++++++++++--- tools/prune-trace/main.cc | 13 ++++++++++--- 6 files changed, 56 insertions(+), 15 deletions(-) diff --git a/tools/compute-hops/main.cc b/tools/compute-hops/main.cc index 2f3979de..0c1134a7 100644 --- a/tools/compute-hops/main.cc +++ b/tools/compute-hops/main.cc @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) // Manually fill the command line option parser CommandLine &cmd = CommandLine::Inst(); - cmd.addOption("", "", Arg::None, "USAGE: compute-hops [options]"); + CommandLine::option_handle UNKNOWN = cmd.addOption("", "", Arg::None, "USAGE: compute-hops [options]"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h,--help \tPrint usage and exit"); CommandLine::option_handle ALGORITHM = @@ -99,7 +99,13 @@ int main(int argc, char *argv[]) return 1; } - if (cmd[HELP]) { + if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() > 0) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 0; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); if (cmd[HELP]) { exit(0); diff --git a/tools/convert-trace/main.cc b/tools/convert-trace/main.cc index 359d3806..45330ba4 100644 --- a/tools/convert-trace/main.cc +++ b/tools/convert-trace/main.cc @@ -17,7 +17,8 @@ static Logger LOG("convert-trace", true); int main(int argc, char *argv[]) { CommandLine &cmd = CommandLine::Inst(); - cmd.addOption("", "", Arg::None, "usage: convert-trace -f dump|gem5 -t tracefile.tc"); + CommandLine::option_handle UNKNOWN = + cmd.addOption("", "", Arg::None, "usage: convert-trace -f dump|gem5 -t tracefile.tc"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit"); CommandLine::option_handle FORMAT = @@ -28,11 +29,17 @@ int main(int argc, char *argv[]) { cmd.add_args(argv[i]); } if (!cmd.parse()) { - LOG << "Error parsing arguments." << endl; + std::cerr << "Error parsing arguments." << endl; return 1; } - if (cmd[HELP] || !cmd[OUTFILE] || !cmd[FORMAT] || cmd.parser()->nonOptionsCount() != 0) { + if (cmd[HELP] || !cmd[OUTFILE] || !cmd[FORMAT] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() != 0) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 0; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); if (cmd[HELP]) { exit(0); diff --git a/tools/dump-hops/DumpHops.cc b/tools/dump-hops/DumpHops.cc index dd3c88c0..e64695bc 100644 --- a/tools/dump-hops/DumpHops.cc +++ b/tools/dump-hops/DumpHops.cc @@ -49,7 +49,8 @@ int main(int argc, char *argv[]) InjectionPointMessage ev; CommandLine &cmd = CommandLine::Inst(); - cmd.addOption("", "", Arg::None, "usage: dump-hops [options] hopfile.hp"); + CommandLine::option_handle UNKNOWN = + cmd.addOption("", "", Arg::None, "usage: dump-hops [options] hopfile.hp"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit"); // CommandLine::option_handle STATS = @@ -64,7 +65,13 @@ int main(int argc, char *argv[]) return 1; } - if (cmd[HELP] || cmd.parser()->nonOptionsCount() != 1) { + if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() != 1) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 1; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); if (cmd[HELP]) { exit(0); diff --git a/tools/dump-trace/DumpTrace.cc b/tools/dump-trace/DumpTrace.cc index 0015cec2..d86ee5e9 100644 --- a/tools/dump-trace/DumpTrace.cc +++ b/tools/dump-trace/DumpTrace.cc @@ -49,7 +49,8 @@ int main(int argc, char *argv[]) Trace_Event ev; CommandLine &cmd = CommandLine::Inst(); - cmd.addOption("", "", Arg::None, "usage: dump-trace [options] tracefile.tc"); + CommandLine::option_handle UNKNOWN = + cmd.addOption("", "", Arg::None, "usage: dump-trace [options] tracefile.tc"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit"); CommandLine::option_handle STATS = @@ -67,7 +68,13 @@ int main(int argc, char *argv[]) return 1; } - if (cmd[HELP] || cmd.parser()->nonOptionsCount() != 1) { + if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() != 1) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 1; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); if (cmd[HELP]) { exit(0); diff --git a/tools/import-trace/main.cc b/tools/import-trace/main.cc index 9259b612..d039b870 100644 --- a/tools/import-trace/main.cc +++ b/tools/import-trace/main.cc @@ -85,7 +85,8 @@ int main(int argc, char *argv[]) { for (int i = 1; i < argc; ++i) cmd.add_args(argv[i]); - cmd.addOption("", "", Arg::None, "USAGE: import-trace [options]"); + CommandLine::option_handle UNKNOWN = + cmd.addOption("", "", Arg::None, "USAGE: import-trace [options]"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit"); CommandLine::option_handle TRACE_FILE = @@ -176,9 +177,15 @@ int main(int argc, char *argv[]) { // reparse all arguments. cmd.parse(); - if (cmd[HELP]) { + if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() > 0) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 0; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); - exit(0); + exit(!cmd[HELP]); } if (cmd[TRACE_FILE]) { diff --git a/tools/prune-trace/main.cc b/tools/prune-trace/main.cc index 1bcd96ec..5c9129e9 100644 --- a/tools/prune-trace/main.cc +++ b/tools/prune-trace/main.cc @@ -35,7 +35,8 @@ int main(int argc, char *argv[]) { cmd.add_args(argv[i]); } - cmd.addOption("", "", Arg::None, "USAGE: prune-trace [options]"); + CommandLine::option_handle UNKNOWN = + cmd.addOption("", "", Arg::None, "USAGE: prune-trace [options]"); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h,--help \tPrint usage and exit"); Database::cmdline_setup(); @@ -112,9 +113,15 @@ int main(int argc, char *argv[]) { // reparse all arguments. cmd.parse(); - if (cmd[HELP]) { + if (cmd[HELP] || cmd[UNKNOWN] || cmd.parser()->nonOptionsCount() > 0) { + for (option::Option* opt = cmd[UNKNOWN]; opt; opt = opt->next()) { + std::cerr << "Unknown option: " << opt->name << "\n"; + } + for (int i = 0; i < cmd.parser()->nonOptionsCount(); ++i) { + std::cerr << "Unknown non-option: " << cmd.parser()->nonOption(i) << "\n"; + } cmd.printUsage(); - exit(0); + exit(!cmd[HELP]); } Database *db = Database::cmdline_connect();