====== ## ******************************************************** ## ## 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 {} ====== <> Command