| /*% cyntax % && cc -go # % |
| * getflags: process flags for command files |
| * Usage: ifs='' eval `{getflags [-s] flagfmt [arg ...]} # rc |
| * Usage: IFS= eval `getflags -b [-s] flagfmt [arg...]` # Bourne shell |
| * -b means give Bourne-shell compatible output |
| */ |
| #include <u.h> |
| #include <libc.h> |
| #include "getflags.h" |
| |
| /* predefine functions */ |
| void bourneprint(int, char *[]); |
| void bournearg(char *); |
| void rcprint(int, char *[]); |
| void usmsg(char *); |
| int count(int, char *); |
| void rcarg(char *); |
| |
| void |
| main(int argc, char *argv[]) |
| { |
| int bourne; |
| argc=getflags(argc, argv, "b"); |
| if(argc<2) usage("flagfmt [arg ...]"); |
| bourne=flag['b']!=0; |
| flag['b']=0; |
| if((argc=getflags(argc-1, argv+1, argv[1]))<0){ |
| usmsg(argv[1]); |
| exits(0); |
| } |
| if(bourne) bourneprint(argc, argv); |
| else rcprint(argc, argv); |
| exits(0); |
| } |
| void |
| bourneprint(int argc, char *argv[]) |
| { |
| register int c, i, n; |
| for(c=0;c!=NFLAG;c++) if(flag[c]){ |
| print("FLAG%c=", c); /* bug -- c could be a bad char */ |
| n=count(c, argv[1]); |
| if(n==0) |
| print("1\n"); |
| else{ |
| print("'"); |
| bournearg(flag[c][0]); |
| for(i=1;i!=n;i++){ |
| print(" "); |
| bournearg(flag[c][i]); |
| } |
| print("'\n"); |
| } |
| } |
| print("set --"); |
| for(c=1;c!=argc;c++){ |
| print(" "); |
| bournearg(argv[c+1]); |
| } |
| print("\n"); |
| } |
| void |
| bournearg(char *s) |
| { |
| for(;*s;s++) |
| if(*s=='\'') |
| print("'\\''"); |
| else |
| print("%c", *s); |
| } |
| void |
| rcprint(int argc, char *argv[]) |
| { |
| int c, i, n; |
| for(c=0;c!=NFLAG;c++) if(flag[c]){ |
| print("FLAG%c=", c); /* bug -- c could be a bad char */ |
| n=count(c, argv[1]); |
| if(n==0) |
| print("''"); |
| else if(n==1) |
| rcarg(flag[c][0]); |
| else{ |
| print("("); |
| rcarg(flag[c][0]); |
| for(i=1;i!=n;i++){ |
| print(" "); |
| rcarg(flag[c][i]); |
| } |
| print(")"); |
| } |
| print("\n"); |
| } |
| print("*="); |
| if(argc==1) print("()"); |
| else if(argc==2) rcarg(argv[2]); |
| else{ |
| print("("); |
| rcarg(argv[2]); |
| for(c=2;c!=argc;c++){ |
| print(" "); |
| rcarg(argv[c+1]); |
| } |
| print(")"); |
| } |
| print("\n"); |
| } |
| void |
| usmsg(char *flagarg) |
| { |
| char *s, *t, c; |
| int count, nflag=0; |
| print("echo Usage: $0'"); |
| for(s=flagarg;*s;){ |
| c=*s; |
| if(*s++==' ') continue; |
| if(*s==':') |
| count = strtol(s+1, &s, 10); |
| else count=0; |
| if(count==0){ |
| if(nflag==0) print(" [-"); |
| nflag++; |
| print("%c", c); |
| } |
| if(*s=='['){ |
| int depth=1; |
| s++; |
| for(;*s!='\0' && depth>0; s++) |
| if (*s==']') depth--; |
| else if (*s=='[') depth++; |
| } |
| } |
| if(nflag) print("]"); |
| for(s=flagarg;*s;){ |
| c=*s; |
| if(*s++==' ') continue; |
| if(*s==':') |
| count = strtol(s+1, &s, 10); |
| else count=0; |
| if(count!=0){ |
| print(" [-"); |
| print("%c", c); |
| if(*s=='['){ |
| int depth=1; |
| s++; |
| t=s; |
| for(;*s!='\0' && depth>0; s++) |
| if (*s==']') depth--; |
| else if (*s=='[') depth++; |
| print(" "); |
| write(1, t, s - t); |
| } |
| else |
| while(count--) print(" arg"); |
| print("]"); |
| } |
| else if(*s=='['){ |
| int depth=1; |
| s++; |
| for(;*s!='\0' && depth>0; s++) |
| if (*s==']') depth--; |
| else if (*s=='[') depth++; |
| } |
| } |
| print("' $usage;\n"); |
| print("exit 'usage'\n"); |
| } |
| int |
| count(int flag, char *flagarg) |
| { |
| char *s, c; |
| int n; |
| for(s=flagarg;*s;){ |
| c=*s; |
| if(*s++==' ') continue; |
| if(*s==':') |
| n = strtol(s+1, &s, 10); |
| else n=0; |
| if(*s=='['){ |
| int depth=1; |
| s++; |
| for(;*s!='\0' && depth>0; s++) |
| if (*s==']') depth--; |
| else if (*s=='[') depth++; |
| } |
| if(c==flag) return n; |
| } |
| return -1; /* never happens */ |
| } |
| void |
| rcarg(char *s) |
| { |
| if(*s=='\0' || strpbrk(s, "\n \t#;&|^$=`'{}()<>?")){ |
| print("\'"); |
| for(;*s;s++) |
| if(*s=='\'') print("''"); |
| else print("%c", *s); |
| print("\'"); |
| } |
| else print("%s", s); |
| } |