---- Why another parsing-routine? Because the other ones like cmdline or OptProc are a little overweighted or just too complex. Here in the wiki, I found links to various usefull parsing-routines, but still I decieded to write one of my own; here is the result. The input is checked/processed against a template, and the result is given back as a list suitable for '''array set'''. Switchnames may be shortened. At the bottom of the page later I will add some examples of how a commandline and the corresponding templates can look like. ---- # Simple ParameterParsing (SPar) # 08.03.2005 proc spar {tpl cmd} { if {[catch {array set a $tpl}]} { return -code error {invalid template}; # we could'nt handle this error }; # don't stop with other errors - give pgmr the chance to decide later set needmore {} set count 0 set seeopts 1 foreach item $cmd { if {[string equal $item "--"]} { set seeopts 0; # end of -flag-processing } elseif {[string length $needmore]} { set a($needmore) $item set needmore {} } elseif {$seeopts == 1 && [string range $item 0 0] == "-"} { set matches [array names a -glob $item*]; # allows shortening if {[llength $matches]} { set match [lindex [lsort $matches] 0] if {[string index $match end] == ":"} { set needmore $match; # -f: means: 'value follows' } else { set a($match) 1; # otherwise simply return 'true' } } else { lappend a(swiunknown) $item } } else { incr count; # each arg counts, even if there are too much if {[info exists a($count)]} { set a($count) $item set a(argcount) $count } else { lappend a(argsuper) $item } } } if {[string length $needmore]} { set a(swinovalue) $needmore; # missing value after -switch: at the very end } return [array get a]; # double conversion is the price for using arrays } ---- # Tests set tpl [list -f1 0 -f2 0 -f3: "*" -f4 0 -test 0 1 "" 2 "" 3 "Default3" -? 0] puts "Template: $tpl\n" puts Commandline: gets stdin cmd if {![catch {array set a [spar $tpl $cmd]} rc]} { puts "Resultarray:\n" parray a } else { puts $rc } ---- ''(Examples will be added later)'' ---- '''Command Line Parsing, enhanced (but yet simple) version with integrated help support''' (German Version) # Simple ParameterParsing (SPar) SPAR_NEW6.TCL # (C) M.Hoffmann 2004-2005 # # 26.03.2005: Erweiterung: Hilfetexte mit übergeben, formatierte Hilfeausgabe # 05.07.2005: ReView, Ergänzungen # 09.07.2005: endgültige Hilfeformatierung festgelegt # 11.07.2005: Leere pos. Args überschreiben nicht Default; Hilfe integriert; # package # # ToDo: # - Doku (hier) # - namespace # - Testcase, Demos # - Wiki # # Unterstützte Sonderzeichen in Hilfezeilen: # %s - ergibt den Switchnamen selbst (bei Pos.args nicht sinnvoll!) # %v - ergibt [Vorgabewert] # %n - Spaltengerechter manueller Zeilenumbruch package provide Spar 1.0 proc spar {tpl cmd} { if {[catch {array set a $tpl}]} { return -code error {invalid template}; # we could'nt handle this error }; # don't stop with other errors - give pgmr the chance to decide later # Help extension, formerly in separate proc set col 0 set sntx {} set help {} foreach name [lsort [array names a]] { set lCol [lindex $a($name) 1]; # left side of help set rCol [lrange $a($name) 2 end]; # right side of help set a($name) [lindex $a($name) 0]; # the value ifself set lCol [string map "%s $name" $lCol]; # 'switch' replaces %s if {[string length $lCol]} { append sntx "$lCol " append help "\[format %-\${col}s $lCol\]$rCol\n" set l [string length $lCol] ; # determine begin of set col [expr {$l > $col ? $l : $col}]; # right side of help } } incr col set nl "\n[string repeat " " $col]" set a(help) "$sntx\n\n[string map [list %v \[$a($name)\] %n $nl] [subst $help]]" # Help extension End set needmore {} set count 0 set seeopts 1 foreach item $cmd { if {[string equal $item "--"]} { set seeopts 0; # end of -flag-processing } elseif {[string length $needmore]} { set a($needmore) $item set needmore {} } elseif {$seeopts == 1 && [string range $item 0 0] == "-"} { set matches [array names a -glob $item*]; # allows shortening if {[llength $matches]} { set match [lindex [lsort $matches] 0] if {[string index $match end] == ":"} { set needmore $match; # -f: means: 'value follows' } else { set a($match) 1; # otherwise simply return 'true' } } else { lappend a(swiunknown) $item } } else { incr count; # each arg counts, even if there are too much if {[info exists a($count)]} { if {[string length $item]} { # Defaults can only be overridden by 'real' values set a($count) $item; # empty string causes skip } set a(argcount) $count } else { lappend a(argsuper) $item } } } if {[string length $needmore]} { set a(swinovalue) $needmore; # missing value after -switch: at very end } return [array get a]; # double conversion is the price for using arrays... } '''Testroutine''' (like documentation, is still a work in progress...) # Tests for Simple Parameter parsing (Spar) module # 11.07.2005 lappend auto_path ./ package require Spar 1.0 # Template Format # # The template must be a proper list suitable for `array set`! # # basic format (without help) { # -flagname|-optionname:|{1|2|...} default_value # -flagname|-optionname:|{1|2|...} default_value # : : # } # # where: # '-flagname' is - well - a flag: the presence of it always returns # 1 (true), so the default value should almost always be 0 (false); # '-optionname:' denotes a named arg, again initializied with a # default value; # 1,2,...n is a placeholder for a positional argument. it's also # possible to specify a default value for missing positional args. # # extended format (with help) { # -flagname|-optionname:|{1|2|...} {default_value helptext ...} # -flagname|-optionname:|{1|2|...} {default_value helptext ...} # : : # } # # helptext may contain %s (replaced by flag/optionname), %v # (replaced by defaultvalue, surrounded with brackets) or %n # (newline) # Setup Array With Example Template set tpl {-flag1 {0 %s A boolean flag. if present, 1 will be returned} -f2 {"" %s Ein Boolflag, bei Auftreten wird 1 geliefert. Dieser Hilfetext ist%nsehr lang, er wird manuell umgebrochen.} -f3 {"flag3def" %s Ein benanntes Argument (Key-value-Paar) %v} -f4 {0 %s Noch ein Boolflag...} -test 0 1 "" 2 Vorgabe2 3 {Default3 Ein Feld an Pos3 %v} -? 0 } puts "Template: $tpl\n" puts Commandline: gets stdin cmd if {![catch {array set a [spar $tpl $cmd]} rc]} { puts "Resultarray:\n" parray a } else { puts $rc } puts \n*****************\n puts $a(help) oops! Something's wrong above with wiki formatting.... no time now to fix it... ---- [Category Argument Processing]