[ACCEPTED]-What is the design pattern for processing command line arguments-language-agnostic

Accepted answer
Score: 18

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.

Score: 14

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").

Score: 6

You didn't mention the language, but for 1 Java we've loved Apache Commons CLI. For C/C++, getopt.

Score: 5

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.

Score: 4

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

Score: 2

The boost::program_options library is nice if you're in C++ and 1 have the luxury of using Boost.

Score: 2

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;
    }
}
Score: 2

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);
   }
Score: 2

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.

Score: 1

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!

Score: 1

Getopt is the only way to go.

http://sourceforge.net/projects/csharpoptparse

0

Score: 1

How about the interpreter pattern? http://www.dofactory.com/net/interpreter-design-pattern

0

Score: 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.

http://www.dribin.org/dave/blog/archives/2008/04/29/ddcli

Score: 0

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

Score: 0

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