home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / print / t1utils / getopt.c next >
Text File  |  1994-02-04  |  5KB  |  120 lines

  1. /* getopt.c - get command line options
  2.  *
  3.  * Parse the command line options, System V style.
  4.  *
  5.  * Standard option syntax is:
  6.  *
  7.  *         option = -[optLetter,...][argLetter argument]
  8.  *
  9.  * where
  10.  *    - there is no space between the '-' and optLetters or argLetters.
  11.  *    - optLetters and argLetters are alphabetic, not punctuation characters.
  12.  *    - optLetters, if present, must be matched in options.
  13.  *    - argLetters, if present, are found in options followed by ':'.
  14.  *    - argument is any white-space delimited string.  Note that it can
  15.  *      include the '-'.
  16.  *    - upper and lower case letters are distinct.
  17.  *
  18.  * There may be multiple option clusters on a command line, each
  19.  * beginning with a '-', but all must appear before any non-option
  20.  * arguments (arguments not introduced by a '-'). optLetters and
  21.  * argLetters may be repeated, it is up to the caller to decide
  22.  * if that is an error.
  23.  *
  24.  * The character '-' appearing alone as the last argument is an error.
  25.  * The lead-in sequence '--' causes itself and all the rest of the
  26.  * line to be ignored (allowing non-options which begin with '-'.
  27.  *
  28.  * The string *options allows valid optLetters and argLetters to be
  29.  * recognized.               argLetters are followed with ':'.  getopt() returns the
  30.  * value of the option character found, or EOF if no more options are in
  31.  * the command line.    If option is an argLetter then the global optarg is
  32.  * set to point to the argument string (having skipped any white-space).
  33.  *
  34.  * The global optind is initially 1 and is always left as the index
  35.  * of the next argument of argv[] which getopt has not taken.      Note
  36.  * that if '--' is used then optind is stepped to the next argument
  37.  * before getopt() returns EOF.
  38.  *
  39.  * If an error occurs, that is '-' precedes an unknown letter, then
  40.  * getopt() will return a '?' character and normally prints an error
  41.  * message via perror().        If the global variable opterr is set to
  42.  * false (zero) before calling getopt() then the error message is
  43.  * not printed.
  44.  *
  45.  * For example, if
  46.  *
  47.  *         *options == "A:F:PuU:wXZ:"
  48.  *
  49.  * then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
  50.  * are followed by arguments.     A valid command line may be:
  51.  *
  52.  *     command  -uPFPi -X -A L otherparameters
  53.  *
  54.  * where:
  55.  *      - 'u' and 'P' will be returned as isolated option letters.
  56.  *    - 'F' will return with "Pi" as its argument string.
  57.  *    - 'X' is an isolated option.
  58.  *    - 'A' will return with "L" as its argument.
  59.  *    - "otherparameters" is not an option, and terminates getOpt.  The
  60.  *      caller may collect remaining arguments using argv pointers.
  61. */
  62.  
  63. #include <errno.h>
  64. #include <stdio.h>
  65. #include <string.h>
  66.  
  67. int            optind  = 1;    /* index of which argument is next */
  68. char    *optarg;         /* pointer to argument of current option */
  69. int      opterr  = 1;    /* allow error message  */
  70.  
  71. static    char   *letP = NULL;    /* remember next option char's location */
  72.  
  73.  
  74. int        getopt(int argc, char *argv[], char *options)
  75. {
  76.           unsigned char ch;
  77.          char *optP;
  78.  
  79.           if (argc > optind) {
  80.                  if (letP == NULL) {
  81.                          if ((letP = argv[optind]) == NULL ||
  82.                                  *(letP++) != '-')  goto gopEOF;
  83.                          if (*letP == '-') {
  84.                                  optind++;  goto gopEOF;
  85.                          }
  86.                  }
  87.                  if (0 == (ch = *(letP++))) {
  88.                          optind++;  goto gopEOF;
  89.                  }
  90.                  if (':' == ch  ||  (optP = strchr(options, ch)) == NULL)
  91.                          goto gopError;
  92.                  if (':' == *(++optP)) {
  93.                          optind++;
  94.                          if (0 == *letP) {
  95.                                  if (argc <= optind)  goto  gopError;
  96.                                  letP = argv[optind++];
  97.                          }
  98.                          optarg = letP;
  99.                          letP = NULL;
  100.                  } else {
  101.                          if (0 == *letP) {
  102.                                  optind++;
  103.                                  letP = NULL;
  104.                          }
  105.                          optarg = NULL;
  106.                  }
  107.                  return ch;
  108.          }
  109. gopEOF:
  110.           optarg = letP = NULL;
  111.          return EOF;
  112.  
  113. gopError:
  114.            optarg = NULL;
  115.          errno  = EINVAL;
  116.          if (opterr)
  117.                  perror ("getopt()");
  118.          return ('?');
  119. }
  120.