core/util: Added CommandLine interface (for bochs)
This commit is contained in:
@ -18,8 +18,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "config/VariantConfig.hpp"
|
#include "config/VariantConfig.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
#include "optionparser.h"
|
#include "optionparser/optionparser.h"
|
||||||
#include "optionparser_ext.hpp"
|
#include "optionparser/optionparser_ext.hpp"
|
||||||
|
|
||||||
#include "T32Connector.hpp"
|
#include "T32Connector.hpp"
|
||||||
#include "t32config.hpp"
|
#include "t32config.hpp"
|
||||||
|
|||||||
@ -6,10 +6,12 @@
|
|||||||
#ifdef BUILD_BOCHS
|
#ifdef BUILD_BOCHS
|
||||||
|
|
||||||
#include "../SALInst.hpp"
|
#include "../SALInst.hpp"
|
||||||
|
#include "util/CommandLine.hpp"
|
||||||
|
|
||||||
aspect FailBochsInit {
|
aspect FailBochsInit {
|
||||||
advice call("int bxmain()") : before ()
|
advice call("int bxmain()") : before ()
|
||||||
{
|
{
|
||||||
|
fail::CommandLine::Inst().collect_args(bx_startup_flags.argc, bx_startup_flags.argv);
|
||||||
fail::simulator.startup();
|
fail::simulator.startup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
set(SRCS
|
set(SRCS
|
||||||
|
CommandLine.cc
|
||||||
|
CommandLine.hpp
|
||||||
ElfReader.cc
|
ElfReader.cc
|
||||||
ElfReader.hpp
|
ElfReader.hpp
|
||||||
Demangler.hpp
|
Demangler.hpp
|
||||||
@ -20,6 +22,7 @@ set(SRCS
|
|||||||
SynchronizedQueue.hpp
|
SynchronizedQueue.hpp
|
||||||
WallclockTimer.cc
|
WallclockTimer.cc
|
||||||
WallclockTimer.hpp
|
WallclockTimer.hpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# required by ProtoStream.cc:
|
# required by ProtoStream.cc:
|
||||||
|
|||||||
72
src/core/util/CommandLine.cc
Normal file
72
src/core/util/CommandLine.cc
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#include "CommandLine.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
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<const char *> 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
|
||||||
91
src/core/util/CommandLine.hpp
Normal file
91
src/core/util/CommandLine.hpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#ifndef __COMMAND_LINE_HPP__
|
||||||
|
#define __COMMAND_LINE_HPP__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <assert.h>
|
||||||
|
#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<std::string> argv;
|
||||||
|
std::vector<option::Descriptor> 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
|
||||||
@ -326,7 +326,7 @@ struct Descriptor
|
|||||||
* Use an enum rather than plain ints for better readability, as shown in the example
|
* Use an enum rather than plain ints for better readability, as shown in the example
|
||||||
* at Descriptor.
|
* at Descriptor.
|
||||||
*/
|
*/
|
||||||
const unsigned index;
|
unsigned index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to distinguish between options with the same @ref 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
|
* It is recommended that you use an enum rather than a plain int to make your
|
||||||
* code more readable.
|
* code more readable.
|
||||||
*/
|
*/
|
||||||
const int type;
|
int type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Each char in this string will be accepted as a short option character.
|
* @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.
|
* See @ref longopt for more information.
|
||||||
*/
|
*/
|
||||||
const char* const shortopt;
|
const char* shortopt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The long option name (without the leading @c -- ).
|
* @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.
|
* 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
|
* @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.
|
* See @ref CheckArg for more information.
|
||||||
*/
|
*/
|
||||||
const CheckArg check_arg;
|
CheckArg check_arg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The usage text associated with the options in this Descriptor.
|
* @brief The usage text associated with the options in this Descriptor.
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#ifndef __OPTIONSPARSER_EXT_HPP__
|
#ifndef __OPTIONSPARSER_EXT_HPP__
|
||||||
#define __OPTIONSPARSER_EXT_HPP__
|
#define __OPTIONSPARSER_EXT_HPP__
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
struct Arg: public option::Arg
|
struct Arg: public option::Arg
|
||||||
{
|
{
|
||||||
Reference in New Issue
Block a user