aux/getflags: improve flagfmt parser
This makes the flagfmt parser more robust and accepting a looser input language — namely by allowing whitespace around specifier fields and ignoring any empty fields. Long flagfmts can thus be pleasingly displayed: flagfmt=' a, b, c, C:cache, m:mtpt mountpoint, s:srvn srvname'
This commit is contained in:
parent
0dc9c8d019
commit
ccf5d3fb9d
|
@ -71,7 +71,7 @@ The description of positional argument list is taken from
|
||||||
An example of the script generated:
|
An example of the script generated:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
% flagfmt='e:example,x,a:arg with args'
|
% flagfmt='e:example, x, a:arg with args'
|
||||||
% aux/getflags -exa arg list positional stuff
|
% aux/getflags -exa arg list positional stuff
|
||||||
example=()
|
example=()
|
||||||
flagx=()
|
flagx=()
|
||||||
|
@ -87,7 +87,7 @@ Parse the arguments for
|
||||||
.IR leak (1):
|
.IR leak (1):
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
flagfmt='b:showbmp,s:acidfmt,f binary,r res,x width'
|
flagfmt='b:showbmp, s:acidfmt, f binary, r res, x width'
|
||||||
args='name | pid list'
|
args='name | pid list'
|
||||||
if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
|
if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
|
||||||
aux/usage
|
aux/usage
|
||||||
|
|
|
@ -9,13 +9,34 @@ usage(void)
|
||||||
exits(0);
|
exits(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
skipspace(char *p)
|
||||||
|
{
|
||||||
|
while(isspace(*p))
|
||||||
|
p++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
nextarg(char *p)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
s = strchr(p, ',');
|
||||||
|
if(s == nil)
|
||||||
|
return p+strlen(p); /* to \0 */
|
||||||
|
while(*s == ',' || isspace(*s))
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
findarg(char *flags, Rune r)
|
findarg(char *flags, Rune r)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
Rune rr;
|
Rune rr;
|
||||||
|
|
||||||
for(p=flags; p!=(char*)1; p=strchr(p, ',')+1){
|
for(p=skipspace(flags); *p; p=nextarg(p)){
|
||||||
chartorune(&rr, p);
|
chartorune(&rr, p);
|
||||||
if(rr == r)
|
if(rr == r)
|
||||||
return p;
|
return p;
|
||||||
|
@ -44,10 +65,9 @@ countargs(char *p)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = 1;
|
n = 1;
|
||||||
while(*p == ' ')
|
print("%s\n", p);
|
||||||
p++;
|
for(p=skipspace(p); *p && *p != ','; p++)
|
||||||
for(; *p && *p != ','; p++)
|
if(isspace(*p) && !isspace(*(p-1)))
|
||||||
if(*p == ' ' && *(p-1) != ' ')
|
|
||||||
n++;
|
n++;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +91,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
fmtfdinit(&fmt, 1, buf, sizeof buf);
|
fmtfdinit(&fmt, 1, buf, sizeof buf);
|
||||||
for(p=flags; p!=(char*)1 && *p != 0; p=strchr(p, ',')+1){
|
for(p=skipspace(flags); *p; p=nextarg(p)){
|
||||||
s = e = nil;
|
s = e = nil;
|
||||||
if(p[1] == ':'){
|
if(p[1] == ':'){
|
||||||
s = p + 2;
|
s = p + 2;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
main(void)
|
main(void)
|
||||||
|
@ -30,9 +31,11 @@ main(void)
|
||||||
if(flags[0]){
|
if(flags[0]){
|
||||||
single = 0;
|
single = 0;
|
||||||
for(p=flags; *p; ){
|
for(p=flags; *p; ){
|
||||||
|
while(isspace(*p))
|
||||||
|
p++;
|
||||||
p += chartorune(&r, p);
|
p += chartorune(&r, p);
|
||||||
if(*p == ':')
|
if(*p == ':')
|
||||||
while(*p != '\0' && *p != ',' && *p != ' ')
|
while(*p && *p != ',' && !isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
if(*p == ',' || *p == 0){
|
if(*p == ',' || *p == 0){
|
||||||
if(!single){
|
if(!single){
|
||||||
|
@ -44,7 +47,7 @@ main(void)
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while(*p == ' ')
|
while(isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
if(single){
|
if(single){
|
||||||
fmtprint(&fmt, "]");
|
fmtprint(&fmt, "]");
|
||||||
|
|
Loading…
Reference in a new issue