Hello 9fans.
Plan9 C has nice ARGBEGIN and ARGEND macros, which make easy to write
code for flags and options.
For example composed flag style
ls -pld dir
is OK. We are not insisted to write decomposed flag style:
ls -p -l -d dir
In rc code, we write code such as
while(~ $1 -*){
switch($1){
case -a
aopt=$2
shift
case -b
bflag=1
...
assuming decomposed flags and options.
I sometimes make mistakes in executing commands forgetting they are
coded in rc.
I want uniform handling for flags and options in command line.
A small helper tool named "decomp" may be useful for this purpose.
=== BEGIN ===
#!/bin/awk -f
# decomp is designed to make easy to parse
# flags and options in rc script.
# usage: echo flg:opt $* | decomp
# examples:
# % echo abc:de -cadefg| decomp
# -c -a -d efg
# % echo abc:de -caxbcdefg| decomp
# -c -a# error in x (-caxbcdefg)
# % echo abc:de -cabcdefg xyz| decomp
# -c -a -b -c -d efg xyz
# % echo abc:de -cabxcdefg -axy | decomp
# -c -a -b# error in x (-cabxcdefg)
# % echo abc:de -cabcd efg -a xy | decomp
# -c -a -b -c -d efg -a xy
# % echo abc: -cabcdefg | decomp
# -c -a -b -c# error in d (-cabcdefg)
# % echo :de -cabxcdefg | decomp
# # error in c (-cabxcdefg)
# % echo abc: -a - foo | decomp
# -a - foo
# % echo abc: -a - 'f oo' | decomp
# -a - f oo
# BUG: decomp cannot handle spaces in arguments
#
# 2021/12/14 Kenar
# function definitions are first
function error(fmt,s){
printf(fmt,s) > "/dev/cons"
exit "usage"
}
function isplit(s,n){
return substr(s,1,n-1) " " substr(s,n)
}
function decomp1(s,s0,b,c,t){
# then s,s0,b,c,t are local
if(cont){
printf(" %s", s)
cont = 0
return
}
cont = 0
s0 = s
for(;;){
#print "#1", s
split(isplit(s,2),t," ")
b=t[1]
c=t[2]
#print "#2", b, c
if(b != "-"){
printf(" %s", s)
return
}
split(isplit(c,2),t," ")
b=t[1]
c=t[2]
#print "#3", b, c
if(index(opt,b) != 0){
if(c == ""){
printf(" -%s", b)
cont = 1
}
else
printf(" -%s %s", b, c)
return
}
if(index(flg,b) != 0){
printf(" -%s", b)
if(c == "")
return
s = "-" c
continue
}
error(fmt1, b "\t(" s0 ")")
return
}
}
BEGIN{ # global constants are here, not insisted by awk though
fmt1="# error in %s\n"
fmt2="# error in input line:\n#\t%s\n"\
"# required flg:opt at the first argument\n"
}
{
if((m = split($0,u," ")) < 2 || split(u[1],t,":") != 2)
error(fmt2,$0)
flg =t[1]
opt =t[2]
cont = 0
#print "#", flg, opt
for(n = 2; n <= m; n++){
#print "#", u[n]
decomp1(u[n])
}
# Why the code below doesn't work?
# split("abc de",u," ")
# for(a in u){
# print a # a is ?
# }
# not required but maybe better in debugging
printf("\n")
}
=== END ===
Then adding lines
*=`{echo flg:opt $* | decomp}
if(~ $status ?*) {do something}
before "while(~ $1 -*)" enables composed flags and options like C.
Maybe someone already have a tool of this sort,
or "decomp" may be improved to be better one,
or there are more bugs in it,
then information is welcome.
Kenji Arisawa
------------------------------------------
9fans: 9fans
Permalink:
https://9fans.topicbox.com/groups/9fans/T0ceb5dd708ebfd4f-M9d1884360382f65d1acf8c9d
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription