home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 700-799 / ff732.lha / pstools / t1utils / t1sourcecode / getopt.c next >
C/C++ Source or Header  |  1992-09-26  |  4KB  |  121 lines

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