This looks like a little language with myfunc as the interpreter. I
would first try to define your grammar a bit more precisely.
For example, can the parameters to these actions also start with a
hyphen? For simplicity, let's assume that won't happen, or if it does,
it's an error to be dealt with.
How do you intend to get these args which then amounts to being a little
script for your little language. Will you be hand coding them, or might
they be generated or read in from somewhere?
Are the actions to be done in order left to right? (I will assume so).
Do you have to do all action verifications before doing any actions at all?
Will the number of actions be fixed, or will you be adding new ones over
time?
My guess is that with just a few lines of tcl code you can quite easily
handle this. It might be easier than trying to find some existing
library code that might be a tricky fit. So, for me, I'd likely just
choose option 4 in your first post.
Let's abbreviate and rewrite your example for easier readability (with
q1 instead of p1 so not to confuse them) and group them on separate lines:
myfunc \
-a p1 p2 p3 \
-b q1 \
-c \
-d
Here, we have what amounts to what Gerald suggested previously, and
could be rather simply changed to tcl code:
a p1 p2 p3
b q1
c
d
Then each of a,b,c,d,... as procs would just validate their own args.
But if you are creating these dynamically, and need an interpreter,
and/or you must pre-validate everything before doing any actions, you
could say, use args for the single parameter to myfunc, and then do
something like this:
proc myfunc {args} {
puts "args= |$args| "
set actions [list]
set action [list]
# convert input to a list of lists
foreach arg $args {
if { [string index $arg 0] eq "-" } {
lappend actions $action ;# close prior
set action [list $arg] ;# start new action
} else {
lappend action $arg ;# add non - parms
}
}
lappend actions $action ;# add the final pending action
puts "actions= |$actions| "
}
For the above example, this would produce:
args= |-a p1 p2 p3 -b q1 -c -d|
actions= |{} {-a p1 p2 p3} {-b q1} -c -d|
You could either remove/skip the first empty one, or just don't generate it.
Next you can make a [foreach] pass on the actions list and validate each
action's parameters. If all ok, you could make a second pass invoking
them in order (as I assumed).
You would likely use a multi-way if/elseif..else.. (or switch) on the
types of actions that could be expanded easily. The above conversion to
a list of lists, would automatically adjust to any additional future
actions.