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:
kvik 2020-05-07 00:10:09 +02:00
parent 0dc9c8d019
commit ccf5d3fb9d
3 changed files with 35 additions and 12 deletions

View file

@ -71,7 +71,7 @@ The description of positional argument list is taken from
An example of the script generated:
.IP
.EX
% flagfmt='e:example,x,a:arg with args'
% flagfmt='e:example, x, a:arg with args'
% aux/getflags -exa arg list positional stuff
example=()
flagx=()
@ -87,7 +87,7 @@ Parse the arguments for
.IR leak (1):
.IP
.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'
if(! ifs=() eval `{aux/getflags $*} || ~ $#* 0){
aux/usage

View file

@ -9,18 +9,39 @@ usage(void)
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*
findarg(char *flags, Rune r)
{
char *p;
Rune rr;
for(p=flags; p!=(char*)1; p=strchr(p, ',')+1){
for(p=skipspace(flags); *p; p=nextarg(p)){
chartorune(&rr, p);
if(rr == r)
return p;
}
return nil;
return nil;
}
char*
@ -44,10 +65,9 @@ countargs(char *p)
int n;
n = 1;
while(*p == ' ')
p++;
for(; *p && *p != ','; p++)
if(*p == ' ' && *(p-1) != ' ')
print("%s\n", p);
for(p=skipspace(p); *p && *p != ','; p++)
if(isspace(*p) && !isspace(*(p-1)))
n++;
return n;
}
@ -71,7 +91,7 @@ main(int argc, char *argv[])
}
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;
if(p[1] == ':'){
s = p + 2;

View file

@ -1,5 +1,6 @@
#include <u.h>
#include <libc.h>
#include <ctype.h>
void
main(void)
@ -30,9 +31,11 @@ main(void)
if(flags[0]){
single = 0;
for(p=flags; *p; ){
while(isspace(*p))
p++;
p += chartorune(&r, p);
if(*p == ':')
while(*p != '\0' && *p != ',' && *p != ' ')
while(*p && *p != ',' && !isspace(*p))
p++;
if(*p == ',' || *p == 0){
if(!single){
@ -44,7 +47,7 @@ main(void)
p++;
continue;
}
while(*p == ' ')
while(isspace(*p))
p++;
if(single){
fmtprint(&fmt, "]");