Using Getopt

Previous: Using io

Flusspferd provides with getopt a module to parse command line parameters. The module has a C++ and a Javascript API and is also used by the Flusspferd Shell. See flusspferd::getopt for the reference.

Getopt is similar to alternatives known from other languages, like getopt(3). The getopt function takes a specification which options are supported and returns a list of parsed options. If no second parameter containing an Array of command line input is passed it is read from the environment.

The parameter specification is an object consisting of parameter names as properties. Those properties contain objects defining different aspects of the parameter. So the specification is basically a JSON structure. A very simple specification thus might look like this:

var spec = {
  "help" : { },
  "version" : { },
  "foo" : { },
  "bar" : { }
};

getopt uses the following syntax for command line parameters:

Short option (one character long): -S

Long option: --longoption

If an option is short or long is determined by the length of the name. In our example all options are long options. It is recommended to always provide a descriptive long option and provide a short alias for common options. This brings us to the next point: Providing aliases. You can define several aliases for each option by adding an "alias" option to the subobjects:

var spec = {
  "help" : {
     "alias" : "h"
  },
  "version" : {
     "alias" : "v"
  },
  "foo" : {
     "alias" : ["f", "F"]
  },
  "bar" : {
     "alias" : ["baz", "b" ]
  }
};

getopt also supports arguments to those options. The following syntaxes are supported:

Short option with argument: -Sargument or -S argument

Long option with argument: --longoption=argument or --longoption argument

You can specify that an option requires an argument with an "argument" parameter which should be either "none", "optional" or "required" and you can define an argument type with "argument_type". The "argument_type" is currently useful to improve the help output and for a bash completion script. We get back to this later.

var spec = {
  "help" : {
     "alias" : "h"
  },
  "version" : {
     "alias" : "v"
  },
  "foo" : {
     "alias" : ["f", "F"],
     "argument" : "required",
     "argument_type" : "file"
  },
  "bar" : {
     "alias" : ["baz", "b" ],
     "argument" : "optional"
     // an argument_type does not need to be set
  }
};

Now we can parse the command line parameters with getopt:

var getopt = require('getopt');
var result = getopt.getopt(spec);

result now is an object containing the parsed options as property names which contain a list of arguments:

{
  "option0" : [ "arg0", "arg1" ],
  "option1" : [ "arg0" ],
  "_" : [ "rest" ]
};

The property "_" is a special case containing the unparsed arguments.

Now you could process result. But getopt provides an even easier way by using callbacks. You can define callbacks inside the specifications:

var spec = {
  "help" : {
    "alias" : "h",
    "callback" : function() {
      print("help");
      quit();
    }
  },
  "version" : {
    "alias" : "v",
    "callback" : function() {
      print("Version 1.0");
      quit();
    }
  },
  "foo" : {
     "alias" : ["f", "F"],
     "argument" : "required",
     "argument_type" : "file",
     "callback" : function(name, argument) {
       print("option '" + name + "' argument '" + argument + "'");
     }
  },
  "bar" : {
     "alias" : ["baz", "b" ],
     "argument" : "optional",
     "callback" : function(name, argument) {
       if(argument) {
         print("option '" + name + "' called with argument '" + argument + "'");
       }
       else {
         print("option '" + name + "' called without argument");
       }
     }
  }
};

"help" is a common option and every program using command line options should provide it to list the supported options. getopt can even help with this option since getopt already know the supported options. There is a getopt_help function taking the parameter specification and generating a corresponding output. To improve the output you should add a "doc" property to all options.

var spec = {
  "help" : {
    "alias" : "h",
    "doc" : "Displays this message.",
    "callback" : function() {
      print("usage: getopt-example.js [OPTIONS] ...");
      print(getopt.getopt_help(spec));
      quit();
    }
  },
  "version" : {
    "alias" : "v",
    "doc" : "Show version number.",
    "callback" : function() {
      print("Version 1.0");
      quit();
    }
  },
  "foo" : {
     "alias" : ["f", "F"],
     "argument" : "required",
     "argument_type" : "file",
     "doc" : "Foo!",
     "callback" : function(name, argument) {
       print("option '" + name + "' argument '" + argument + "'");
     }
  },
  "bar" : {
     "alias" : ["baz", "b" ],
     "argument" : "optional",
     "doc" : "Bar is the way to go.",
     "callback" : function(name, argument) {
       if(argument) {
         print("option '" + name + "' called with argument '" + argument + "'");
       }
       else {
         print("option '" + name + "' called without argument");
       }
     }
  }
};

getopt even provides functions to auto generate parts of a manpage (flusspferd::getopt_man) and bash completion script (flusspferd::getopt_bash).

See help/getopt-example.js or misc/replace-var.js for examples on the usage of getopt with Javascript or take a look at src/programs/flusspferd.cpp for the getopt usage with C++.

Next: Using the cURL module


Contact us at team -AT- flusspferd -DOT- org or as described on our homepage.

Generated on Thu Feb 4 23:05:12 2010 for Flusspferd by doxygen 1.6.1