]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.sbin/ctm/ctm_rmail/options.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.sbin / ctm / ctm_rmail / options.h
1 /*
2  * Macros for processing command arguments.
3  *
4  * Conforms closely to the command option requirements of intro(1) in System V
5  * and intro(C) in Xenix.
6  *
7  * A command consists of: cmdname [ options ] [ cmdarguments ]
8  *
9  * Options consist of a leading dash '-' and a flag letter.  An argument may
10  * follow optionally preceded by white space.
11  * Options without arguments may be grouped behind a single dash.
12  * A dash on its own is interpreted as the end of the options and is retained
13  * as a command argument.
14  * A double dash '--' is interpreted as the end of the options and is discarded.
15  *
16  * For example:
17  *      zap -xz -f flame -q34 -- -x
18  *
19  * where zap.c contains the following in main():
20  *
21  *      OPTIONS("[-xz] [-q queue-id] [-f dump-file] user")
22  *          FLAG('x', xecute)
23  *          FLAG('z', zot)
24  *          STRING('f', file)
25  *              fp = fopen(file, "w");
26  *          NUMBER('q', queue)
27  *          ENDOPTS
28  *
29  * Results in:
30  *      xecute = 1
31  *      zot = 1
32  *      file = "flame"
33  *      fp = fopen("flame", "w")
34  *      queue = 34
35  *      argc = 2
36  *      argv[0] = "zap"
37  *      argv[1] = "-x"
38  *
39  * Should the user enter unknown flags or leave out required arguments,
40  * the message:
41  *
42  *      Usage: zap [-xz] [-q queue-id] [-f dump-file] user
43  *
44  * will be printed.  This message can be printed by calling pusage(), or
45  * usage().  usage() will also cause program termination with exit code 1.
46  *
47  * Author: Stephen McKay, February 1991
48  *
49  * Based on recollection of the original options.h produced at the University
50  * of Queensland by Ross Patterson (and possibly others).
51  *
52  * $FreeBSD$
53  */
54
55 static char *O_usage;
56 static char *O_name;
57 extern long atol();
58
59 void
60 pusage()
61     {
62     /*
63      * Avoid gratuitously loading stdio.
64      */
65     write(STDERR_FILENO, "usage: ", 7);
66     write(STDERR_FILENO, O_name, strlen(O_name));
67     write(STDERR_FILENO, " ", 1);
68     write(STDERR_FILENO, O_usage, strlen(O_usage));
69     write(STDERR_FILENO, "\n", 1);
70     }
71
72 #define usage()         (pusage(), exit(1))
73
74 #define OPTIONS(usage_msg)              \
75     {                                   \
76     char O_cont;                        \
77     O_usage = (usage_msg);              \
78     O_name = argv[0];                   \
79     while (*++argv && **argv == '-')    \
80         {                               \
81         if ((*argv)[1] == '\0')         \
82             break;                      \
83         argc--;                         \
84         if ((*argv)[1] == '-' && (*argv)[2] == '\0') \
85             {                           \
86             argv++;                     \
87             break;                      \
88             }                           \
89         O_cont = 1;                     \
90         while (O_cont)                  \
91             switch (*++*argv)           \
92                 {                       \
93                 default:                \
94                 case '-':               \
95                     usage();            \
96                 case '\0':              \
97                     O_cont = 0;
98
99 #define FLAG(x,flag)                    \
100                     break;              \
101                 case (x):               \
102                     (flag) = 1;
103
104 #define CHAR(x,ch)                      \
105                     break;              \
106                 case (x):               \
107                     O_cont = 0;         \
108                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
109                         usage();        \
110                     (ch) = **argv;
111
112 #define NUMBER(x,n)                     \
113                     break;              \
114                 case (x):               \
115                     O_cont = 0;         \
116                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
117                         usage();        \
118                     (n) = atol(*argv);
119
120 #define STRING(x,str)                   \
121                     break;              \
122                 case (x):               \
123                     O_cont = 0;         \
124                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
125                         usage();        \
126                     (str) = *argv;
127
128 #define SUFFIX(x,str)                   \
129                     break;              \
130                 case (x):               \
131                     (str) = ++*argv;    \
132                     O_cont = 0;
133
134 #define ENDOPTS                         \
135                     break;              \
136                 }                       \
137         }                               \
138     *--argv = O_name;                   \
139     }