From acd47706189b842db4894473168a4dded897e245 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 10 Aug 2005 18:00:38 +0000 Subject: new --- src/cmd/getflags/funcgetflags.c | 267 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 src/cmd/getflags/funcgetflags.c (limited to 'src/cmd/getflags/funcgetflags.c') diff --git a/src/cmd/getflags/funcgetflags.c b/src/cmd/getflags/funcgetflags.c new file mode 100644 index 00000000..a88e99f2 --- /dev/null +++ b/src/cmd/getflags/funcgetflags.c @@ -0,0 +1,267 @@ +#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 -- cgit v1.2.3