|
|
1.1 root 1: /*% cyntax -DTEST % && cc -DTEST -go # %
2: */
3: #include <libc.h>
4: #include <getflags.h>
5: char **flag[NFLAG];
6: char cmdline[NCMDLINE+1];
7: char *cmdname;
8: char *flagset[];
9: char *flagset[]={"<flag>"};
10: static char *flagarg="";
11: static reverse(), scanflag();
12: static int reason;
13: #define RESET 1
14: #define ARGC 2
15: #define FLAGSYN 3
16: #define BADFLAG 4
17: static int badflag;
18: char *getflagsargv[NGETFLAGSARGV+2]; /* original argv stored here for people who need it */
19: getflags(argc, argv, flags)
20: char *argv[], *flags;
21: {
22: register char *s, *t;
23: register i, j, c, count;
24: flagarg=flags;
25: if(cmdname==0){
26: cmdname=argv[0];
27: for(i=0;i!=argc && i!=NGETFLAGSARGV;i++) getflagsargv[i]=argv[i];
28: if(argc>NGETFLAGSARGV) getflagsargv[i++]="...";
29: getflagsargv[i]=0;
30: }
31: s=cmdline;
32: for(i=0;i!=argc;i++){
33: for(t=argv[i];*t;)
34: if(s!=&cmdline[NCMDLINE])
35: *s++=*t++;
36: if(i!=argc-1 && s!=&cmdline[NCMDLINE])
37: *s++=' ';
38: }
39: *s='\0';
40: i=1;
41: while(i!=argc && argv[i][0]=='-'){
42: s=argv[i]+1;
43: if(*s=='\0'){ /* if argument is "-", stop scanning and delete it */
44: for(j=i+1;j<=argc;j++)
45: argv[j-1]=argv[j];
46: return argc-1;
47: }
48: while(*s){
49: c=*s++;
50: count=scanflag(c, flags);
51: if(count==-1) return -1;
52: if(flag[c]){ reason=RESET; badflag=c; return -1; }
53: if(count==0){
54: flag[c]=flagset;
55: if(*s=='\0'){
56: for(j=i+1;j<=argc;j++)
57: argv[j-1]=argv[j];
58: --argc;
59: }
60: }
61: else{
62: if(*s=='\0'){
63: for(j=i+1;j<=argc;j++)
64: argv[j-1]=argv[j];
65: --argc;
66: s=argv[i];
67: }
68: if(argc-i<count){
69: reason=ARGC;
70: badflag=c;
71: return -1;
72: }
73: reverse(argv+i, argv+argc);
74: reverse(argv+i, argv+argc-count);
75: reverse(argv+argc-count+1, argv+argc);
76: argc-=count;
77: flag[c]=argv+argc+1;
78: flag[c][0]=s;
79: s="";
80: }
81: }
82: }
83: return argc;
84: }
85: static reverse(p, q)
86: register char **p, **q;
87: {
88: register char *t;
89: for(;p<q;p++,--q){ t=*p; *p=*q; *q=t; }
90: }
91: static scanflag(c, f)
92: register char *f;
93: {
94: register fc, count;
95: if(0<=c && c<NFLAG) while(*f){
96: if(*f==' '){
97: f++;
98: continue;
99: }
100: fc=*f++;
101: if(*f==':'){
102: f++;
103: if(*f<'0' || '9'<*f){ reason=FLAGSYN; return -1; }
104: count=0;
105: while('0'<=*f && *f<='9') count=count*10+*f++-'0';
106: }
107: else
108: count=0;
109: if(*f=='['){
110: do{
111: f++;
112: if(*f=='\0'){ reason=FLAGSYN; return -1; }
113: }while(*f!=']');
114: f++;
115: }
116: if(c==fc) return count;
117: }
118: reason=BADFLAG;
119: badflag=c;
120: return -1;
121: }
122: static errn(), errs(), errc();
123: usage(tail)
124: char *tail;
125: {
126: register char *s, *t, c;
127: register count, nflag=0;
128: switch(reason){
129: case RESET:
130: errs("Flag -");
131: errc(badflag);
132: errs(": set twice\n");
133: break;
134: case ARGC:
135: errs("Flag -");
136: errc(badflag);
137: errs(": too few arguments\n");
138: break;
139: case FLAGSYN:
140: errs("Bad argument to getflags!\n");
141: break;
142: case BADFLAG:
143: errs("Illegal flag -");
144: errc(badflag);
145: errc('\n');
146: break;
147: }
148: errs("Usage: ");
149: errs(cmdname);
150: for(s=flagarg;*s;){
151: c=*s;
152: if(*s++==' ') continue;
153: if(*s==':'){
154: s++;
155: count=0;
156: while('0'<=*s && *s<='9') count=count*10+*s++-'0';
157: }
158: else count=0;
159: if(count==0){
160: if(nflag==0) errs(" [-");
161: nflag++;
162: errc(c);
163: }
164: if(*s=='['){
165: s++;
166: while(*s!=']' && *s!='\0') s++;
167: if(*s==']') s++;
168: }
169: }
170: if(nflag) errs("]");
171: for(s=flagarg;*s;){
172: c=*s;
173: if(*s++==' ') 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==']') s++;
190: }
191: else
192: while(count--) errs(" arg");
193: errs("]");
194: }
195: else if(*s=='['){
196: s++;
197: while(*s!=']' && *s!='\0') s++;
198: if(*s==']') s++;
199: }
200: }
201: if(tail){
202: errs(" ");
203: errs(tail);
204: }
205: errs("\n");
206: exit(1);
207: }
208: static errn(s, count)
209: register char *s;
210: register count;
211: {
212: while(count){ errc(*s++); --count; }
213: }
214: static errs(s)
215: register char *s;
216: {
217: while(*s) errc(*s++);
218: }
219: #define NBUF 80
220: static char buf[NBUF], *bufp=buf;
221: static errc(c){
222: *bufp++=c;
223: if(bufp==&buf[NBUF] || c=='\n'){
224: write(2, buf, bufp-buf);
225: bufp=buf;
226: }
227: }
228: #ifdef TEST
229: #include <stdio.h>
230: main(argc, argv)
231: char *argv[];
232: {
233: int c, i, n;
234: if(argc<3){
235: fprintf(stderr, "Usage: %s flags cmd ...\n", argv[0]);
236: exit(1);
237: }
238: n=getflags(argc-2, argv+2, argv[1], 0);
239: if(n<0) usage("...");
240: for(i=0;i!=n;i++) printf("%s ", argv[2+i]);
241: putchar('\n');
242: for(c=0;c!=128;c++) if(flag[c]){
243: printf("\t-%c", c);
244: n=scanflag(c, argv[1]);
245: for(i=0;i!=n;i++) printf(" %s", flag[c][i]);
246: putchar('\n');
247: }
248: }
249: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.