Get Teem at SourceForge.net. Fast, secure and Free Open Source software downloads
teem / hest

  Usage Basics

All the parameters in an option need to be of the same type: boolean, or int, or float, etc. The types come from the air library, in the air.h header file:

  typedef enum {
    airTypeUnknown,   /* 0 */
    airTypeBool,      /* 1 */
    airTypeInt,       /* 2 */
    airTypeFloat,     /* 3 */
    airTypeDouble,    /* 4 */
    airTypeChar,      /* 5 */
    airTypeString,    /* 6 */
    airTypeLast
  } airType;
All the information about an option that is required to parse it is given in a struct called a hestOpt. The important part of the struct is (as copied from hest.h):
  char *flag,           /* how the option is identified on the cmd line */
    *name;              /* simple description of option's parameter(s) */
  int type,             /* type of option (from airType enum) */
    min, max;           /* min and max # of parameters for option */
  void *valueP;         /* storage of parsed values */
  char *dflt,           /* default value written out as string */
    *info;              /* description to be printed with "glossary" info */
  int *sawP,            /* used ONLY for multiple variable parameter options
                           (min < max > 2): storage of # of parsed values */
These are the pieces of information which hest uses to parse the command line: The hestParse() function which does the command-line parsing takes as one of its arguments an array of hestOpt structs. There are two ways of creating this array: statically and dynamically. In the static method, we use C's ability to initialize a subset of the members of a struct:
  hestOpt opt[] = {
    {"res",   "sx sy", airTypeInt,    2,  2,   res,  NULL, 
     "image resolution"},
    {"v",     "level", airTypeInt,    0,  1,   &v,   "0",
     "verbosity level"},
    {"out",   "file",  airTypeString, 1,  1,   &out, "output.ppm",
     "PPM image output"},
    {NULL,    "input", airTypeString, 1, -1,   &in,  NULL,
     "input image file(s)", &numIn},
    {NULL, NULL, 0}
  };
So "res" is initializing flag, "sx sy" is initializing name, and so on. In the last option, min is 1, and max is -1. A max of -1 is always internally interpreted by hest as INT_MAX (from limits.h). This is how a hest user would say "1 or more" arguments. Because there are a variable number of multiple arguments, we also pass &numIn (stored in sawP in the hestOpt struct) so that hestParse() can store the number of strings parsed.

For the sake of simplicity, there is a single function which called repeatedly in order to dynamically create the same array:

  hestOpt *opt = NULL;
  ...
  hestOptAdd(&opt, "res",   "sx sy", airTypeInt,    2,  2,  res,  NULL,
             "image resolution");
  hestOptAdd(&opt, "v",     "level", airTypeInt,    0,  1,  &v,   "0",
             "verbosity level");
  hestOptAdd(&opt, "out",   "file",  airTypeString, 1,  1,  &out, "output.ppm",
             "PPM image output");
  hestOptAdd(&opt, NULL,    "input", airTypeString, 1, -1,  &in,  NULL,
             "input image file(s)", &numIn);
Notice that the necessary fields in the static and dynamic cases are identical. In both cases, the length of the the array of options does not need to be explicitly calculated or communicated, since {NULL, NULL, 0} values are set in the last hestOpt struct to signal the end of the array. To free all the memory created by calls to hestOptAdd(), use hestOptFree().

Basically, the important part of the hest library is a single function call:

  hestOpt *opt;
  char *err;
  ...
  if (hestParse(opt, argc-1, argv+1, &err, NULL)) {
    fprintf(stderr, "ERROR: %s\n", err);
    free(err); exit(1);
  }
You give to hestParse() only that part of the command line that you want it to process, which is why argc-1, argv+1 is being passed, as opposed to argc, argv, since argv[0] is the executable's name (and for CVS- and AFS-like programs, both argv[0] and argv[1] are the command name). If all goes well, the return value of hestParse() is 0, and all the parsed values are stored in the locations which had been given as the valueP fields in the hestOpt array. If things go wrong, the return value of of hestParse() is 1, and err is allocated to a string holding an error message. The last NULL argument to hestParse() indicates that all defaults in the behavior of hestParse() are acceptable. Whenever parsing strings or a variable number of parameters for an option, hestParse() allocates memory for storage, and the valueP field in hestOpt struct is set to point to this new memory. To simplify the process of cleaning up this memory, the single function hestParseFree() will free any and all memory allocated to store parsed values.

The other useful parts of hest are hestUsage() and hestGlossary(). The hestUsage() function prints a compact reresentation of the various options available on the command line. hestGlossary() gives a longer description of the different options, with at least one line per option. Given the option definitions above, the generated usage and glossary information is:

  Usage: cmd -res <sx sy> [-v [<level>]] [-out <file>] <input...>

  -res <sx sy> = image resolution (2 ints)
  -v [<level>] = verbosity level (optional int); default 0
   -out <file> = PPM image output (string); default output.ppm
    <input...> = input image file(s) (1 or more strings)