e1b4d8d074
definitions are more readable, and it's possible that they're more portable to pathalogical platforms. Submitted by: David Hill <david@phobia.ms>
140 lines
3.1 KiB
C
140 lines
3.1 KiB
C
/*
|
|
* Macros for processing command arguments.
|
|
*
|
|
* Conforms closely to the command option requirements of intro(1) in System V
|
|
* and intro(C) in Xenix.
|
|
*
|
|
* A command consists of: cmdname [ options ] [ cmdarguments ]
|
|
*
|
|
* Options consist of a leading dash '-' and a flag letter. An argument may
|
|
* follow optionally preceded by white space.
|
|
* Options without arguments may be grouped behind a single dash.
|
|
* A dash on its own is interpreted as the end of the options and is retained
|
|
* as a command argument.
|
|
* A double dash '--' is interpreted as the end of the options and is discarded.
|
|
*
|
|
* For example:
|
|
* zap -xz -f flame -q34 -- -x
|
|
*
|
|
* where zap.c contains the following in main():
|
|
*
|
|
* OPTIONS("[-xz] [-q queue-id] [-f dump-file] user")
|
|
* FLAG('x', xecute)
|
|
* FLAG('z', zot)
|
|
* STRING('f', file)
|
|
* fp = fopen(file, "w");
|
|
* NUMBER('q', queue)
|
|
* ENDOPTS
|
|
*
|
|
* Results in:
|
|
* xecute = 1
|
|
* zot = 1
|
|
* file = "flame"
|
|
* fp = fopen("flame", "w")
|
|
* queue = 34
|
|
* argc = 2
|
|
* argv[0] = "zap"
|
|
* argv[1] = "-x"
|
|
*
|
|
* Should the user enter unknown flags or leave out required arguments,
|
|
* the message:
|
|
*
|
|
* Usage: zap [-xz] [-q queue-id] [-f dump-file] user
|
|
*
|
|
* will be printed. This message can be printed by calling pusage(), or
|
|
* usage(). usage() will also cause program termination with exit code 1.
|
|
*
|
|
* Author: Stephen McKay, February 1991
|
|
*
|
|
* Based on recollection of the original options.h produced at the University
|
|
* of Queensland by Ross Patterson (and possibly others).
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
static char *O_usage;
|
|
static char *O_name;
|
|
extern long atol();
|
|
|
|
void
|
|
pusage()
|
|
{
|
|
/*
|
|
* Avoid gratuitously loading stdio.
|
|
*/
|
|
write(STDERR_FILENO, "Usage: ", 7);
|
|
write(STDERR_FILENO, O_name, strlen(O_name));
|
|
write(STDERR_FILENO, " ", 1);
|
|
write(STDERR_FILENO, O_usage, strlen(O_usage));
|
|
write(STDERR_FILENO, "\n", 1);
|
|
}
|
|
|
|
#define usage() (pusage(), exit(1))
|
|
|
|
#define OPTIONS(usage_msg) \
|
|
{ \
|
|
char O_cont; \
|
|
O_usage = (usage_msg); \
|
|
O_name = argv[0]; \
|
|
while (*++argv && **argv == '-') \
|
|
{ \
|
|
if ((*argv)[1] == '\0') \
|
|
break; \
|
|
argc--; \
|
|
if ((*argv)[1] == '-' && (*argv)[2] == '\0') \
|
|
{ \
|
|
argv++; \
|
|
break; \
|
|
} \
|
|
O_cont = 1; \
|
|
while (O_cont) \
|
|
switch (*++*argv) \
|
|
{ \
|
|
default: \
|
|
case '-': \
|
|
usage(); \
|
|
case '\0': \
|
|
O_cont = 0;
|
|
|
|
#define FLAG(x,flag) \
|
|
break; \
|
|
case (x): \
|
|
(flag) = 1;
|
|
|
|
#define CHAR(x,ch) \
|
|
break; \
|
|
case (x): \
|
|
O_cont = 0; \
|
|
if (*++*argv == '\0' && (--argc, *++argv == 0)) \
|
|
usage(); \
|
|
(ch) = **argv;
|
|
|
|
#define NUMBER(x,n) \
|
|
break; \
|
|
case (x): \
|
|
O_cont = 0; \
|
|
if (*++*argv == '\0' && (--argc, *++argv == 0)) \
|
|
usage(); \
|
|
(n) = atol(*argv);
|
|
|
|
#define STRING(x,str) \
|
|
break; \
|
|
case (x): \
|
|
O_cont = 0; \
|
|
if (*++*argv == '\0' && (--argc, *++argv == 0)) \
|
|
usage(); \
|
|
(str) = *argv;
|
|
|
|
#define SUFFIX(x,str) \
|
|
break; \
|
|
case (x): \
|
|
(str) = ++*argv; \
|
|
O_cont = 0;
|
|
|
|
#define ENDOPTS \
|
|
break; \
|
|
} \
|
|
} \
|
|
*--argv = O_name; \
|
|
}
|