views:

155

answers:

3

I'm writing a command line interpreter and I'm trying to setup formats for individual commands. I have things like the name of the command, the maximum amount of parameters and the minimum amount of parameters. I want to have sort of collection, a sort of prototype of what kind of types the parameters are. My first thought was just to declare a vector without the generics, but then I realized this isn't Java.

Let's say I have a command such as "read test.dat 2" I would want a structure showing that the typical read command has a string and then an integer.

Any ideas?

+2  A: 

I'm not really clear about what you are asking so I may be getting this wrong.

From your description ,it sounds as if you have an abstract notion of commands, and that they have names and an expected structure in terms of parameters. From your description, it sounds like you would want a list of type identifiers and indications on whether they are optional.

Then, you could just instantiate a command object for each command you expect to work with, and add all of them to a collection of commands.

Alternatively, use a map collection to map from command names to the actual command objects. Each command object can also hold a reference to a handler object to actually execute the command.

Uri
How would I create a data structure of type identifiers?
Chad
If you are going to be working with a set of standard types (e.g., ints and strings), you could create enums to represent them and generate an array or list of enums to represent the exact order. If your types have special semantics (e.g., address vs. password), use a singleton object for each type.
Uri
Thanks, this helps immensely
Chad
Glad to be of help. If your commands are natural text or similar to natural text, then there are infrastructures you could use. If they're just standard formats, you have even more reusable building blocks to work with.
Uri
+2  A: 

Heterogenous Container

If you want to have a container that can store a fixed set of types, you can use one of boost::variant:

typedef boost::variant<std::string, int> optval;
typedef std::vector<optval> options;

Now, you can push_back into the vector either strings or integers, and the variant will note what it contains:

options opts;
opts.push_back(10);
opts.push_back("hello");

You can read about it in its documentation at Boost variant, including how to get the right value out of the variant. You can of course also have a map from argument names to such variants, if you have already set up your command line parsing, and don't need libraries for that anymore:

std::map<std::string, optval> map;
map["--max-foo"] = 10;
map["--title"] = "something fun";

Command line parsing

If you want to parse the command line arguments of your program, you can look into the Boost.Program Options library, which will greatly assist you doing that.

Mostly, however, i end up using the posix getopt function, which can also parse the command line. I recommend you to look into boost program options first, and if you feel it's too heavy, you can look into getopt (see man 3 getopt)

Johannes Schaub - litb
+1  A: 

Something like this, perhaps:

enum ParameterType
{
  Int,
  String
};

struct Command
{
  string name;
  vector<ParameterType> maxParameters;
  int minParameters;
};
ChrisW