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 53static char *O_usage; 54static char *O_name; 55extern long atol(); 56 57void 58pusage() 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 case '-': \ 92 usage(); \ 93 case '\0': \ 94 O_cont = 0; 95 96#define FLAG(x,flag) \ 97 break; \ 98 case (x): \ 99 (flag) = 1; 100 101#define CHAR(x,ch) \ 102 break; \ 103 case (x): \ 104 O_cont = 0; \ 105 if (*++*argv == '\0' && (--argc, *++argv == 0)) \ 106 usage(); \ 107 (ch) = **argv; 108 109#define NUMBER(x,n) \ 110 break; \ 111 case (x): \ 112 O_cont = 0; \ 113 if (*++*argv == '\0' && (--argc, *++argv == 0)) \ 114 usage(); \ 115 (n) = atol(*argv); 116 117#define STRING(x,str) \ 118 break; \ 119 case (x): \ 120 O_cont = 0; \ 121 if (*++*argv == '\0' && (--argc, *++argv == 0)) \ 122 usage(); \ 123 (str) = *argv; 124 125#define SUFFIX(x,str) \ 126 break; \ 127 case (x): \ 128 (str) = ++*argv; \ 129 O_cont = 0; 130 131#define ENDOPTS \ 132 break; \ 133 default: \ 134 usage(); \ 135 } \ 136 } \ |
137 *--argv = O_name; \ 138 } |