1 #include "rc.h" 2 #include "getflags.h" 3 #include "fns.h" 4 char *flagset[] = {"<flag>"}; 5 char **flag[NFLAG]; 6 char *cmdname; 7 static char *flagarg=""; 8 static void reverse(char**, char**); 9 static int scanflag(int, char*); 10 static void errn(char*, int); 11 static void errs(char*); 12 static void errc(int); 13 static int reason; 14 #define RESET 1 15 #define FEWARGS 2 16 #define FLAGSYN 3 17 #define BADFLAG 4 18 static int badflag; 19 20 int 21 getflags(int argc, char *argv[], char *flags, int stop) 22 { 23 char *s; 24 int i, j, c, count; 25 flagarg = flags; 26 if(cmdname==0) 27 cmdname = argv[0]; 28 29 i = 1; 30 while(i!=argc){ 31 if(argv[i][0] != '-' || argv[i][1] == '\0'){ 32 if(stop) /* always true in rc */ 33 return argc; 34 i++; 35 continue; 36 } 37 s = argv[i]+1; 38 while(*s){ 39 c=*s++; 40 count = scanflag(c, flags); 41 if(count==-1) 42 return -1; 43 if(flag[c]){ reason = RESET; badflag = c; return -1; } 44 if(count==0){ 45 flag[c] = flagset; 46 if(*s=='\0'){ 47 for(j = i+1;j<=argc;j++) 48 argv[j-1] = argv[j]; 49 --argc; 50 } 51 } 52 else{ 53 if(*s=='\0'){ 54 for(j = i+1;j<=argc;j++) 55 argv[j-1] = argv[j]; 56 --argc; 57 s = argv[i]; 58 } 59 if(argc-i<count){ 60 reason = FEWARGS; 61 badflag = c; 62 return -1; 63 } 64 reverse(argv+i, argv+argc); 65 reverse(argv+i, argv+argc-count); 66 reverse(argv+argc-count+1, argv+argc); 67 argc-=count; 68 flag[c] = argv+argc+1; 69 flag[c][0] = s; 70 s=""; 71 } 72 } 73 } 74 return argc; 75 } 76 77 static void 78 reverse(char **p, char **q) 79 { 80 char *t; 81 for(;p<q;p++,--q){ t=*p; *p=*q; *q = t; } 82 } 83 84 static int 85 scanflag(int c, char *f) 86 { 87 int fc, count; 88 if(0<=c && c<NFLAG) 89 while(*f){ 90 if(*f==' '){ 91 f++; 92 continue; 93 } 94 fc=*f++; 95 if(*f==':'){ 96 f++; 97 if(*f<'0' || '9'<*f){ reason = FLAGSYN; return -1; } 98 count = 0; 99 while('0'<=*f && *f<='9') count = count*10+*f++-'0'; 100 } 101 else 102 count = 0; 103 if(*f=='['){ 104 do{ 105 f++; 106 if(*f=='\0'){ reason = FLAGSYN; return -1; } 107 }while(*f!=']'); 108 f++; 109 } 110 if(c==fc) 111 return count; 112 } 113 reason = BADFLAG; 114 badflag = c; 115 return -1; 116 } 117 118 void 119 usage(char *tail) 120 { 121 char *s, *t, c; 122 int count, nflag = 0; 123 switch(reason){ 124 case RESET: 125 errs("Flag -"); 126 errc(badflag); 127 errs(": set twice\n"); 128 break; 129 case FEWARGS: 130 errs("Flag -"); 131 errc(badflag); 132 errs(": too few arguments\n"); 133 break; 134 case FLAGSYN: 135 errs("Bad argument to getflags!\n"); 136 break; 137 case BADFLAG: 138 errs("Illegal flag -"); 139 errc(badflag); 140 errc('\n'); 141 break; 142 } 143 errs("Usage: "); 144 errs(cmdname); 145 for(s = flagarg;*s;){ 146 c=*s; 147 if(*s++==' ') 148 continue; 149 if(*s==':'){ 150 s++; 151 count = 0; 152 while('0'<=*s && *s<='9') count = count*10+*s++-'0'; 153 } 154 else count = 0; 155 if(count==0){ 156 if(nflag==0) 157 errs(" [-"); 158 nflag++; 159 errc(c); 160 } 161 if(*s=='['){ 162 s++; 163 while(*s!=']' && *s!='\0') s++; 164 if(*s==']') 165 s++; 166 } 167 } 168 if(nflag) 169 errs("]"); 170 for(s = flagarg;*s;){ 171 c=*s; 172 if(*s++==' ') 173 continue; 174 if(*s==':'){ 175 s++; 176 count = 0; 177 while('0'<=*s && *s<='9') count = count*10+*s++-'0'; 178 } 179 else count = 0; 180 if(count!=0){ 181 errs(" [-"); 182 errc(c); 183 if(*s=='['){ 184 s++; 185 t = s; 186 while(*s!=']' && *s!='\0') s++; 187 errs(" "); 188 errn(t, s-t); 189 if(*s==']') 190 s++; 191 } 192 else 193 while(count--) errs(" arg"); 194 errs("]"); 195 } 196 else if(*s=='['){ 197 s++; 198 while(*s!=']' && *s!='\0') s++; 199 if(*s==']') 200 s++; 201 } 202 } 203 if(tail){ 204 errs(" "); 205 errs(tail); 206 } 207 errs("\n"); 208 Exit("bad flags"); 209 } 210 211 static void 212 errn(char *s, int count) 213 { 214 while(count){ errc(*s++); --count; } 215 } 216 217 static void 218 errs(char *s) 219 { 220 while(*s) errc(*s++); 221 } 222 #define NBUF 80 223 static char buf[NBUF], *bufp = buf; 224 225 static void 226 errc(int c) 227 { 228 *bufp++=c; 229 if(bufp==&buf[NBUF] || c=='\n'){ 230 Write(2, buf, bufp-buf); 231 bufp = buf; 232 } 233 } 234