What is the design pattern for processing command line arguments

Design PatternsCommand LineArgumentsLanguage Agnostic

Design Patterns Problem Overview


If you are writing a program that is executable from the command line, you often want to offer the user several options or flags, along with possibly more than one argument. I have stumbled my way through this many times, but is there some sort of design pattern for looping through args and calling the appropriate handler functions?

Consider:

myprogram -f filename -d directory -r regex

How do you organize the handler functions after you retrieve the arguments using whatever built-ins for your language? (language-specific answers welcomed, if that helps you articulate an answer)

Design Patterns Solutions


Solution 1 - Design Patterns

I think the following answer is more along the lines of what you are looking for:

You should look at applying the Template Pattern (Template Method in "Design Patterns" [Gamma, el al])

In short it's overall processing looks 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 class that has methods for:

PreProcess()
ProcessLine()
PostProcess()
Usage()
Main()

Then create a chassis, that instantiates a ConsoleEngine() instance and sends the Main() message to kick it off.

To see a good example of how to apply this to a console or command line program check out the following link: http://msdn.microsoft.com/en-us/magazine/cc164014.aspx

The example is in C#, but the ideas are easily implemented in any other environment.

You would look at the GetOpt() as just the part that fit's into the argument handling (pre-processing).

Hope this helps.

Solution 2 - Design Patterns

I don't know of any documented "patterns" for processing.

I believe one of the oldest libraries/APIs for handling arguments is getopt. Googling "getopt" shows lots of man pages and links to implementations.

Generally, I have a preferences or settings service in my application that the argument processor knows how to communicate with. Arguments are then translated into something in this service that the application than then query. This could be as simple as a dictionary of settings (like a string setting named "filename").

Solution 3 - Design Patterns

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

Solution 4 - Design Patterns

Well, its an old post but i would still like to contribute. The question was intended on choice of design patterns however i could see a lot of discussion on which library to use. I have checked out microsoft link as per lindsay which talks about template design pattern to use.

However, i am not convinced with the post. Template pattern's intent is to define a template which will be implemented by various other classes to have uniform behavior. I don't think parsing command line fits into it.

I would rather go with "Command" design pattern. This pattern is best fit for menu driven options.

http://www.blackwasp.co.uk/Command.aspx

so in your case, -f, -d and -r all becomes commands which has common or separate receiver defined. That way more receivers can be defined in future. The next step will be to chain these responsibilities of commands, in case there a processing chain required. For which i would choose.

http://www.blackwasp.co.uk/ChainOfResponsibility.aspx

I guess the combination of these two are best to organize the code for command line processing or any menu driven approach.

Solution 5 - Design Patterns

A few comments on this...

First, while there aren't any patterns per se, writing a parser is essentially a mechanical exercise, since given a grammar, a parser can be easily generated. Tools like Bison, and ANTLR come to mind.

That said, parser generators are usually overkill for the command line. So the usual pattern is to write one yourself (as others have demonstrated) a few times until you get sick of dealing with the tedious detail and find a library to do it for you.

I wrote one for C++ that saves a bunch of effort that getopt imparts and makes nice use of templates: TCLAP

Solution 6 - Design Patterns

The http://www.boost.org/doc/libs/1_36_0/doc/html/program_options.html">boost::program_options</a> library is nice if you're in C++ and have the luxury of using Boost.

Solution 7 - Design Patterns

Assuming you have a "config" object that you aim to setup with the flags and a suitable command line parser that takes care of parsing the command line and supply a constant stream 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;
    }
}

Solution 8 - Design Patterns

I prefer options like "-t text" and "-i 44"; I don't like "-fname" or "--very-long-argument=some_value".

And "-?", "-h", and "/h" all produce a help 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);
   }


   

Solution 9 - Design Patterns

I'm riffing on the ANTLR answer by mes5k. This link to Codeproject is for an article that discusses ANLTR and using the visit pattern to implement the actions you want you app to take. It's well written and worth reviewing.

Solution 10 - Design Patterns

I would recommend using a command line processor library. Some Russian guy created a decent one, but there are tons of them out there. Will save you some time so you can concentrate on the purpose of your app rather than parsing command line switches!

Solution 11 - Design Patterns

Getopt is the only way to go.

http://sourceforge.net/projects/csharpoptparse

Solution 12 - Design Patterns

Solution 13 - Design Patterns

You don't mention a language for this but if you are looking for a really nice Objective-C wrapper around getopt then Dave Dribin's DDCLI framework is really nice.

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

Solution 14 - Design Patterns

I use the Getopts::std and Getopts::long in perl and also the Getopt function in C. This standardises the parsing and format of parameters. Other languages have different mechanisms for handling these.

Hope this helps

Solution 15 - Design Patterns

The standard design usually follows what getopt does, there are getopt libraries for many languages, .NET, python, C, Perl, PHP, etc.

The basic design is to have a command line parser which returns part by part the arguments passed to be checked in a loop.

This article discusses it in some more detail.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSam McAfeeView Question on Stackoverflow
Solution 1 - Design PatternsLindsay MorsilloView Answer on Stackoverflow
Solution 2 - Design PatternsPeter RitchieView Answer on Stackoverflow
Solution 3 - Design PatternsJason CohenView Answer on Stackoverflow
Solution 4 - Design Patternsamarnath chatterjeeView Answer on Stackoverflow
Solution 5 - Design Patternsmes5kView Answer on Stackoverflow
Solution 6 - Design Patternsargv0View Answer on Stackoverflow
Solution 7 - Design PatternsVinko VrsalovicView Answer on Stackoverflow
Solution 8 - Design PatternsMartin Del VecchioView Answer on Stackoverflow
Solution 9 - Design PatternsDavid RobbinsView Answer on Stackoverflow
Solution 10 - Design PatternsKilhofferView Answer on Stackoverflow
Solution 11 - Design PatternscfedukeView Answer on Stackoverflow
Solution 12 - Design PatternsMeadockView Answer on Stackoverflow
Solution 13 - Design PatternsDave VerwerView Answer on Stackoverflow
Solution 14 - Design PatternsXetiusView Answer on Stackoverflow
Solution 15 - Design PatternsVinko VrsalovicView Answer on Stackoverflow