#include #include #include #include "getflags.h" char **flag[NFLAG]; char cmdline[NCMDLINE+1]; char *cmdname; char *flagset[]; char *flagset[]={""}; static char *flagarg=""; static void reverse(char **, char **); static int scanflag(int, char *); static int reason; #define RESET 1 #define ARGCCOUNT 2 #define FLAGSYN 3 #define BADFLAG 4 static int badflag; char *getflagsargv[NGETFLAGSARGV+2]; /* original argv stored here for people who need it */ int getflags(int argc, char *argv[], char *flags) { char *s, *t; int i, j, c, count; flagarg=flags; if(cmdname==0){ cmdname=argv[0]; for(i=0;i!=argc && i!=NGETFLAGSARGV;i++) getflagsargv[i]=argv[i]; if(argc>NGETFLAGSARGV) getflagsargv[i++]="..."; getflagsargv[i]=0; } s=cmdline; for(i=0;i!=argc;i++){ for(t=argv[i];*t;) if(s!=&cmdline[NCMDLINE]) *s++=*t++; else break; if(i!=argc-1 && s!=&cmdline[NCMDLINE]) *s++=' '; } *s='\0'; i=1; while(i!=argc && argv[i][0]=='-'){ s=argv[i]+1; if(*s=='\0'){ /* if argument is "-", stop scanning and delete it */ for(j=i+1;j<=argc;j++) argv[j-1]=argv[j]; return argc-1; } while(*s){ c=*s++; count=scanflag(c, flags); if(count==-1) return -1; if(flag[c]){ reason=RESET; badflag=c; return -1; } if(count==0){ flag[c]=flagset; if(*s=='\0'){ for(j=i+1;j<=argc;j++) argv[j-1]=argv[j]; --argc; } } else{ if(*s=='\0'){ for(j=i+1;j<=argc;j++) argv[j-1]=argv[j]; --argc; s=argv[i]; } if(argc-i0); f++; } if(c==fc) return count; } reason=BADFLAG; badflag=c; return -1; } static void errn(char *, int), errs(char *), errc(int); void usage(char *tail) { char *s, *t, c; int count, nflag=0; switch(reason){ case RESET: errs("Flag -"); errc(badflag); errs(": set twice\n"); break; case ARGCCOUNT: errs("Flag -"); errc(badflag); errs(": too few arguments\n"); break; case FLAGSYN: errs("Bad argument to getflags!\n"); break; case BADFLAG: errs("Illegal flag -"); errc(badflag); errc('\n'); break; } errs("Usage: "); errs(cmdname); for(s=flagarg;*s;){ c=*s; if(*s++==' ') continue; if(*s==':'){ s++; count=strtol(s, &s, 10); } else count=0; if(count==0){ if(nflag==0) errs(" [-"); nflag++; errc(c); } if(*s=='['){ int depth=1; s++; for(;*s!='\0' && depth>0; s++) if (*s==']') depth--; else if (*s=='[') depth++; } } if(nflag) errs("]"); for(s=flagarg;*s;){ c=*s; if(*s++==' ') continue; if(*s==':'){ s++; count=strtol(s, &s, 10); } else count=0; if(count!=0){ errs(" [-"); errc(c); if(*s=='['){ int depth=1; s++; t=s; for(;*s!='\0' && depth>0; s++) if (*s==']') depth--; else if (*s=='[') depth++; errs(" "); errn(t, s-t); } else while(count--) errs(" arg"); errs("]"); } else if(*s=='['){ int depth=1; s++; for(;*s!='\0' && depth>0; s++) if (*s==']') depth--; else if (*s=='[') depth++; } } if(tail){ errs(" "); errs(tail); } errs("\n"); exits("usage"); } static void errn(char *s, int count) { while(count){ errc(*s++); --count; } } static void errs(char *s) { while(*s) errc(*s++); } #define NBUF 80 static char buf[NBUF], *bufp=buf; static void errc(int c){ *bufp++=c; if(bufp==&buf[NBUF] || c=='\n'){ write(2, buf, bufp-buf); bufp=buf; } } #ifdef TEST #include main(int argc, char *argv[]) { int c, i, n; if(argc<3){ fprint(2, "Usage: %s flags cmd ...\n", argv[0]); exits("usage"); } n=getflags(argc-2, argv+2, argv[1]); if(n<0) usage("..."); putchar('\n'); for(c=0;c!=128;c++) if(flag[c]){ print("\t-.%c. ", c); n=scanflag(c, argv[1]); for(i=0;i!=n;i++) print(" <%s>", flag[c][i]); putchar('\n'); } } #endif