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