Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.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
53 static char *O_usage;
54 static char *O_name;
55 extern long atol();
56
57 void
58 pusage()
59     {
60     /*
61      * Avoid gratuitously loading stdio.
62      */
63     write(2, "Usage: ", 7);
64     write(2, O_name, strlen(O_name));
65     write(2, " ", 1);
66     write(2, O_usage, strlen(O_usage));
67     write(2, "\n", 1);
68     }
69
70 #define usage()         (pusage(), exit(1))
71
72 #define OPTIONS(usage_msg)              \
73     {                                   \
74     char O_cont;                        \
75     O_usage = (usage_msg);              \
76     O_name = argv[0];                   \
77     while (*++argv && **argv == '-')    \
78         {                               \
79         if ((*argv)[1] == '\0')         \
80             break;                      \
81         argc--;                         \
82         if ((*argv)[1] == '-' && (*argv)[2] == '\0') \
83             {                           \
84             argv++;                     \
85             break;                      \
86             }                           \
87         O_cont = 1;                     \
88         while (O_cont)                  \
89             switch (*++*argv)           \
90                 {                       \
91                 default:                \
92                 case '-':               \
93                     usage();            \
94                 case '\0':              \
95                     O_cont = 0;
96
97 #define FLAG(x,flag)                    \
98                     break;              \
99                 case (x):               \
100                     (flag) = 1;
101
102 #define CHAR(x,ch)                      \
103                     break;              \
104                 case (x):               \
105                     O_cont = 0;         \
106                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
107                         usage();        \
108                     (ch) = **argv;
109
110 #define NUMBER(x,n)                     \
111                     break;              \
112                 case (x):               \
113                     O_cont = 0;         \
114                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
115                         usage();        \
116                     (n) = atol(*argv);
117
118 #define STRING(x,str)                   \
119                     break;              \
120                 case (x):               \
121                     O_cont = 0;         \
122                     if (*++*argv == '\0' && (--argc, *++argv == 0)) \
123                         usage();        \
124                     (str) = *argv;
125
126 #define SUFFIX(x,str)                   \
127                     break;              \
128                 case (x):               \
129                     (str) = ++*argv;    \
130                     O_cont = 0;
131
132 #define ENDOPTS                         \
133                     break;              \
134                 }                       \
135         }                               \
136     *--argv = O_name;                   \
137     }