[ACCEPTED]-What is the design pattern for processing command line arguments-language-agnostic
I think the following answer is more along 16 the lines of what you are looking for:
You 15 should look at applying the Template Pattern 14 (Template Method in "Design Patterns" [Gamma, el 13 al])
In short it's overall processing looks 12 like this:
If the arguments to the program are valid then
Do necessary pre-processing
For every line in the input
Do necessary input processing
Do necessary post-processing
Otherwise
Show the user a friendly usage message
In short, implement a ConsoleEngineBase 11 class that has methods for:
PreProcess()
ProcessLine()
PostProcess()
Usage()
Main()
Then create a 10 chassis, that instantiates a ConsoleEngine() instance 9 and sends the Main() message to kick it 8 off.
To see a good example of how to apply 7 this to a console or command line program 6 check out the following link: http://msdn.microsoft.com/en-us/magazine/cc164014.aspx
The example 5 is in C#, but the ideas are easily implemented 4 in any other environment.
You would look 3 at the GetOpt() as just the part that fit's 2 into the argument handling (pre-processing).
Hope 1 this helps.
I don't know of any documented "patterns" for 11 processing.
I believe one of the oldest libraries/APIs 10 for handling arguments is getopt. Googling 9 "getopt" shows lots of man pages and links 8 to implementations.
Generally, I have a preferences 7 or settings service in my application that 6 the argument processor knows how to communicate 5 with. Arguments are then translated into 4 something in this service that the application 3 than then query. This could be as simple 2 as a dictionary of settings (like a string 1 setting named "filename").
You didn't mention the language, but for 1 Java we've loved Apache Commons CLI. For C/C++, getopt.
Well, its an old post but i would still 23 like to contribute. The question was intended 22 on choice of design patterns however i could 21 see a lot of discussion on which library 20 to use. I have checked out microsoft link 19 as per lindsay which talks about template 18 design pattern to use.
However, i am not 17 convinced with the post. Template pattern's 16 intent is to define a template which will 15 be implemented by various other classes 14 to have uniform behavior. I don't think 13 parsing command line fits into it.
I would 12 rather go with "Command" design 11 pattern. This pattern is best fit for menu 10 driven options.
http://www.blackwasp.co.uk/Command.aspx
so in your case, -f, -d and 9 -r all becomes commands which has common 8 or separate receiver defined. That way more 7 receivers can be defined in future. The 6 next step will be to chain these responsibilities 5 of commands, in case there a processing 4 chain required. For which i would choose.
http://www.blackwasp.co.uk/ChainOfResponsibility.aspx
I 3 guess the combination of these two are best 2 to organize the code for command line processing 1 or any menu driven approach.
A few comments on this...
First, while there 13 aren't any patterns per se, writing a parser 12 is essentially a mechanical exercise, since 11 given a grammar, a parser can be easily 10 generated. Tools like Bison, and ANTLR 9 come to mind.
That said, parser generators 8 are usually overkill for the command line. So 7 the usual pattern is to write one yourself 6 (as others have demonstrated) a few times 5 until you get sick of dealing with the tedious 4 detail and find a library to do it for you.
I 3 wrote one for C++ that saves a bunch of 2 effort that getopt imparts and makes nice 1 use of templates: TCLAP
The boost::program_options library is nice if you're in C++ and 1 have the luxury of using Boost.
Assuming you have a "config" object that 4 you aim to setup with the flags and a suitable 3 command line parser that takes care of parsing 2 the command line and supply a constant stream 1 of the options, here goes a block of pseudocode
while (current_argument = cli_parser_next()) {
switch(current_argument) {
case "f": //Parser strips the dashes
case "force":
config->force = true;
break;
case "d":
case "delete":
config->delete = true;
break;
//So on and so forth
default:
printUsage();
exit;
}
}
I prefer options like "-t text" and "-i 3 44"; I don't like "-fname" or "--very-long-argument=some_value".
And 2 "-?", "-h", and "/h" all produce a help 1 screen.
Here's how my code looks:
int main (int argc, char *argv[])
{ int i;
char *Arg;
int ParamX, ParamY;
char *Text, *Primary;
// Initialize...
ParamX = 1;
ParamY = 0;
Text = NULL;
Primary = NULL;
// For each argument...
for (i = 0; i < argc; i++)
{
// Get the next argument and see what it is
Arg = argv[i];
switch (Arg[0])
{
case '-':
case '/':
// It's an argument; which one?
switch (Arg[1])
{
case '?':
case 'h':
case 'H':
// A cry for help
printf ("Usage: whatever...\n\n");
return (0);
break;
case 't':
case 'T':
// Param T requires a value; is it there?
i++;
if (i >= argc)
{
printf ("Error: missing value after '%s'.\n\n", Arg);
return (1);
}
// Just remember this
Text = Arg;
break;
case 'x':
case 'X':
// Param X requires a value; is it there?
i++;
if (i >= argc)
{
printf ("Error: missing value after '%s'.\n\n", Arg);
return (1);
}
// The value is there; get it and convert it to an int (1..10)
Arg = argv[i];
ParamX = atoi (Arg);
if ((ParamX == 0) || (ParamX > 10))
{
printf ("Error: invalid value for '%s'; must be between 1 and 10.\n\n", Arg);
return (1);
}
break;
case 'y':
case 'Y':
// Param Y doesn't expect a value after it
ParamY = 1;
break;
default:
// Unexpected argument
printf ("Error: unexpected parameter '%s'; type 'command -?' for help.\n\n", Arg);
return (1);
break;
}
break;
default:
// It's not a switch that begins with '-' or '/', so it's the primary option
Primary = Arg;
break;
}
}
// Done
return (0);
}
I'm riffing on the ANTLR answer by mes5k. This 4 link to Codeproject is for an article that discusses ANLTR 3 and using the visit pattern to implement 2 the actions you want you app to take. It's 1 well written and worth reviewing.
I would recommend using a command line processor 5 library. Some Russian guy created a decent one, but there 4 are tons of them out there. Will save you 3 some time so you can concentrate on the 2 purpose of your app rather than parsing 1 command line switches!
How about the interpreter pattern? http://www.dofactory.com/net/interpreter-design-pattern
0
You don't mention a language for this but 3 if you are looking for a really nice Objective-C 2 wrapper around getopt then Dave Dribin's 1 DDCLI framework is really nice.
I use the Getopts::std and Getopts::long in perl and also the Getopt function 4 in C. This standardises the parsing and 3 format of parameters. Other languages have 2 different mechanisms for handling these.
Hope 1 this helps
The standard design usually follows what 6 getopt does, there are getopt libraries 5 for many languages, .NET, python, C, Perl, PHP, etc.
The 4 basic design is to have a command line parser 3 which returns part by part the arguments 2 passed to be checked in a loop.
This article 1 discusses it in some more detail.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.