FRAG-OPT

Section: C Library Functions (3)
Updated: 2005-02-06
Index  

NAME

frag-opt - a re-entrant argument parsing library  

SYNOPSIS

#include <frag-opt.h>

FRAG * frag_init(frag_option * fops, int argc, char ** argv, int flags);
int frag_parse(FRAG * frag);
const char * frag_err(FRAG * frag);
void frag_usage(FRAG * frag);
void frag_free(FRAG * frag);

typedef struct {
    signed int id;  /* the id-number */
    char chr;       /* short option */
    char *str;      /* long option */
    int type;       /* type */
    char *arg;      /* argument name */
    char *desc;     /* description */
} frag_option;

typedef struct {
    int index;      /* where are we going */
    int chr;        /* more specificly */
    int id;         /* the id-number of the option (or error) */
    int type;       /* what type the option was (enable or disable) */
    /* + some other fields you don't need to know or care about */
} FRAG;  

DESCRIPTION

frag-opt is a re-entrant argument parsing library, designed in the spirit of getopt. frag-opt can parse the normal short (a dash followed by a character, "-o") and long options (two dashes followed by a string, "--option") as well as short negation (a plus-sign followed by a character, "+o") and long negation (two dashes followed by the string "no-" followed by a string, "--no-option") options.

This man-page is meant to be a quick referance, the complete manual is in info-format.  

USAGE

First you will have to create an array of frag_option structures (the example below shows how to do this easily). Then you have to create the FRAG-structure using the frag_init() funtion. Then you have to call frag_parse() to actually parse the arguments. frag_parse() puts the correct identification number in frag->id, so you can handle the identification with a switch-statement. frag_parse() returns the number of arguments left to parse, which means that it will return 0 when there is nothing to do anymore, which means that you can wrap the switch-statement in a nice while-loop with frag_parse() as it's condition. See the example below.  

FRAG_OPTION FIELDS

id
This is the identification-number of the option. Some people like to use plain numbers here (like in the example), while some people like to use the ascii-value of a character ('h'). The only requirement is that it is a positive integer (zero is accepted).

chr
This is the short option. At the moment any character is acceptable. Using common sense is recommended though, as for example '-' won't work right.

str
This is the long option. No checking is done for the strings at the moment. Traditionally only alphanumeric characters (usually in lower case) and the dash (to substitute space) are used in long options.

type
This is the type of the option. Zero means that it is a normal option. FRAG_ARG means it takes an argument. FRAG_OPT_ARG means it takes an optional argument. FRAG_NEG means it is negatable. If you OR FRAG_HIDDEN with any of the above, the option won't show in the help message. If FRAG_ALIAS is OR'd with them, the option is printed as if it was just another alternative of the previous option (description is discarded).

arg
This is used in the help message to describe what kind of argument the option takes. If the option takes an argument and this is NULL, "VALUE" is used instead. Brackets are automatically used for optional arguments.

desc
This is used in the help message to describe what the option does. Long lines are automatically word-wrapped. Any tabs or newlines are printed as well, so you can do some rudimentary formatting if you think it's necessary.  

FRAG_OPTION MACROS

FRAG_PROGRAM
If you want to get arguments to the program itself (filenames for example), use the FRAG_PROGRAM-macro. FRAG_PROGRAM covers the short option, long option and type fields of the structure. You can choose the identification number yourself. The arg-name-string is used in the help-message-creation like this: "usage: PROGRAM-NAME [OPTIONS] ARG-NAME", so if the arguments for the program are optional, remember to put brackets in the string. The description field will be printed on the line following the usage-text. Both the arg-name and the description can be NULL to disable them.

FRAG_END_ARRAY
To end the array, use FRAG_END_ARRAY. FRAG_END_ARRAY covers all fields. If you do not use FRAG_END_ARRAY, frag-opt will segfault.  

FRAG_INIT FLAGS

When calling frag_init(), you can give several flags OR'd together as it's last argument. If you don't know what OR'ing is see the example below and if you still don't understand, ask someone.

FRAG_DISABLE_DOUBLEDASH
Disables the behaviour where all arguments after a "--" are interpreted to be arguments for the program.

FRAG_DISABLE_CLUSTERS
Disables clusters of short options like "-xzv".

FRAG_DISABLE_EQUALS_LONG
Disables the "--option=ARGUMENT" way of giving arguments to options.

FRAG_ENABLE_SPACED_LONG
Enables the "--option ARGUMENT" way of giving arguments to options.

FRAG_DISABLE_SPACED_SHORT
Disables the "-o ARGUMENT" way of giving arguments to options.

FRAG_ENABLE_NO_SPACE_SHORT
Enables the "-oARGUMENT" way of giving arguments to options.

FRAG_DISABLE_LONG_OPTIONS
Disables long options altogether.

FRAG_DISABLE_SHORT_OPTIONS
Disables short options altogether.

FRAG_DISABLE_NEGATION_OPTIONS
Disables negation options altogether (both long and short).

FRAG_ENABLE_ONEDASH_LONG
Long options can be used with "-option". Consider disabling clusters if using this, since the "-utc" cluster could be interpreted as the long option "-utc". If the options are designed so that no such overlapping is possible, then there is no danger.

FRAG_QUIET
Does not print error-messages. An alternative way of getting a description is using frag_err(), whic returns a simpler, constant string.

 

RETURN VALUE

frag_init() returns a pointer to the FRAG-structure or NULL if out of memory, frag_parse() returns the number of arguments left to parse and frag_err() returns a constant string describing the error that happened.  

EXAMPLE

The following example implements most of frag-opt's features.


  #include <stdio.h>
  #include <stdlib.h>
  #include <frag-opt.h>


  int main(int argc, char ** argv)
  {
      int recursion = 0;
      int depth = 0;
      char *end;
      FRAG *frag;
      frag_option fops[] = {
          { 0, FRAG_PROGRAM,                 "[FILES]", "an example program" },
          { 1, 'h', "help",      0           NULL,      "print this message" },
          { 1, 'u', "usage",     FRAG_ALIAS, NULL,      NULL                 },
          { 2, 'v', "version",   0,          NULL,      "print version info" },
          { 3, 'r', "recursive", FRAG_NEG,   NULL,      "search recursively" },
          { 4, 'd', "depth",     FRAG_ARG,   "DEPTH",   "depth of recursion" },
          { FRAG_END_ARRAY }
      };


      frag = frag_init(fops, argc, argv, FRAG_ENABLE_SPACED_LONG
                                       | FRAG_ENABLE_NO_SPACE_SHORT);
      if (frag == NULL) {
          printf("out of memory\n");
          exit(EXIT_FAILURE);
      }
      while (frag_parse(frag)) {
          switch (frag->id) {
              case 0:
                  printf("arg: %s\n", frag->arg);
                  break;
              case 1:
                  frag_usage(frag);
                  frag_free(frag);
                  exit(EXIT_SUCCESS);
              case 2:
                  printf("example version 1.0.0\n");
                  frag_free(frag);
                  exit(EXIT_SUCCESS);
              case 3:
                  recursion = frag->type;
                  break;
              case 4:
                  depth = atoi(frag->arg);
                  if (depth < 0) {
                      printf("depth must be a positive integer\n");
                      frag_free(frag);
                      exit(EXIT_FAILURE);
                  } else if (depth == 0)
                      recursion = 0;
                  else
                      recursion = 1;
                  break;
              default: /* an error occured */
                  frag_free(frag);
                  frag_usage(frag);
                  exit(EXIT_FAILURE);
          }
      }
      frag_free(frag);


      printf("recursion is %d, depth is %d\n", recursion, depth);


      return 0;
  }

Of course a real program would check that the argument actually is a number and use a function like strtol(3) to convert it to a number.  

AUTHOR

Written by Ville Jokela.  

URL

http://koti.mbnet.fi/midiania/hack/index.html#frag-opt  

SEE ALSO

getopt(3), popt(3)


 

Index

NAME
SYNOPSIS
DESCRIPTION
USAGE
FRAG_OPTION FIELDS
FRAG_OPTION MACROS
FRAG_INIT FLAGS
RETURN VALUE
EXAMPLE
AUTHOR
URL
SEE ALSO

This document was created by man2html, using the manual pages. And then fixed a little by hand :).
Time: 22:11:09 GMT, March 09, 2005