home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 19 Printer / 19-Printer.zip / REV.ZIP / getopt.c < prev    next >
C/C++ Source or Header  |  1993-02-26  |  9KB  |  229 lines

  1. #define VER "1.03"
  2.  
  3. /*
  4.  * Verarbeitung einer rudiment"aren Optionsliste, vor allem der
  5.  * "Ubergabeparameter an eine Applikation.
  6.  *
  7.  * T.J. Domsalla, dommi@rz.tu-clausthal.de
  8.  * T. Schwerdtfeger, apts@rz.tu-clausthal.de
  9.  *
  10.  * Version VER, Clausthal, 1991, 1993
  11.  */
  12.  
  13. #define OPTARGSTR_WARNING       0        /* Warnung bei Argument mit '-' */
  14.  
  15. char    *gopt_VersionString = "Version " VER ", " __DATE__ ", " __TIME__;
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include "getopt.h"
  21.  
  22. int   gopt_MAXOPTIONS = GOPT_MAXOPTIONS;
  23. union gopt_Arg gopt_Argument;
  24.  
  25. static int _gopt_lookupoption (char);
  26.  
  27. /*************************************************************************
  28.  * argc enth"alt beim Erstaufruf der Routine die Anzahl der "ubergebenen
  29.  * Argumente.
  30.  * Diese sind im Vektor argv enthalten. F"ur die Art der Speicherung gilt
  31.  * gleiches wie f"ur die Argument"ubergabe an main(); argv ist ein Array von
  32.  * Pointern auf Strings und wird mit einem NULL-Pointer abgeschlossen.
  33.  * program_name sollte den Namen dieses Programmes enthalten (i.allg.
  34.  * argv[0] aus main(argc, argv)) und wird bei Fehlermeldungen angegeben.
  35.  * Ist argc gleich 0, werden weitere Optionen aus argv des vorangegangen
  36.  * getopt()-Aufrufes mit argc != 0 extrahiert. In diesem Fall bleibt argv
  37.  * unbeachtet. Optionen werden mit einem '-' eingeleitet, andernfalls wird
  38.  * GOPT_IS_SIMPLE_STRING zur"uckgegeben und gopt_Argument enth"alt den gelesenen
  39.  * String.
  40.  */
  41. char     getopt (int argc, char **argv, char *program_name)
  42. {
  43.   static char **args = NULL;
  44.   static char *actarg;
  45.   static   more = 0;                     /* in zusammengefasster Optionsliste? */
  46.   char     status = 0;
  47.   char     ch;
  48.  
  49.   /* Auswertung von argv nur, wenn argc != 0, */
  50.   /* z.B. f"ur wiederholte Aufrufe             */
  51.   if (argc > 0)
  52.     args = argv;                           /* Zeiger auf Optionenliste */
  53.  
  54.   if ((args && *args) || more)             /* war argv vielleicht NULL? */
  55.     {                                      /* nein! */
  56.       int      rc = GOPT_NO_OPTION;      /* Returncode von _gopt_lookupoption() */
  57.  
  58.       gopt_Argument.s = NULL;              /* Arg-String zur"ucksetzen */
  59.  
  60.       if (!more)                           /* nicht mehr in Optionsliste? */
  61.         actarg = *args++;                  /* n"achstes Argumentfeld */
  62.       if ( ((!more) && *actarg++ == '-') || more)
  63.         {
  64.           more = 0;
  65.           /* Ist hinter dem '-' eine g"ultige Option */
  66.           /* angegeben? Wenn nicht, Fehlermeldung und  */
  67.           /* raus mit GOPT_ERROR */
  68.           if ((rc = _gopt_lookupoption (ch = *actarg)) != GOPT_NO_OPTION)
  69.             {
  70.               if (rc == GOPT_SIMPLE_OPTION)
  71.                 {
  72.                   if (*++actarg)           /* 's ist 'ne Optionsfolge */
  73.                     more = 1;
  74.                 }
  75.               else if (rc == GOPT_SARG_OPTION)
  76.                 /* auf das Optionszeichen folgt direkt ein */
  77.                 /* weiteres einzelnes Zeichen als Argument */
  78.                 {
  79.                   if (!(gopt_Argument.c = *++actarg))
  80.                     /* es wurde kein weiteres Argumentzeichen angegeben */
  81.                     {
  82.                       fprintf (stderr, "\n%s%sOption `-%c': missing argument\n",
  83.                                (program_name ? program_name : ""), ": ", ch);
  84.                       status = GOPT_ERROR;
  85.                     }
  86.                   else if (*++actarg)
  87.                     more = 1;
  88.                 }
  89.               else
  90.                 /* rc == GOPT_ARG_OPTION */
  91.  
  92.                 /*
  93.                  * folgen direkt nach der Option (ohne Leerzeichen) weitere
  94.                  * Zeichen, werden diese als Argument der Option genommen.
  95.                  * Sonst wird das Argument nach einem Leer- zeichen angenommen
  96.                  */
  97.                 {
  98.                   if (*++actarg)
  99.                     {
  100.                       gopt_Argument.s = actarg;
  101.                       /* args++; */
  102.                     }
  103.                   else if (*args && *(actarg = *args++))
  104.                     {
  105.                       gopt_Argument.s = actarg;
  106.  
  107. #if OPTARGSTR_WARNING
  108.  
  109.                       /*
  110.                        * Warnung ausgeben, falls erstes Zeichen des
  111.                        * Argumentstrings ein '-' ist
  112.                        */
  113.                       if (*actarg == '-')
  114.                         fprintf (stderr, "\n%s%sWarning: option `-%c': argument `%s' "
  115.                                  "could be option\n",
  116.                                  (program_name ? program_name : ""),
  117.                                  ": ", ch, actarg);
  118. #else
  119.                       /* keine Warnung, sondern gnadenlose Fehlermeldung */
  120.                       if (*actarg == '-' && strchr (goptVektor, actarg[1]))
  121.                         {
  122.                           fprintf (stderr, "\n%s%sOption `-%c': argument `%s' "
  123.                                    "is option\n",
  124.                                    (program_name ? program_name : ""),
  125.                                    ": ", ch, actarg);
  126.                           status = GOPT_ERROR;
  127.                         }
  128. #endif
  129.                     }
  130.                   else
  131.                     {
  132.                       fprintf (stderr, "\n%s%sOption `-%c' missing argument\n",
  133.                                (program_name ? program_name : ""),
  134.                                ": ", ch);
  135.                       status = GOPT_ERROR;
  136.                     }
  137.                 }
  138.             }
  139.           else
  140.             /* rc = GOPT_NO_OPTION */
  141.             {
  142.               fprintf (stderr, "\n%s%sUnrecognized option `-%c'\n",
  143.                        (program_name ? program_name : ""), ": ", ch);
  144.               rc = GOPT_ERROR;
  145.               if (*++actarg)
  146.                 more = 1;
  147.             }
  148.         }
  149.       else
  150.         /* ist irgendein String */
  151.         {
  152.           gopt_Argument.s = actarg - 1;
  153.           status = GOPT_IS_SIMPLE_STRING;
  154.         }
  155.     }                                      /* endif (args) */
  156.   else
  157.     status = GOPT_FINISHED;
  158.  
  159.   return status ? status : ch;
  160. }
  161.  
  162. /**************************************************************************
  163.  * getopt_env() wird als ERSTER Aufruf (wie getopt() mit argc > 0, s.o.!)
  164.  * anstelle von getopt() aufgerufen, um statt eines Argumentvektors eine
  165.  * Environmentvariable mit Namen name auszulesen und liefert die erste Option
  166.  * aus dieser Variable. Weitere Optionen werden wie gewohnt mit
  167.  * getopt(0,NULL, prgname) ausgelesen.
  168.  * program_name enth"alt den Namen der aufrufenden Application (vgl. getopt()).
  169.  */
  170. #ifdef ANSIC
  171.  #define __MAXO__   GOPT_MAXOPTIONS
  172. #else
  173.   #define __MAXO__  gopt_MAXOPTIONS
  174. #endif
  175. char     getopt_env (char *name, char *program_name)
  176. {
  177.   char    *options;                      /* Optionenstring (Inhalt der
  178.                                           * Env-Variable */
  179.  
  180.   /* ANSI C-WARNUNG: ANSI C unterst"utzt keine gr"o"senvariable Arrays!
  181.    * GNU C tut's ...; sonst mit -DANSIC compilieren */
  182.   char    *optionlist[__MAXO__];         /* Liste der Einzeloptionen f"ur
  183.                                           * maximal gopt_MAXOPTIONS Optionen
  184.                                           * (standard 32). */
  185.   int      i = 0;
  186.   char     status = GOPT_FINISHED;
  187.  
  188.   if (name)
  189.     {
  190.       options = getenv (name);             /* hole Optionen (hoffentlich) aus
  191.                                             * Environmentvariable */
  192.       /* baue argv f"ur getopt() */
  193.       while ((optionlist[i++] = strtok (options, " \t\n\f")) != NULL &&
  194.              i < __MAXO__)              /* ANSI C: s.o. wg. gopt_MAXOPTIONS */
  195.         options = NULL;
  196.       status = getopt (i, optionlist, program_name);
  197.     }
  198.   return status;
  199. }
  200.  
  201. /**************************************************************************
  202.  * Nachschauen, ob das in ch "ubergebene Zeichen (ausser '.' und ':') in
  203.  * goptVektor enthalten ist. Gibt GOPT_ARG_OPTION, GOPT_SIMPLE_OPTION oder 0
  204.  * zur"uck, je nachdem, ob eine Option ein Argument besitzt, keins oder nicht
  205.  * zul"assig ist.
  206.  */
  207. static int _gopt_lookupoption (char ch)
  208. {
  209.   char    *cp;
  210.   int      status = GOPT_NO_OPTION;
  211.  
  212.   if (!(ch == '.' && ch == ':'))           /* '.', ':' nicht erlaubt */
  213.     {
  214.       if ((cp = strchr (goptVektor, ch)))  /* ch als Option zul"assig? */
  215.         {
  216.           cp++;
  217.           if (*cp == '.')                  /* Opt. mit Argument? */
  218.             status = GOPT_SARG_OPTION;     /* Option mit Zeichenargument */
  219.           else if (*cp == ':')
  220.             status = GOPT_ARG_OPTION;      /* Option mit Argument */
  221.           else
  222.             status = GOPT_SIMPLE_OPTION;   /* einfache Option */
  223.         }
  224.     }
  225.   return status;
  226. }
  227.  
  228. /**************************************************************************/
  229.