home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 19 Printer
/
19-Printer.zip
/
REV.ZIP
/
getopt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-26
|
9KB
|
229 lines
#define VER "1.03"
/*
* Verarbeitung einer rudiment"aren Optionsliste, vor allem der
* "Ubergabeparameter an eine Applikation.
*
* T.J. Domsalla, dommi@rz.tu-clausthal.de
* T. Schwerdtfeger, apts@rz.tu-clausthal.de
*
* Version VER, Clausthal, 1991, 1993
*/
#define OPTARGSTR_WARNING 0 /* Warnung bei Argument mit '-' */
char *gopt_VersionString = "Version " VER ", " __DATE__ ", " __TIME__;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "getopt.h"
int gopt_MAXOPTIONS = GOPT_MAXOPTIONS;
union gopt_Arg gopt_Argument;
static int _gopt_lookupoption (char);
/*************************************************************************
* argc enth"alt beim Erstaufruf der Routine die Anzahl der "ubergebenen
* Argumente.
* Diese sind im Vektor argv enthalten. F"ur die Art der Speicherung gilt
* gleiches wie f"ur die Argument"ubergabe an main(); argv ist ein Array von
* Pointern auf Strings und wird mit einem NULL-Pointer abgeschlossen.
* program_name sollte den Namen dieses Programmes enthalten (i.allg.
* argv[0] aus main(argc, argv)) und wird bei Fehlermeldungen angegeben.
* Ist argc gleich 0, werden weitere Optionen aus argv des vorangegangen
* getopt()-Aufrufes mit argc != 0 extrahiert. In diesem Fall bleibt argv
* unbeachtet. Optionen werden mit einem '-' eingeleitet, andernfalls wird
* GOPT_IS_SIMPLE_STRING zur"uckgegeben und gopt_Argument enth"alt den gelesenen
* String.
*/
char getopt (int argc, char **argv, char *program_name)
{
static char **args = NULL;
static char *actarg;
static more = 0; /* in zusammengefasster Optionsliste? */
char status = 0;
char ch;
/* Auswertung von argv nur, wenn argc != 0, */
/* z.B. f"ur wiederholte Aufrufe */
if (argc > 0)
args = argv; /* Zeiger auf Optionenliste */
if ((args && *args) || more) /* war argv vielleicht NULL? */
{ /* nein! */
int rc = GOPT_NO_OPTION; /* Returncode von _gopt_lookupoption() */
gopt_Argument.s = NULL; /* Arg-String zur"ucksetzen */
if (!more) /* nicht mehr in Optionsliste? */
actarg = *args++; /* n"achstes Argumentfeld */
if ( ((!more) && *actarg++ == '-') || more)
{
more = 0;
/* Ist hinter dem '-' eine g"ultige Option */
/* angegeben? Wenn nicht, Fehlermeldung und */
/* raus mit GOPT_ERROR */
if ((rc = _gopt_lookupoption (ch = *actarg)) != GOPT_NO_OPTION)
{
if (rc == GOPT_SIMPLE_OPTION)
{
if (*++actarg) /* 's ist 'ne Optionsfolge */
more = 1;
}
else if (rc == GOPT_SARG_OPTION)
/* auf das Optionszeichen folgt direkt ein */
/* weiteres einzelnes Zeichen als Argument */
{
if (!(gopt_Argument.c = *++actarg))
/* es wurde kein weiteres Argumentzeichen angegeben */
{
fprintf (stderr, "\n%s%sOption `-%c': missing argument\n",
(program_name ? program_name : ""), ": ", ch);
status = GOPT_ERROR;
}
else if (*++actarg)
more = 1;
}
else
/* rc == GOPT_ARG_OPTION */
/*
* folgen direkt nach der Option (ohne Leerzeichen) weitere
* Zeichen, werden diese als Argument der Option genommen.
* Sonst wird das Argument nach einem Leer- zeichen angenommen
*/
{
if (*++actarg)
{
gopt_Argument.s = actarg;
/* args++; */
}
else if (*args && *(actarg = *args++))
{
gopt_Argument.s = actarg;
#if OPTARGSTR_WARNING
/*
* Warnung ausgeben, falls erstes Zeichen des
* Argumentstrings ein '-' ist
*/
if (*actarg == '-')
fprintf (stderr, "\n%s%sWarning: option `-%c': argument `%s' "
"could be option\n",
(program_name ? program_name : ""),
": ", ch, actarg);
#else
/* keine Warnung, sondern gnadenlose Fehlermeldung */
if (*actarg == '-' && strchr (goptVektor, actarg[1]))
{
fprintf (stderr, "\n%s%sOption `-%c': argument `%s' "
"is option\n",
(program_name ? program_name : ""),
": ", ch, actarg);
status = GOPT_ERROR;
}
#endif
}
else
{
fprintf (stderr, "\n%s%sOption `-%c' missing argument\n",
(program_name ? program_name : ""),
": ", ch);
status = GOPT_ERROR;
}
}
}
else
/* rc = GOPT_NO_OPTION */
{
fprintf (stderr, "\n%s%sUnrecognized option `-%c'\n",
(program_name ? program_name : ""), ": ", ch);
rc = GOPT_ERROR;
if (*++actarg)
more = 1;
}
}
else
/* ist irgendein String */
{
gopt_Argument.s = actarg - 1;
status = GOPT_IS_SIMPLE_STRING;
}
} /* endif (args) */
else
status = GOPT_FINISHED;
return status ? status : ch;
}
/**************************************************************************
* getopt_env() wird als ERSTER Aufruf (wie getopt() mit argc > 0, s.o.!)
* anstelle von getopt() aufgerufen, um statt eines Argumentvektors eine
* Environmentvariable mit Namen name auszulesen und liefert die erste Option
* aus dieser Variable. Weitere Optionen werden wie gewohnt mit
* getopt(0,NULL, prgname) ausgelesen.
* program_name enth"alt den Namen der aufrufenden Application (vgl. getopt()).
*/
#ifdef ANSIC
#define __MAXO__ GOPT_MAXOPTIONS
#else
#define __MAXO__ gopt_MAXOPTIONS
#endif
char getopt_env (char *name, char *program_name)
{
char *options; /* Optionenstring (Inhalt der
* Env-Variable */
/* ANSI C-WARNUNG: ANSI C unterst"utzt keine gr"o"senvariable Arrays!
* GNU C tut's ...; sonst mit -DANSIC compilieren */
char *optionlist[__MAXO__]; /* Liste der Einzeloptionen f"ur
* maximal gopt_MAXOPTIONS Optionen
* (standard 32). */
int i = 0;
char status = GOPT_FINISHED;
if (name)
{
options = getenv (name); /* hole Optionen (hoffentlich) aus
* Environmentvariable */
/* baue argv f"ur getopt() */
while ((optionlist[i++] = strtok (options, " \t\n\f")) != NULL &&
i < __MAXO__) /* ANSI C: s.o. wg. gopt_MAXOPTIONS */
options = NULL;
status = getopt (i, optionlist, program_name);
}
return status;
}
/**************************************************************************
* Nachschauen, ob das in ch "ubergebene Zeichen (ausser '.' und ':') in
* goptVektor enthalten ist. Gibt GOPT_ARG_OPTION, GOPT_SIMPLE_OPTION oder 0
* zur"uck, je nachdem, ob eine Option ein Argument besitzt, keins oder nicht
* zul"assig ist.
*/
static int _gopt_lookupoption (char ch)
{
char *cp;
int status = GOPT_NO_OPTION;
if (!(ch == '.' && ch == ':')) /* '.', ':' nicht erlaubt */
{
if ((cp = strchr (goptVektor, ch))) /* ch als Option zul"assig? */
{
cp++;
if (*cp == '.') /* Opt. mit Argument? */
status = GOPT_SARG_OPTION; /* Option mit Zeichenargument */
else if (*cp == ':')
status = GOPT_ARG_OPTION; /* Option mit Argument */
else
status = GOPT_SIMPLE_OPTION; /* einfache Option */
}
}
return status;
}
/**************************************************************************/