home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / GETOPT.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  6KB  |  194 lines

  1. /****************************************************************************
  2.     $Id: getopt.cpp 501.0 1995/03/07 12:26:14 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of tlGetOpt().
  10.  
  11.     $Log: getopt.cpp $
  12.     Revision 501.0  1995/03/07 12:26:14  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.8  1995/01/31 16:30:14  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.7  1995/01/06  15:57:50  ron
  18.     Corrected Revision keyword
  19.  
  20.     Revision 1.6  1994/11/16  15:39:46  ron
  21.     Added module info; rearranged #include directives
  22.  
  23.     Revision 1.5  1994/10/05  18:38:23  ron
  24.     Renamed TLx...() functions to tl...()
  25.  
  26.     Revision 1.4  1994/09/28  14:18:37  ron
  27.     Removed Macintosh-style #include references
  28.  
  29.     Revision 1.3  1994/09/27  20:22:28  ron
  30.     Changed path separator from / to \
  31.  
  32.     Revision 1.2  1994/09/26  15:43:00  ron
  33.     Changed include file references
  34.  
  35.     Revision 1.1  1994/08/16  18:13:04  ron
  36.     Initial revision
  37.  
  38. ****************************************************************************/
  39.  
  40. #include <tlx\501\_build.h>
  41.  
  42. TLX_MODULE_INFO("$Revision: 501.0 $");
  43.  
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <tlx\501\cmdapp.h>
  47.  
  48. /*---------------------------------------------------------------------------
  49.     Global variables
  50. ---------------------------------------------------------------------------*/
  51.  
  52. int    _TLXDATA    gOptInd = 1;    // Index of next argument
  53. int    _TLXDATA    gOptErr = 1;    // Nonzero enables arre message
  54. char * _TLXDATA    gOptArg = 0;    // Pointer to current option argument
  55.  
  56. /*-------------------------------------------------------------------------*/
  57.     int _TLXFUNC tlGetOpt(int argc, char *argv[], const char *opts)
  58.  
  59. /*  Parses the command line options, UNIX System V style. Standard option
  60.     syntax is:
  61.  
  62.         option ::= SW [optLetter]* [argLetter space* argument]
  63.  
  64.     where:
  65.  
  66.     - SW is either '/' or '-', according to the native platform
  67.       conventions:
  68.       - MS-DOS: current setting of the switchar (int 21h function 37h).
  69.       - OS/2: always '/'
  70.       - UNIX: always '-'
  71.     - there is no space before any optLetter or argLetter.
  72.     - opt/arg letters are alphabetic, not punctuation characters.
  73.     - optLetters, if present, must be matched in opts.
  74.     - argLetters, if present, are found in opts followed by ':'.
  75.     - argument is any white-space delimited string.     Note that it
  76.       can include the SW character.
  77.     - upper and lower case letters are distinct.
  78.  
  79.     There may be multiple option clusters on a command line, each
  80.     beginning with a SW, but all must appear before any non-option
  81.     arguments (arguments not introduced by SW).  Opt/arg letters may
  82.     be repeated: it is up to the caller to decide if that is an error.
  83.  
  84.     The character SW appearing alone as the last argument is an error.
  85.     The lead-in sequence SWSW ("--" or "//") causes itself and all the
  86.     rest of the line to be ignored (allowing non-options which begin
  87.     with the switch char).
  88.  
  89.     The string *opts allows valid opt/arg letters to be recognized.
  90.     argLetters are followed with ':'.  Getopt() returns the value of
  91.     the option character found, or EOF if no more options are in the
  92.     command line. If option is an argLetter then the global gOptArg is
  93.     set to point to the argument string (having skipped any white-space).
  94.  
  95.     The global gOptInd is initially 1 and is always left as the index
  96.     of the next argument of argv[] which getopt has not taken.  Note
  97.     that if "--" or "//" are used then gOptInd is stepped to the next
  98.     argument before getopt() returns EOF.
  99.  
  100.     If an error occurs, that is an SW char precedes an unknown letter,
  101.     then getopt() will return a '?' character and normally prints an
  102.     error message via perror(). If the global variable gOptErr is set
  103.     to false (zero) before calling getopt() then the error message is
  104.     not printed.
  105.  
  106.     For example, if the MSDOS switch char is '/' (the MSDOS norm) and
  107.  
  108.         *opts == "A:F:PuU:wXZ:"
  109.  
  110.     then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
  111.     are followed by arguments.  A valid command line may be:
  112.  
  113.         aCommand  /uPFPi /X /A L someFile
  114.  
  115.     where:
  116.  
  117.     - 'u' and 'P' will be returned as isolated option letters.
  118.     - 'F' will return with "Pi" as its argument string.
  119.     - 'X' is an isolated option.
  120.     - 'A' will return with "L" as its argument.
  121.     - "someFile" is not an option, and terminates getopt().     The
  122.     caller may collect remaining arguments using argv pointers.
  123.  
  124.     Parameters:
  125.     argc    = number of command line arguments
  126.     argv    = array of argument pointers
  127.     opts    = string describing options (see above)
  128.  
  129.     Return value:
  130.     Value of the next option character, or EOF if no more options follow.
  131. ---------------------------------------------------------------------------*/
  132. {
  133.     static char *nextopt = NULL;    /* remember next option char's location */
  134.     const char *optP;
  135.     char ch;
  136.  
  137.     TLX_ASSERT_PTR(argv);
  138.     TLX_ASSERT_PTR(opts);
  139.  
  140.     if (gOptInd <= argc)
  141.     {
  142.     if (nextopt == NULL)        // Ran out of previous argument
  143.     {
  144.         if ((nextopt = argv[gOptInd]) == NULL || *(nextopt++) != gOptionChar)
  145.         goto gopEOF;
  146.  
  147.         if (*nextopt == gOptionChar)    // Repeated switch character
  148.         {
  149.         gOptInd++;
  150.         goto gopEOF;
  151.         }
  152.     }
  153.  
  154.     if ((ch = *(nextopt++)) == 0)    // Null option
  155.     {
  156.         gOptInd++;
  157.         goto gopEOF;
  158.     }
  159.  
  160.     if (':' == ch  ||  (optP = strchr(opts, ch)) == NULL)
  161.         goto gopError;
  162.  
  163.     if (':' == *(++optP))
  164.     {
  165.         gOptInd++;
  166.         if (*nextopt == 0)
  167.         {
  168.         if (gOptInd > argc)  goto  gopError;
  169.         nextopt = argv[gOptInd++];
  170.         }
  171.         gOptArg = nextopt;
  172.         nextopt = NULL;
  173.     }
  174.     else
  175.     {
  176.         if (*nextopt == 0)
  177.         {
  178.         gOptInd++;
  179.         nextopt = NULL;
  180.         }
  181.         gOptArg = NULL;
  182.     }
  183.     return ch;
  184.     }
  185.  
  186. gopEOF:
  187.     gOptArg = nextopt = NULL;
  188.     return EOF;
  189.  
  190. gopError:
  191.     gOptArg = NULL;
  192.     return '?';
  193. }
  194.