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