This is code from
DISCUSSION: Argument Expansion Syntax demonstrating an alternative method of expanding an executable file name and arguments (I think...).
## start of expand.tcl
#
# prototype expand command
# Joe Mistachkin
# 7/31/2003
set expand_argument_error "wrong # args: should be \"expand ?-expand expand_list? arg ?arg ...?\""
set expand_list_error "malformed expansion list"
proc expand_processExpansionList { array_name error_name expand_list argument_count } {
# get variable to put error message into...
upvar "1" $error_name local_error
if {$argument_count > "0"} then {
# we are going to put the results into the caller's array.
upvar "1" $array_name local_array
# set all arguments to default state (not expanded)
set index "0"
while {$index < $argument_count} {
set local_array($index) "0"
incr index
}
# assume success until we find an actual error.
set result "0"
# are we processing a "to" range?
set range(from) "-1"
set range(to) "-1"
set last_item ""
foreach this_item $expand_list {
if {[string is integer -strict $this_item] != "0"} then {
if {$range(from) != "-1"} then {
# mark the end of the range...
set range(to) $this_item
# make sure it's a valid range...
if {$range(from) <= $range(to)} then {
# mark entire range to be expanded...
set index $range(from)
while {$index <= $range(to)} {
set local_array($index) "1"
incr index
}
# reset range positions...
set range(from) "-1"
set range(to) "-1"
} else {
# nope, not a valid range.
set local_error "not a valid range"
set result "-1"
break
}
} else {
if {(($this_item >= "0") && ($this_item < $argument_count))} then {
# mark this argument for expansion...
set local_array($this_item) "1"
} else {
# out of bounds.
set local_error "argument index out of bounds"
set result "-1"
break
}
}
} else {
switch -exact -- $this_item {
"to" {
if {$range(from) == "-1"} then {
if {[string is integer -strict $last_item] != "0"} then {
set range(from) $last_item
} else {
# invalid start of range...
set local_error "invalid index for start of range"
set result "-1"
break
}
} else {
# already started a range...
set local_error "range already started"
set result "-1"
break
}
}
"end" {
# mark last argument to be expanded...
set local_array([expr {$argument_count - "1"}]) "1"
}
default {
# unknown argument processing directive.
set local_error "unknown argument processing directive"
set result "-1"
break
}
}
}
# set last item processed to current item...
set last_item $this_item
}
} else {
# NOTE: not really an error.
set local_error "nothing to process"
set result "0"
}
return $result
}
proc expand { args } {
global expand_argument_error
global expand_list_error
#
# check for list of things to expand...
# (default is to expand nothing)
#
if {[llength $args] > "0"} then {
switch -exact -- [lindex $args "0"] {
"-expand" {
# we want to expand the specified arguments.
set expand "1"
# next, there should be a list of things to expand.
set index "1"
# the option and expansion list are NOT included in the argument count.
set argument_count [expr {[llength $args] - ($index + "1")}]
}
"-noexpand" {
# we want to NOT expand the specified arguments.
set expand "0"
# next, there should be a list of things to NOT expand.
set index "1"
# the option and expansion list are NOT included in the argument count.
set argument_count [expr {[llength $args] - ($index + "1")}]
}
default {
# don't expand by default.
set expand "0"
# there is no list of things to expand.
set index "-1"
# all arguments are passed along.
set argument_count [llength $args]
}
}
if {(($index == "-1") || ([llength $args] > ($index + "1")))} then {
if {$index != "-1"} then {
# get list of args to modify.
set expand_list [lindex $args $index]
set expand_error ""
array set expand_array {}
if {[expand_processExpansionList expand_array expand_error $expand_list $argument_count] != "0"} then {
error "$expand_list_error: $expand_error"
}
} else {
# no arguments to modify.
set expand_list [list]
}
# start with an empty list as the command string to evaluate.
set result [list]
# start just beyond the end of the expansion list (if any).
set this_index [expr {$index + "1"}]
while {$this_index < [llength $args]} {
# get the translated argument index...
if {$index != "-1"} then {
set argument_index [expr {$this_index - ($index + "1")}]
} else {
set argument_index $this_index
}
if {[info exists expand_array($argument_index)] != "0"} then {
# is the argument targeted for expansion?
if {$expand_array($argument_index) != "0"} then {
set do_expand [expr {$expand ? "1" : "0"}]
} else {
set do_expand [expr {$expand ? "0" : "1"}]
}
} else {
set do_expand [expr {$expand ? "0" : "1"}]
}
if {$do_expand != "0"} then {
# add the expanded list to the command string.
set result [concat $result [lindex $args $this_index]]
} else {
# add the unmodified argument to the command string.
lappend result [lindex $args $this_index]
}
incr this_index
}
} else {
# not enough arguments.
error $expand_argument_error
}
} else {
#
# NOTE: potential for design change here.
#
# return empty string when given no arguments...?
set result ""
}
uplevel "1" $result
}
proc expand_test_proc { args } {
puts stdout "number of args = [llength $args]"
puts stdout "args = \{ $args \}"
}
## end of expand.tcl
Try these examples:
expand -expand {1 to 3 end} expand_test_proc [list argument 1] [list argument 2] [list argument 3] [list argument 4] [list argument 5]
expand -expand {1} expand_test_proc [list this is a test.]
expand -noexpand {1} expand_test_proc [list this is a test.]
expand expand_test_proc [list this is a test.]