|
|
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.