145 lines
5.7 KiB
C++
145 lines
5.7 KiB
C++
#ifndef COMMAND_H
|
|
#define COMMAND_H
|
|
|
|
/*********************************************************************
|
|
* This header file includes data structure for option reading
|
|
* This is a cornerstone data structure of mini shell
|
|
* which aims to store command-line options for parser
|
|
*
|
|
* This data structue is design to read-in the command line options
|
|
* which are organized as follows:
|
|
*
|
|
* <command_name> --<command_option_1> <command_option_1_value>
|
|
* --<command_option_2> ...
|
|
*
|
|
* This is not only used by each command available in the shell
|
|
* but also the interface of the shell, such as interactive mode
|
|
********************************************************************/
|
|
#include <string>
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#include "vtr_vector.h"
|
|
#include "vtr_range.h"
|
|
#include "command_fwd.h"
|
|
|
|
/* Begin namespace openfpga */
|
|
namespace openfpga {
|
|
|
|
/*********************************************************************
|
|
* Supported date types of value which is followed by a command-line option
|
|
********************************************************************/
|
|
enum e_option_value_type {
|
|
OPT_INT,
|
|
OPT_FLOAT,
|
|
OPT_STRING,
|
|
NUM_OPT_VALUE_TYPES
|
|
};
|
|
|
|
/*********************************************************************
|
|
* Data structure to stores all the information related to a command
|
|
* to be defined in the mini shell
|
|
* This data structure should NOT contain any parsing results!
|
|
* It should be a read-only once created!
|
|
*
|
|
* An example of how to use
|
|
* -----------------------
|
|
* // Create a new command with a name of 'read_file'
|
|
* // This command can be called as
|
|
* // read_file --file <file_name>
|
|
* // read_file -f <file_name>
|
|
* // read_file --help
|
|
* // read_file -h
|
|
* Command cmd("read_file");
|
|
*
|
|
* // Add a mandatory option 'file' to the command
|
|
* CommandOptionId opt_file = cmd.add_option("file", true, "Input file path");
|
|
* // Add a short name 'f' for 'file' option
|
|
* cmd.set_option_short_name(opt_file, "f");
|
|
* // The option require a string value which is the file path
|
|
* cmd.set_option_require_value(opt_file, OPT_STRING);
|
|
*
|
|
* // Add an non-mandatory option 'help' to the command
|
|
* // which does not require a value
|
|
* CommandOptionId opt_help = cmd.add_option("help", false, "Show help desk");
|
|
* // Add a short name 'h' for 'help' option
|
|
* cmd.set_option_short_name(opt_help, "h");
|
|
*
|
|
* // Run a command parser and store the results in CommandContext
|
|
* CommandContext cmd_context(cmd);
|
|
* if (false == parse_command(cmd_opts, cmd, cmd_context)) {
|
|
* // Parse failed. Print the help desk
|
|
* print_command_options(cmd);
|
|
* } else {
|
|
* // Parse succeed. Let user to confirm selected options
|
|
* print_command_context(cmd, cmd_context);
|
|
* }
|
|
*
|
|
* Note:
|
|
* When adding an option name, please do NOT add any dash at the beginning!!!
|
|
********************************************************************/
|
|
class Command {
|
|
public: /* Types */
|
|
typedef vtr::vector<CommandOptionId, CommandOptionId>::const_iterator command_option_iterator;
|
|
/* Create range */
|
|
typedef vtr::Range<command_option_iterator> command_option_range;
|
|
public: /* Constructor */
|
|
Command(const char* name);
|
|
public: /* Public accessors */
|
|
std::string name() const;
|
|
command_option_range options() const;
|
|
/* Find all the options that are mandatory */
|
|
std::vector<CommandOptionId> required_options() const;
|
|
/* Find all the options that require a value */
|
|
std::vector<CommandOptionId> require_value_options() const;
|
|
CommandOptionId option(const std::string& name) const;
|
|
CommandOptionId short_option(const std::string& name) const;
|
|
std::string option_name(const CommandOptionId& option_id) const;
|
|
std::string option_short_name(const CommandOptionId& option_id) const;
|
|
bool option_required(const CommandOptionId& option_id) const;
|
|
bool option_require_value(const CommandOptionId& option_id) const;
|
|
e_option_value_type option_require_value_type(const CommandOptionId& option_id) const;
|
|
std::string option_description(const CommandOptionId& option_id) const;
|
|
public: /* Public mutators */
|
|
CommandOptionId add_option(const char* name,
|
|
const bool& option_required,
|
|
const char* description);
|
|
bool set_option_short_name(const CommandOptionId& option_id, const char* short_name);
|
|
void set_option_require_value(const CommandOptionId& option_id,
|
|
const e_option_value_type& option_require_value_type);
|
|
public: /* Public validators */
|
|
bool valid_option_id(const CommandOptionId& option_id) const;
|
|
private: /* Internal data */
|
|
/* The name of the command */
|
|
std::string name_;
|
|
|
|
vtr::vector<CommandOptionId, CommandOptionId> option_ids_;
|
|
|
|
/* Information about the options available in this command */
|
|
/* Name of command line option to appear in the user interface
|
|
* Regular names are typically with a prefix of double dash '--'
|
|
* Short names are typically with a prefix of single dash '-'
|
|
*/
|
|
vtr::vector<CommandOptionId, std::string> option_names_;
|
|
vtr::vector<CommandOptionId, std::string> option_short_names_;
|
|
|
|
/* If the option is manadatory when parsing */
|
|
vtr::vector<CommandOptionId, bool> option_required_;
|
|
|
|
/* Data type of the option values to be converted
|
|
* If the option does NOT require a value, this will be an invalid type
|
|
*/
|
|
vtr::vector<CommandOptionId, e_option_value_type> option_require_value_types_;
|
|
|
|
/* Description of the option, this is going to be printed out in the help desk */
|
|
vtr::vector<CommandOptionId, std::string> option_description_;
|
|
|
|
/* Fast name look-up */
|
|
std::map<std::string, CommandOptionId> option_name2ids_;
|
|
std::map<std::string, CommandOptionId> option_short_name2ids_;
|
|
};
|
|
|
|
} /* End namespace openfpga */
|
|
|
|
#endif
|