home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / getopt.c < prev    next >
Text File  |  1994-09-25  |  7KB  |  208 lines

  1. /******************************************************************************     From: The C Users Journal - June 1991 p.75-87   New GETOPT(3)
  2.  
  3.    getopt()
  4.  
  5.    Function GETOPT gets the next option letter from the command line.
  6.    GETOPT is an enhanced version of the C library function, GETOPT(3).
  7.  
  8.  
  9.    Innvocation:
  10.  
  11.        option = getopt (argc, argv, optstring);
  12.  
  13.    where
  14.        <argc>
  15.            is the number of arguments in the argument value array.
  16.  
  17.        <argv>
  18.            is the argument value array, i.e., an array of pointers to
  19.            the "words" extracted from the command line.
  20.  
  21.        <optstring>
  22.            is the set of recognized options.  Each character in the
  23.            string is a legal option; any other characters encountered
  24.            as an option in the command line is an illegal option and
  25.            an error message is displayed.  If a character is followed
  26.            by a colon in OPTSTRING, the option expects an argument.
  27.  
  28.        <option>
  29.            returns the next option letter from the command line.  If
  30.            the option expects an argument, OPTARG is set to point to
  31.            the argument.  '?' is returned in the cases of an illegal
  32.            option letter or a missing option argument.  Constant NONOPT
  33.            is returned if a non-option argument is encountered or the
  34.            command line scan is complete (also see OPTARG below for
  35.            both cases.)
  36.  
  37.  
  38.    Public Variables:
  39.  
  40.        OPTARG - returns the text of an option's argument or of a 
  41.             non-option argument.  NULL is returned if an option
  42.             has no argument or if the command line scan is complete.
  43.             For illegal options or missing option arguments, OPTARG
  44.             returns a pointer to the trailing portion of the defective
  45.             ARGV.
  46.  
  47.        OPTERR - controls whether or not GETOPT prints out an 
  48.             error message upon detecting an illegal option or
  49.             a missing option argument.  A non-zero value enables
  50.             error messages; zero disables them.
  51.  
  52.        OPTIND - is the index in ARGV of the command line argument
  53.             that GETOPT will examine next.  GETOPT recognizes changes
  54.             to this variable.  Arguments can be skipped by incrementing
  55.             OPTIND outside of GETOPT and the command line scan can be
  56.             restarted by resetting OPTIND to either 0 or 1.
  57.  
  58. **************************************************************************/
  59.  
  60. #include <stdio.h>                       /* standard I/O definitions */
  61. #ifdef _UCC
  62. #undef USE_INDEX                         /* Set to 1 if your C library uses */
  63. #else                                    /* "index" instead of "strchr" */
  64. #define USE_INDEX 1
  65. #endif
  66.  
  67. #ifdef _UCC
  68. #include <string.h>
  69. #endif
  70.  
  71. #ifdef USE_INDEX
  72. #include <strings.h>                     /* C library string functions */
  73. #define strchr index
  74. #else
  75. #include <string.h>                      /* C library string functions */
  76. #endif
  77. #include "getopt.h"                      /* GETOPT(3) definitions */
  78.  
  79.                                          /* Public variables */
  80. char *optarg = NULL;
  81. int  opterr  = -1,
  82.      optind  = 0;
  83.  
  84.                                          /* Private variables */
  85. static int  end_optind = 0,
  86.             last_optind = 0,
  87.             offset_in_group = 1;
  88.  
  89.  
  90. int  getopt (argc, argv, optstring)
  91.  
  92.      int  argc;
  93.      char **argv;
  94.      char *optstring;
  95.  
  96. {    /* Local variables */
  97.      char  *group, option, *s;
  98.  
  99. /* Did the caller restart or advance the scan by modifying OPTIND? */
  100.  
  101.      if (optind <= 0)  {
  102.          end_optind = 0;
  103.          last_optind = 0;
  104.          optind = 1;
  105.      }
  106.  
  107.      if (optind != last_optind)
  108.          offset_in_group = 1;
  109.  
  110. /*************************************************************************
  111.  
  112.      Scan the command line and return the next option or, if none, the
  113.      next non-option argument.  At the start of each loop iteration,
  114.      OPTIND is the index of the command line argument currently under
  115.      examination and OFFSET_IN_GROUP is the offset within the current
  116.      ARGV string of the next option (i.e. to be examined in this 
  117.      iteration.)
  118.  
  119. ************************************************************************/
  120.  
  121.      for (option = ' ', optarg = NULL;
  122.            optind < argc;
  123.            optind++, offset_in_group = 1, option = ' ')  {
  124.  
  125.          group = argv[optind];
  126.  
  127. /*  Is this a non-option argument?  If it is and it's the same one
  128.     GETOPT returned on the last call, then loop and try the next
  129.     command line argument.  If it's a new, non-option argument,
  130.     then return the argument to the calling routine.  */
  131.  
  132.          if ( (group[0] != '-')  ||
  133.               ((end_optind > 0)  &&  (optind > end_optind)))  {
  134.               if (optind == last_optind)
  135.                   continue;
  136.               optarg = group;               /* Return NONOPT and argument */
  137.               break;
  138.          }
  139.  
  140. /*  Are we at the end of the current options group?  If so, loop and
  141.     try the next command line argument. */
  142.  
  143.          if (offset_in_group >= strlen (group))
  144.              continue;
  145.  
  146. /*  If the current option is the end-of-option indicator, remember
  147.     its position and move on to the next command line argument. */
  148.  
  149.          option = group[offset_in_group++];
  150.          if (option == '-')  {
  151.              end_optind = optind;            /* Mark end-of-options positon */
  152.              continue;
  153.          }
  154.  
  155. /*  If the current option is an illegal option, print an error message
  156.     and return '?' to the calling routine. */
  157.  
  158.          s = strchr (optstring, option);
  159.          if (s == NULL)  {
  160.              if (opterr)
  161.                  fprintf (stderr, "%s: illegal option -- %c\n",
  162.                              argv[0], option);
  163.              option = '?';
  164.              optarg = &group[offset_in_group-1];
  165.              break;
  166.          }
  167.  
  168. /*  Does the option  expect an argument?  If yes, return the option and
  169.     its argument to the calling routine.  The option's argument may be
  170.     flush up against the option (i.e., the argument is the remainder of
  171.     the current ARGV) or it may be separated from the option by white
  172.     space (i.e., the argument is the whole of the next ARGV). */
  173.  
  174.          if (*++s == ':')  {
  175.              if (offset_in_group < strlen (group))  {
  176.                  optarg = &group[offset_in_group];
  177.                  offset_in_group = strlen (group);
  178.              }
  179.              else  {
  180.                  if ((++optind < argc)  &&  (*argv[optind] != '-'))  {
  181.                      optarg = argv[optind];
  182.                  } else {
  183.                       if (opterr)
  184.                           fprintf (stderr,
  185.                           "%s: option requires an argument -- %c\n",
  186.                                      argv[0], option);
  187.                       option = '?';
  188.                       optarg = &group[offset_in_group-1];
  189.                       offset_in_group = 1;
  190.                  }
  191.              } 
  192.              break;
  193.          }
  194.  
  195. /*  It must be a single-letter option without an argument */
  196.  
  197.          break;
  198.      }
  199.  
  200.  
  201. /*  Return the option and (optionally) its argument */
  202.  
  203.      last_optind = optind;
  204.      return ((option == ' ')  ?  NONOPT : (int) option);
  205. }
  206. /* End of file */
  207.  
  208.