## ********************************************************
##
## Name: expandOpts
##
## Description:
## Expands procedure options. See example and test cases
## below.
##
## Comments:
## Ambiguous options throw exception.
proc expandOpts {{opts "opts"}} {
set options {}
set matches {}
set inputs [uplevel set args]
regsub -all -- {\n\s+} $inputs { } inputs
regexp {^\{(.+)\}$} $inputs -> inputs
;## get defaults
set defaults [uplevel subst \$$opts]
regsub -all -- {\n\s+} $defaults { } defaults
foreach {opt def} $defaults {
set opt [string trim $opt]
set def [string trim $def]
set matched 0
foreach {name val} $inputs {
set name [string trim $name]
regsub -- {[-]+} $name "-" name
set val [string trim $val]
if {[regexp -nocase -- $name $opt]} {
;## next test fails if ambiguous item is last
;## option on command line...
if {[lsearch -exact $matches $name] > -1} {
return -code error "ambiguous option: $name"
}
lappend matches $name
set options [concat $options [list $opt $val]]
set matched 1
break
}
}
if {$matched == 0} {
set options [concat $options [list $opt $def]]
}
}
return $options
}
## ******************************************************** ## ********************************************************
##
## Usage example and test function
proc test { args } {
set opts {
-this "$something"
-that "hostname: $::env(HOST)"
-those { 0.1 2.0 -1.2 12-43 }
-them {}
-these "foo*!{}icky-blat xx -1"
-the-others .......
}
set something foo!
array set foo [ expandOpts ]
puts [ array get foo ]
}
## ********************************************************
test -that "whaaaa?? {} foo x-m" -them "1 2 -3" -the-o {}
test -them "1 2 -3" -that "whaaaa?? {} foo x-m" -the oops! -the-o {}