getflags: import from 4e, with usage
fixes #6 http://bitbucket.org/rsc/plan9port/issue/6/ http://codereview.appspot.com/95043
This commit is contained in:
parent
9bea9069bf
commit
3cd77ae679
7 changed files with 231 additions and 485 deletions
82
cmd/getflags.c
Normal file
82
cmd/getflags.c
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
print("status=usage\n");
|
||||||
|
exits(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
findarg(char *flags, Rune r)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
Rune rr;
|
||||||
|
|
||||||
|
for(p=flags; p!=(char*)1; p=strchr(p, ',')+1){
|
||||||
|
chartorune(&rr, p);
|
||||||
|
if(rr == r)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
countargs(char *p)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 1;
|
||||||
|
while(*p == ' ')
|
||||||
|
p++;
|
||||||
|
for(; *p && *p != ','; p++)
|
||||||
|
if(*p == ' ' && *(p-1) != ' ')
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *flags, *p, buf[512];
|
||||||
|
int i, n;
|
||||||
|
Fmt fmt;
|
||||||
|
|
||||||
|
quotefmtinstall();
|
||||||
|
argv0 = argv[0]; /* for sysfatal */
|
||||||
|
|
||||||
|
flags = getenv("flagfmt");
|
||||||
|
if(flags == nil){
|
||||||
|
fprint(2, "$flagfmt not set\n");
|
||||||
|
print("exit 'missing flagfmt'");
|
||||||
|
exits(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmtfdinit(&fmt, 1, buf, sizeof buf);
|
||||||
|
for(p=flags; p!=(char*)1; p=strchr(p, ',')+1)
|
||||||
|
fmtprint(&fmt, "flag%.1s=()\n", p);
|
||||||
|
ARGBEGIN{
|
||||||
|
default:
|
||||||
|
if((p = findarg(flags, ARGC())) == nil)
|
||||||
|
usage();
|
||||||
|
p += runelen(ARGC());
|
||||||
|
if(*p == ',' || *p == 0){
|
||||||
|
fmtprint(&fmt, "flag%C=1\n", ARGC());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = countargs(p);
|
||||||
|
fmtprint(&fmt, "flag%C=(", ARGC());
|
||||||
|
for(i=0; i<n; i++)
|
||||||
|
fmtprint(&fmt, "%s%q", i ? " " : "", EARGF(usage()));
|
||||||
|
fmtprint(&fmt, ")\n");
|
||||||
|
}ARGEND
|
||||||
|
|
||||||
|
fmtprint(&fmt, "*=(");
|
||||||
|
for(i=0; i<argc; i++)
|
||||||
|
fmtprint(&fmt, "%s%q", i ? " " : "", argv[i]);
|
||||||
|
fmtprint(&fmt, ")\n");
|
||||||
|
fmtprint(&fmt, "status=''\n");
|
||||||
|
fmtfdflush(&fmt);
|
||||||
|
exits(0);
|
||||||
|
}
|
||||||
72
cmd/usage.c
Normal file
72
cmd/usage.c
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
Fmt fmt;
|
||||||
|
char buf[512];
|
||||||
|
char *argv0, *args, *flags, *p, *p0;
|
||||||
|
int single;
|
||||||
|
Rune r;
|
||||||
|
|
||||||
|
argv0 = getenv("0");
|
||||||
|
if(argv0 == nil) {
|
||||||
|
if(argc > 1)
|
||||||
|
argv0 = argv[1];
|
||||||
|
else
|
||||||
|
argv0 = "unknown-program-name";
|
||||||
|
}
|
||||||
|
if((p = strrchr(argv0, '/')) != nil)
|
||||||
|
argv0 = p+1;
|
||||||
|
flags = getenv("flagfmt");
|
||||||
|
args = getenv("args");
|
||||||
|
|
||||||
|
if(argv0 == nil){
|
||||||
|
fprint(2, "aux/usage: $0 not set\n");
|
||||||
|
exits("$0");
|
||||||
|
}
|
||||||
|
if(flags == nil)
|
||||||
|
flags = "";
|
||||||
|
if(args == nil)
|
||||||
|
args = "";
|
||||||
|
|
||||||
|
fmtfdinit(&fmt, 2, buf, sizeof buf);
|
||||||
|
fmtprint(&fmt, "usage: %s", argv0);
|
||||||
|
if(flags[0]){
|
||||||
|
single = 0;
|
||||||
|
for(p=flags; *p; ){
|
||||||
|
p += chartorune(&r, p);
|
||||||
|
if(*p == ',' || *p == 0){
|
||||||
|
if(!single){
|
||||||
|
fmtprint(&fmt, " [-");
|
||||||
|
single = 1;
|
||||||
|
}
|
||||||
|
fmtprint(&fmt, "%C", r);
|
||||||
|
if(*p == ',')
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while(*p == ' ')
|
||||||
|
p++;
|
||||||
|
if(single){
|
||||||
|
fmtprint(&fmt, "]");
|
||||||
|
single = 0;
|
||||||
|
}
|
||||||
|
p0 = p;
|
||||||
|
p = strchr(p0, ',');
|
||||||
|
if(p == nil)
|
||||||
|
p = "";
|
||||||
|
else
|
||||||
|
*p++ = 0;
|
||||||
|
fmtprint(&fmt, " [-%C %s]", r, p0);
|
||||||
|
}
|
||||||
|
if(single)
|
||||||
|
fmtprint(&fmt, "]");
|
||||||
|
}
|
||||||
|
if(args)
|
||||||
|
fmtprint(&fmt, " %s", args);
|
||||||
|
fmtprint(&fmt, "\n");
|
||||||
|
fmtfdflush(&fmt);
|
||||||
|
exits("usage");
|
||||||
|
}
|
||||||
77
man8/getflags.8
Normal file
77
man8/getflags.8
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
.TH GETFLAGS 8
|
||||||
|
.SH NAME
|
||||||
|
getflags, usage \- command-line parsing for shell scripts
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B getflags $*
|
||||||
|
.PP
|
||||||
|
.B usage [ progname ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I Getflags
|
||||||
|
parses the options in its command-line arguments
|
||||||
|
according to the environment variable
|
||||||
|
.BR $flagfmt .
|
||||||
|
This variable should be a list of comma-separated options.
|
||||||
|
Each option can be a single letter, indicating that it does
|
||||||
|
not take arguments, or a letter followed by the space-separated
|
||||||
|
names of its arguments.
|
||||||
|
.I Getflags
|
||||||
|
prints an
|
||||||
|
.IR rc (1)
|
||||||
|
script on standard output which initializes the
|
||||||
|
environment variable
|
||||||
|
.BI $flag x
|
||||||
|
for every option mentioned in
|
||||||
|
.BR $flagfmt .
|
||||||
|
If the option is not present on the command-line, the script
|
||||||
|
sets that option's flag variable to an empty list.
|
||||||
|
Otherwise, the script sets that option's flag variable with
|
||||||
|
a list containing the option's arguments or,
|
||||||
|
if the option takes no arguments,
|
||||||
|
with the string
|
||||||
|
.BR 1 .
|
||||||
|
The script also sets the variable
|
||||||
|
.B $*
|
||||||
|
to the list of arguments following the options.
|
||||||
|
The final line in the script sets the
|
||||||
|
.B $status
|
||||||
|
variable, to the empty string on success
|
||||||
|
and to the string
|
||||||
|
.B usage
|
||||||
|
when there is an error parsing the command line.
|
||||||
|
.PP
|
||||||
|
.I Usage
|
||||||
|
prints a usage message to standard error.
|
||||||
|
It creates the message using
|
||||||
|
.BR $flagfmt ,
|
||||||
|
as described above,
|
||||||
|
.BR $args ,
|
||||||
|
which should contain the string to be printed explaining
|
||||||
|
non-option arguments,
|
||||||
|
and
|
||||||
|
.BR $0 ,
|
||||||
|
the program name
|
||||||
|
(see
|
||||||
|
.IR rc (1)).
|
||||||
|
If run under
|
||||||
|
.IR sh (1),
|
||||||
|
which does not set
|
||||||
|
.BR $0 ,
|
||||||
|
the program name must be given explicitly on the command line.
|
||||||
|
.SH EXAMPLE
|
||||||
|
Parse the arguments for
|
||||||
|
.IR leak (1):
|
||||||
|
.IP
|
||||||
|
.EX
|
||||||
|
flagfmt='b,s,f binary,r res,x width'
|
||||||
|
args='name | pid list'
|
||||||
|
if(! ifs=() eval `{getflags $*} || ~ $#* 0){
|
||||||
|
usage
|
||||||
|
exit usage
|
||||||
|
}
|
||||||
|
.EE
|
||||||
|
.SH SOURCE
|
||||||
|
.B \*9/src/cmd/getflags.c
|
||||||
|
.br
|
||||||
|
.B \*9/src/cmd/usage.c
|
||||||
|
.SH SEE ALSO
|
||||||
|
.IR arg (3)
|
||||||
|
|
@ -1,267 +0,0 @@
|
||||||
#include <u.h>
|
|
||||||
#include <libc.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "getflags.h"
|
|
||||||
|
|
||||||
char **flag[NFLAG];
|
|
||||||
char cmdline[NCMDLINE+1];
|
|
||||||
char *cmdname;
|
|
||||||
char *flagset[];
|
|
||||||
char *flagset[]={"<flag>"};
|
|
||||||
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-i<count){
|
|
||||||
reason=ARGCCOUNT;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
static reverse(char **p, char **q)
|
|
||||||
{
|
|
||||||
register 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(!isdigit((uchar)*f)){ reason=FLAGSYN; return -1; }
|
|
||||||
count=strtol(f, &f, 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
count=0;
|
|
||||||
if(*f=='['){
|
|
||||||
int depth=1;
|
|
||||||
do{
|
|
||||||
f++;
|
|
||||||
if(*f=='\0'){ reason=FLAGSYN; return -1; }
|
|
||||||
if(*f=='[') depth++;
|
|
||||||
if(*f==']') depth--;
|
|
||||||
}while(depth>0);
|
|
||||||
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 <stdio.h>
|
|
||||||
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
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
/*% 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#define NFLAG 128
|
|
||||||
#define NCMDLINE 512
|
|
||||||
#define NGETFLAGSARGV 256
|
|
||||||
extern char **flag[NFLAG];
|
|
||||||
extern char cmdline[NCMDLINE+1];
|
|
||||||
extern char *cmdname;
|
|
||||||
extern char *flagset[];
|
|
||||||
extern char *getflagsargv[NGETFLAGSARGV+2];
|
|
||||||
int getflags(int, char *[], char *);
|
|
||||||
void usage(char *);
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<$PLAN9/src/mkhdr
|
|
||||||
|
|
||||||
TARG=getflags
|
|
||||||
OFILES=\
|
|
||||||
getflags.$O\
|
|
||||||
funcgetflags.$O\
|
|
||||||
|
|
||||||
<$PLAN9/src/mkone
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue