diff --git a/debuggers/t32/src/main.cc b/debuggers/t32/src/main.cc index 7b2f4543..af3c68a8 100644 --- a/debuggers/t32/src/main.cc +++ b/debuggers/t32/src/main.cc @@ -18,8 +18,8 @@ #include #include "config/VariantConfig.hpp" #include "sal/SALInst.hpp" -#include "optionparser.h" -#include "optionparser_ext.hpp" +#include "optionparser/optionparser.h" +#include "optionparser/optionparser_ext.hpp" #include "T32Connector.hpp" #include "t32config.hpp" diff --git a/src/core/sal/bochs/FailBochsInit.ah b/src/core/sal/bochs/FailBochsInit.ah index 42b9fcac..5b64ee4d 100644 --- a/src/core/sal/bochs/FailBochsInit.ah +++ b/src/core/sal/bochs/FailBochsInit.ah @@ -6,10 +6,12 @@ #ifdef BUILD_BOCHS #include "../SALInst.hpp" +#include "util/CommandLine.hpp" aspect FailBochsInit { advice call("int bxmain()") : before () { + fail::CommandLine::Inst().collect_args(bx_startup_flags.argc, bx_startup_flags.argv); fail::simulator.startup(); } }; diff --git a/src/core/util/CMakeLists.txt b/src/core/util/CMakeLists.txt index a514c5a4..a22112d2 100644 --- a/src/core/util/CMakeLists.txt +++ b/src/core/util/CMakeLists.txt @@ -1,4 +1,6 @@ set(SRCS + CommandLine.cc + CommandLine.hpp ElfReader.cc ElfReader.hpp Demangler.hpp @@ -20,6 +22,7 @@ set(SRCS SynchronizedQueue.hpp WallclockTimer.cc WallclockTimer.hpp + ) # required by ProtoStream.cc: diff --git a/src/core/util/CommandLine.cc b/src/core/util/CommandLine.cc new file mode 100644 index 00000000..23530d36 --- /dev/null +++ b/src/core/util/CommandLine.cc @@ -0,0 +1,72 @@ +#include "CommandLine.hpp" +#include +#include +#include + + +namespace fail { + CommandLine CommandLine::m_instance; + + void CommandLine::collect_args(argument_count &argc, argument_value &argv) { + // Filter out all command line arguments that start with -Wf, + for (int i = 0; i < argc; ++i) { + if (strncmp(argv[i], "-Wf,", 4) == 0) { + this->argv.push_back(std::string(argv[i] + 4)); + + for (int x = i + 1; x < argc; ++x) { + argv[x - 1] = argv[x]; + } + i --; + argc --; + } + + } + } + + CommandLine::option_handle CommandLine::addOption(const std::string &shortopt, + const std::string &longopt, + const option::CheckArg & check_arg, + const std::string &help) { + + const unsigned int handle = this->options.size(); + option::Descriptor desc = {handle, 0, strdup(shortopt.c_str()), + strdup(longopt.c_str()), + check_arg, strdup(help.c_str())}; + this->options.push_back(desc); + return handle; + } + + bool CommandLine::parse() { + // Terminate the descriptor list + option::Descriptor desc = {0, 0, 0, 0, 0, 0}; + this->options.push_back(desc); + + // Build an argv array + std::vector tmp_argv; + int argc = this->argv.size(); + for (unsigned i = 0; i < this->argv.size(); ++i) + tmp_argv.push_back(this->argv[i].c_str()); + + // Generate the options stats + option::Stats stats(this->options.data(), argc, tmp_argv.data()); + + if (parsed_options) + delete[] parsed_options; + if (parsed_buffer) + delete[] parsed_buffer; + + parsed_options = new option::Option[stats.options_max]; + parsed_buffer = new option::Option[stats.buffer_max]; + + option::Parser parse(this->options.data(), argc, tmp_argv.data(), + parsed_options, parsed_buffer); + + + // Pop the terminating entry + this->options.pop_back(); + + return !parse.error(); + } + + +} // end of namespace diff --git a/src/core/util/CommandLine.hpp b/src/core/util/CommandLine.hpp new file mode 100644 index 00000000..9d4faaa0 --- /dev/null +++ b/src/core/util/CommandLine.hpp @@ -0,0 +1,91 @@ +#ifndef __COMMAND_LINE_HPP__ +#define __COMMAND_LINE_HPP__ + +#include +#include +#include +#include "optionparser/optionparser.h" +#include "optionparser/optionparser_ext.hpp" + + + +namespace fail { + /** + * @class CommandLine + * @brief Implements a command line interface, that filters the + * simulators command line. It is a Singleton. + */ + class CommandLine { + public: + typedef int argument_count; + typedef char **argument_value; + private: + static CommandLine m_instance; + + std::vector argv; + std::vector options; + option::Option *parsed_options, *parsed_buffer; + public: + /// Handle for accessing the parsed data of an option + typedef int option_handle; + + /** + * Singleton accessor + * + * @return reference to the CommandLine singleton object + */ + static CommandLine &Inst() { return m_instance; } + + /** + * Called by the simulator to filter all fail arguments from + * argc, argv + */ + void collect_args(argument_count &, argument_value &); + + /** + * Add a option to the command line interface of the fail-client + * + * @param shortopt e.g "m" for -m + * @param longopt e.g. "memory-region" for --memory-region= + * @param check_arg argument is required. + * @param help help text to be printed for -h + * + * @return return handle to option + */ + option_handle addOption(const std::string &shortopt, + const std::string &longopt, + const option::CheckArg & check_arg, + const std::string &help); + + /** + * + * do the acutal parsing, called by the experiment + * + * @return was the parsing a sucess + */ + bool parse(); + + /** + * Accessor for the command line option objects + * + * @param handle option handle + * + * @return reference to the option parser object + */ + option::Option &operator[](option_handle handle) { + assert(parsed_options != 0); + assert(handle >= 0 && handle < (int)options.size()); + return parsed_options[handle]; + } + /** + * Print help message. + */ + void printUsage() { + int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80; + option::printUsage(fwrite, stdout, options.data(), columns); + } + }; + +} // end of namespace + +#endif diff --git a/debuggers/t32/include/optionparser.h b/src/core/util/optionparser/optionparser.h similarity index 99% rename from debuggers/t32/include/optionparser.h rename to src/core/util/optionparser/optionparser.h index 17bf6ad3..d0ff7fc8 100644 --- a/debuggers/t32/include/optionparser.h +++ b/src/core/util/optionparser/optionparser.h @@ -326,7 +326,7 @@ struct Descriptor * Use an enum rather than plain ints for better readability, as shown in the example * at Descriptor. */ - const unsigned index; + unsigned index; /** * @brief Used to distinguish between options with the same @ref index. @@ -335,7 +335,7 @@ struct Descriptor * It is recommended that you use an enum rather than a plain int to make your * code more readable. */ - const int type; + int type; /** * @brief Each char in this string will be accepted as a short option character. @@ -348,7 +348,7 @@ struct Descriptor * * See @ref longopt for more information. */ - const char* const shortopt; + const char* shortopt; /** * @brief The long option name (without the leading @c -- ). @@ -383,7 +383,7 @@ struct Descriptor * If there is no dummy descriptor, unknown options will be dropped silently. * */ - const char* const longopt; + const char* longopt; /** * @brief For each option that matches @ref shortopt or @ref longopt this function @@ -395,7 +395,7 @@ struct Descriptor * * See @ref CheckArg for more information. */ - const CheckArg check_arg; + CheckArg check_arg; /** * @brief The usage text associated with the options in this Descriptor. diff --git a/debuggers/t32/include/optionparser_ext.hpp b/src/core/util/optionparser/optionparser_ext.hpp similarity index 97% rename from debuggers/t32/include/optionparser_ext.hpp rename to src/core/util/optionparser/optionparser_ext.hpp index 993c0027..c2e01200 100644 --- a/debuggers/t32/include/optionparser_ext.hpp +++ b/src/core/util/optionparser/optionparser_ext.hpp @@ -1,6 +1,8 @@ #ifndef __OPTIONSPARSER_EXT_HPP__ #define __OPTIONSPARSER_EXT_HPP__ +#include +#include struct Arg: public option::Arg {