1 f08fdedc 2003-11-23 devnull /*% cyntax -DTEST % && cc -DTEST -go # %
3 f08fdedc 2003-11-23 devnull #include "rc.h"
4 f08fdedc 2003-11-23 devnull #include "getflags.h"
5 f08fdedc 2003-11-23 devnull #include "fns.h"
6 f08fdedc 2003-11-23 devnull char *flagset[]={"<flag>"};
7 f08fdedc 2003-11-23 devnull char **flag[NFLAG];
8 f08fdedc 2003-11-23 devnull char cmdline[NCMDLINE+1];
9 f08fdedc 2003-11-23 devnull char *cmdname;
10 f08fdedc 2003-11-23 devnull static char *flagarg="";
11 f08fdedc 2003-11-23 devnull static void reverse(char**, char**);
12 f08fdedc 2003-11-23 devnull static int scanflag(int, char*);
13 f08fdedc 2003-11-23 devnull static void errn(char*, int);
14 f08fdedc 2003-11-23 devnull static void errs(char*);
15 f08fdedc 2003-11-23 devnull static void errc(int);
16 f08fdedc 2003-11-23 devnull static int reason;
17 f08fdedc 2003-11-23 devnull #define RESET 1
18 f08fdedc 2003-11-23 devnull #define FEWARGS 2
19 f08fdedc 2003-11-23 devnull #define FLAGSYN 3
20 f08fdedc 2003-11-23 devnull #define BADFLAG 4
21 f08fdedc 2003-11-23 devnull static int badflag;
22 f08fdedc 2003-11-23 devnull int getflags(int argc, char *argv[], char *flags, int stop)
24 f08fdedc 2003-11-23 devnull char *s, *t;
25 f08fdedc 2003-11-23 devnull int i, j, c, count;
26 f08fdedc 2003-11-23 devnull flagarg=flags;
27 f08fdedc 2003-11-23 devnull if(cmdname==0) cmdname=argv[0];
28 f08fdedc 2003-11-23 devnull s=cmdline;
29 f08fdedc 2003-11-23 devnull for(i=0;i!=argc;i++){
30 f08fdedc 2003-11-23 devnull for(t=argv[i];*t;t++)
31 f08fdedc 2003-11-23 devnull if(s!=&cmdline[NCMDLINE])
33 f08fdedc 2003-11-23 devnull if(i!=argc-1 && s!=&cmdline[NCMDLINE])
34 f08fdedc 2003-11-23 devnull *s++=' ';
38 f08fdedc 2003-11-23 devnull while(i!=argc){
39 f08fdedc 2003-11-23 devnull if(argv[i][0]!='-' || argv[i][1]=='\0'){
40 f08fdedc 2003-11-23 devnull if(stop) return argc;
42 f08fdedc 2003-11-23 devnull continue;
44 f08fdedc 2003-11-23 devnull s=argv[i]+1;
45 f08fdedc 2003-11-23 devnull while(*s){
47 f08fdedc 2003-11-23 devnull count=scanflag(c, flags);
48 f08fdedc 2003-11-23 devnull if(count==-1) return -1;
49 f08fdedc 2003-11-23 devnull if(flag[c]){ reason=RESET; badflag=c; return -1; }
50 f08fdedc 2003-11-23 devnull if(count==0){
51 f08fdedc 2003-11-23 devnull flag[c]=flagset;
52 f08fdedc 2003-11-23 devnull if(*s=='\0'){
53 f08fdedc 2003-11-23 devnull for(j=i+1;j<=argc;j++)
54 f08fdedc 2003-11-23 devnull argv[j-1]=argv[j];
59 f08fdedc 2003-11-23 devnull if(*s=='\0'){
60 f08fdedc 2003-11-23 devnull for(j=i+1;j<=argc;j++)
61 f08fdedc 2003-11-23 devnull argv[j-1]=argv[j];
63 f08fdedc 2003-11-23 devnull s=argv[i];
65 f08fdedc 2003-11-23 devnull if(argc-i<count){
66 f08fdedc 2003-11-23 devnull reason=FEWARGS;
67 f08fdedc 2003-11-23 devnull badflag=c;
68 f08fdedc 2003-11-23 devnull return -1;
70 f08fdedc 2003-11-23 devnull reverse(argv+i, argv+argc);
71 f08fdedc 2003-11-23 devnull reverse(argv+i, argv+argc-count);
72 f08fdedc 2003-11-23 devnull reverse(argv+argc-count+1, argv+argc);
73 f08fdedc 2003-11-23 devnull argc-=count;
74 f08fdedc 2003-11-23 devnull flag[c]=argv+argc+1;
75 f08fdedc 2003-11-23 devnull flag[c][0]=s;
80 f08fdedc 2003-11-23 devnull return argc;
82 f08fdedc 2003-11-23 devnull static void reverse(char **p, char **q)
85 f08fdedc 2003-11-23 devnull for(;p<q;p++,--q){ t=*p; *p=*q; *q=t; }
87 f08fdedc 2003-11-23 devnull static int scanflag(int c, char *f)
89 f08fdedc 2003-11-23 devnull int fc, count;
90 f08fdedc 2003-11-23 devnull if(0<=c && c<NFLAG) while(*f){
91 f08fdedc 2003-11-23 devnull if(*f==' '){
93 f08fdedc 2003-11-23 devnull continue;
96 f08fdedc 2003-11-23 devnull if(*f==':'){
98 f08fdedc 2003-11-23 devnull if(*f<'0' || '9'<*f){ reason=FLAGSYN; return -1; }
100 f08fdedc 2003-11-23 devnull while('0'<=*f && *f<='9') count=count*10+*f++-'0';
103 f08fdedc 2003-11-23 devnull count=0;
104 f08fdedc 2003-11-23 devnull if(*f=='['){
107 f08fdedc 2003-11-23 devnull if(*f=='\0'){ reason=FLAGSYN; return -1; }
108 f08fdedc 2003-11-23 devnull }while(*f!=']');
111 f08fdedc 2003-11-23 devnull if(c==fc) return count;
113 f08fdedc 2003-11-23 devnull reason=BADFLAG;
114 f08fdedc 2003-11-23 devnull badflag=c;
115 f08fdedc 2003-11-23 devnull return -1;
117 f08fdedc 2003-11-23 devnull void usage(char *tail)
119 f08fdedc 2003-11-23 devnull char *s, *t, c;
120 f08fdedc 2003-11-23 devnull int count, nflag=0;
121 f08fdedc 2003-11-23 devnull switch(reason){
122 f08fdedc 2003-11-23 devnull case RESET:
123 f08fdedc 2003-11-23 devnull errs("Flag -");
124 f08fdedc 2003-11-23 devnull errc(badflag);
125 f08fdedc 2003-11-23 devnull errs(": set twice\n");
127 f08fdedc 2003-11-23 devnull case FEWARGS:
128 f08fdedc 2003-11-23 devnull errs("Flag -");
129 f08fdedc 2003-11-23 devnull errc(badflag);
130 f08fdedc 2003-11-23 devnull errs(": too few arguments\n");
132 f08fdedc 2003-11-23 devnull case FLAGSYN:
133 f08fdedc 2003-11-23 devnull errs("Bad argument to getflags!\n");
135 f08fdedc 2003-11-23 devnull case BADFLAG:
136 f08fdedc 2003-11-23 devnull errs("Illegal flag -");
137 f08fdedc 2003-11-23 devnull errc(badflag);
138 f08fdedc 2003-11-23 devnull errc('\n');
141 f08fdedc 2003-11-23 devnull errs("Usage: ");
142 f08fdedc 2003-11-23 devnull errs(cmdname);
143 f08fdedc 2003-11-23 devnull for(s=flagarg;*s;){
145 f08fdedc 2003-11-23 devnull if(*s++==' ') continue;
146 f08fdedc 2003-11-23 devnull if(*s==':'){
148 f08fdedc 2003-11-23 devnull count=0;
149 f08fdedc 2003-11-23 devnull while('0'<=*s && *s<='9') count=count*10+*s++-'0';
151 f08fdedc 2003-11-23 devnull else count=0;
152 f08fdedc 2003-11-23 devnull if(count==0){
153 f08fdedc 2003-11-23 devnull if(nflag==0) errs(" [-");
154 f08fdedc 2003-11-23 devnull nflag++;
155 f08fdedc 2003-11-23 devnull errc(c);
157 f08fdedc 2003-11-23 devnull if(*s=='['){
159 f08fdedc 2003-11-23 devnull while(*s!=']' && *s!='\0') s++;
160 f08fdedc 2003-11-23 devnull if(*s==']') s++;
163 f08fdedc 2003-11-23 devnull if(nflag) errs("]");
164 f08fdedc 2003-11-23 devnull for(s=flagarg;*s;){
166 f08fdedc 2003-11-23 devnull if(*s++==' ') continue;
167 f08fdedc 2003-11-23 devnull if(*s==':'){
169 f08fdedc 2003-11-23 devnull count=0;
170 f08fdedc 2003-11-23 devnull while('0'<=*s && *s<='9') count=count*10+*s++-'0';
172 f08fdedc 2003-11-23 devnull else count=0;
173 f08fdedc 2003-11-23 devnull if(count!=0){
174 f08fdedc 2003-11-23 devnull errs(" [-");
175 f08fdedc 2003-11-23 devnull errc(c);
176 f08fdedc 2003-11-23 devnull if(*s=='['){
179 f08fdedc 2003-11-23 devnull while(*s!=']' && *s!='\0') s++;
180 f08fdedc 2003-11-23 devnull errs(" ");
181 f08fdedc 2003-11-23 devnull errn(t, s-t);
182 f08fdedc 2003-11-23 devnull if(*s==']') s++;
185 f08fdedc 2003-11-23 devnull while(count--) errs(" arg");
186 f08fdedc 2003-11-23 devnull errs("]");
188 f08fdedc 2003-11-23 devnull else if(*s=='['){
190 f08fdedc 2003-11-23 devnull while(*s!=']' && *s!='\0') s++;
191 f08fdedc 2003-11-23 devnull if(*s==']') s++;
194 f08fdedc 2003-11-23 devnull if(tail){
195 f08fdedc 2003-11-23 devnull errs(" ");
196 f08fdedc 2003-11-23 devnull errs(tail);
198 f08fdedc 2003-11-23 devnull errs("\n");
199 f08fdedc 2003-11-23 devnull Exit("bad flags");
201 f08fdedc 2003-11-23 devnull static void errn(char *s, int count)
203 f08fdedc 2003-11-23 devnull while(count){ errc(*s++); --count; }
205 f08fdedc 2003-11-23 devnull static void errs(char *s)
207 f08fdedc 2003-11-23 devnull while(*s) errc(*s++);
209 f08fdedc 2003-11-23 devnull #define NBUF 80
210 f08fdedc 2003-11-23 devnull static char buf[NBUF], *bufp=buf;
211 f08fdedc 2003-11-23 devnull static void errc(int c){
212 f08fdedc 2003-11-23 devnull *bufp++=c;
213 f08fdedc 2003-11-23 devnull if(bufp==&buf[NBUF] || c=='\n'){
214 f08fdedc 2003-11-23 devnull Write(2, buf, bufp-buf);
215 f08fdedc 2003-11-23 devnull bufp=buf;