Annotation of researchv10no/libc/gen/getflags.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.