diff options
author | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
commit | f08fdedcee12c06e3ce9ac9bec363915978e8289 (patch) | |
tree | d67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/getflags.c | |
parent | 5993a8f2756bc455101a8c9ce95347d5050e7883 (diff) | |
download | plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.gz plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.bz2 plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.zip |
Plan 9's rc.
not a clear win over byron's,
but at least it has the right syntax.
Diffstat (limited to 'src/cmd/rc/getflags.c')
-rw-r--r-- | src/cmd/rc/getflags.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/src/cmd/rc/getflags.c b/src/cmd/rc/getflags.c new file mode 100644 index 00000000..c452067f --- /dev/null +++ b/src/cmd/rc/getflags.c @@ -0,0 +1,217 @@ +/*% cyntax -DTEST % && cc -DTEST -go # % + */ +#include "rc.h" +#include "getflags.h" +#include "fns.h" +char *flagset[]={"<flag>"}; +char **flag[NFLAG]; +char cmdline[NCMDLINE+1]; +char *cmdname; +static char *flagarg=""; +static void reverse(char**, char**); +static int scanflag(int, char*); +static void errn(char*, int); +static void errs(char*); +static void errc(int); +static int reason; +#define RESET 1 +#define FEWARGS 2 +#define FLAGSYN 3 +#define BADFLAG 4 +static int badflag; +int getflags(int argc, char *argv[], char *flags, int stop) +{ + char *s, *t; + int i, j, c, count; + flagarg=flags; + if(cmdname==0) cmdname=argv[0]; + s=cmdline; + for(i=0;i!=argc;i++){ + for(t=argv[i];*t;t++) + if(s!=&cmdline[NCMDLINE]) + *s++=*t; + if(i!=argc-1 && s!=&cmdline[NCMDLINE]) + *s++=' '; + } + *s='\0'; + i=1; + while(i!=argc){ + if(argv[i][0]!='-' || argv[i][1]=='\0'){ + if(stop) return argc; + i++; + continue; + } + s=argv[i]+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-i<count){ + reason=FEWARGS; + badflag=c; + return -1; + } + reverse(argv+i, argv+argc); + reverse(argv+i, argv+argc-count); + reverse(argv+argc-count+1, argv+argc); + argc-=count; + flag[c]=argv+argc+1; + flag[c][0]=s; + s=""; + } + } + } + return argc; +} +static void reverse(char **p, char **q) +{ + char *t; + for(;p<q;p++,--q){ t=*p; *p=*q; *q=t; } +} +static int scanflag(int c, char *f) +{ + int fc, count; + if(0<=c && c<NFLAG) while(*f){ + if(*f==' '){ + f++; + continue; + } + fc=*f++; + if(*f==':'){ + f++; + if(*f<'0' || '9'<*f){ reason=FLAGSYN; return -1; } + count=0; + while('0'<=*f && *f<='9') count=count*10+*f++-'0'; + } + else + count=0; + if(*f=='['){ + do{ + f++; + if(*f=='\0'){ reason=FLAGSYN; return -1; } + }while(*f!=']'); + f++; + } + if(c==fc) return count; + } + reason=BADFLAG; + badflag=c; + return -1; +} +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 FEWARGS: + 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=0; + while('0'<=*s && *s<='9') count=count*10+*s++-'0'; + } + else count=0; + if(count==0){ + if(nflag==0) errs(" [-"); + nflag++; + errc(c); + } + if(*s=='['){ + s++; + while(*s!=']' && *s!='\0') s++; + if(*s==']') s++; + } + } + if(nflag) errs("]"); + for(s=flagarg;*s;){ + c=*s; + if(*s++==' ') continue; + if(*s==':'){ + s++; + count=0; + while('0'<=*s && *s<='9') count=count*10+*s++-'0'; + } + else count=0; + if(count!=0){ + errs(" [-"); + errc(c); + if(*s=='['){ + s++; + t=s; + while(*s!=']' && *s!='\0') s++; + errs(" "); + errn(t, s-t); + if(*s==']') s++; + } + else + while(count--) errs(" arg"); + errs("]"); + } + else if(*s=='['){ + s++; + while(*s!=']' && *s!='\0') s++; + if(*s==']') s++; + } + } + if(tail){ + errs(" "); + errs(tail); + } + errs("\n"); + Exit("bad flags"); +} +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; + } +} |