⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optparse.tcl

📁 linux 下的源代码分析阅读器 red hat公司新版
💻 TCL
📖 第 1 页 / 共 3 页
字号:
        }        return $val    }    # Description format error helper    proc OptOptUsage {item {what ""}} {        return -code error "invalid description format$what: $item\n\                should be a list of {varname|-flagname ?-type? ?defaultvalue?\                ?helpstring?}";    }    # Generate a canonical form single instruction    proc OptNewInst {state varname type typeArgs help} {	list $state $varname [list 0 {}] $type $typeArgs $help;	#                          ^  ^	#                          |  |	#               hasBeenSet=+  +=currentValue    }    # Translate one item to canonical form    proc OptNormalizeOne {item} {        set lg [Lassign $item varname arg1 arg2 arg3];#       puts "called optnormalizeone '$item' v=($varname), lg=$lg";        set isflag [OptIsFlag $varname];	set isopt  [OptIsOpt  $varname];        if {$isflag} {            set state "flags";        } elseif {$isopt} {	    set state "optValue";	} elseif {[string compare $varname "args"]} {	    set state "value";	} else {	    set state "args";	}	# apply 'smart' 'fuzzy' logic to try to make	# description writer's life easy, and our's difficult :	# let's guess the missing arguments :-)        switch $lg {            1 {                if {$isflag} {                    return [OptNewInst $state $varname boolflag false ""];                } else {                    return [OptNewInst $state $varname any "" ""];                }            }            2 {                # varname default                # varname help                set type [OptGuessType $arg1]                if {[string compare $type "string"] == 0} {                    if {$isflag} {			set type boolflag			set def false		    } else {			set type any			set def ""		    }		    set help $arg1                } else {                    set help ""                    set def $arg1                }                return [OptNewInst $state $varname $type $def $help];            }            3 {                # varname type value                # varname value comment		                if {[regexp {^-(.+)$} $arg1 x type]} {		    # flags/optValue as they are optional, need a "value",		    # on the contrary, for a variable (non optional),	            # default value is pointless, 'cept for choices :		    if {$isflag || $isopt || ($type == "choice")} {			return [OptNewInst $state $varname $type $arg2 ""];		    } else {			return [OptNewInst $state $varname $type "" $arg2];		    }                } else {                    return [OptNewInst $state $varname\			    [OptGuessType $arg1] $arg1 $arg2]                }            }            4 {                if {[regexp {^-(.+)$} $arg1 x type]} {		    return [OptNewInst $state $varname $type $arg2 $arg3];                } else {                    return -code error [OptOptUsage $item];                }            }            default {                return -code error [OptOptUsage $item];            }        }    }    # Auto magic lasy type determination    proc OptGuessType {arg} {        if {[regexp -nocase {^(true|false)$} $arg]} {            return boolean        }        if {[regexp {^(-+)?[0-9]+$} $arg]} {            return int        }        if {![catch {expr {double($arg)}}]} {            return float        }        return string    }    # Error messages front ends    proc OptAmbigous {desc arg} {        OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]    }    proc OptFlagUsage {desc arg} {        OptError "bad flag \"$arg\", must be one of" $desc;    }    proc OptTooManyArgs {desc arguments} {        OptError "too many arguments (unexpected argument(s): $arguments),\		usage:"\		$desc 1    }    proc OptParamType {item} {	if {[OptIsFlag $item]} {	    return "flag";	} else {	    return "parameter";	}    }    proc OptBadValue {item arg {err {}}} {#       puts "bad val err = \"$err\"";        OptError "bad value \"$arg\" for [OptParamType $item]"\		[list $item]    }    proc OptMissingValue {descriptions} {#        set item [OptCurDescFinal $descriptions];        set item [OptCurDesc $descriptions];        OptError "no value given for [OptParamType $item] \"[OptName $item]\"\		(use -help for full usage) :"\		[list $item]    }proc ::tcl::OptKeyError {prefix descKey {header 0}} {    OptError $prefix [OptKeyGetDesc $descKey] $header;}    # determine string length for nice tabulated output    proc OptLengths {desc nlName tlName dlName} {	upvar $nlName nl;	upvar $tlName tl;	upvar $dlName dl;	foreach item $desc {	    if {[OptIsCounter $item]} continue;	    if {[OptIsPrg $item]} {		OptLengths $item nl tl dl	    } else {		SetMax nl [string length [OptName $item]]		SetMax tl [string length [OptType $item]]		set dv [OptTypeArgs $item];		if {[OptState $item] != "header"} {		    set dv "($dv)";		}		set l [string length $dv];		# limit the space allocated to potentially big "choices"		if {([OptType $item] != "choice") || ($l<=12)} {		    SetMax dl $l		} else {		    if {![info exists dl]} {			set dl 0		    }		}	    }	}    }    # output the tree    proc OptTree {desc nl tl dl} {	set res "";	foreach item $desc {	    if {[OptIsCounter $item]} continue;	    if {[OptIsPrg $item]} {		append res [OptTree $item $nl $tl $dl];	    } else {		set dv [OptTypeArgs $item];		if {[OptState $item] != "header"} {		    set dv "($dv)";		}		append res [format "\n    %-*s %-*s %-*s %s" \			$nl [OptName $item] $tl [OptType $item] \			$dl $dv [OptHelp $item]]	    }	}	return $res;    }# Give nice usage stringproc ::tcl::OptError {prefix desc {header 0}} {    # determine length    if {$header} {	# add faked instruction	set h [list [OptNewInst header Var/FlagName Type Value Help]];	lappend h   [OptNewInst header ------------ ---- ----- ----];	lappend h   [OptNewInst header {( -help} "" "" {gives this help )}]	set desc [concat $h $desc]    }    OptLengths $desc nl tl dl    # actually output     return "$prefix[OptTree $desc $nl $tl $dl]"}################     General Utility functions   ######################### List utility functions# Naming convention:#     "Lvarxxx" take the list VARiable name as argument#     "Lxxxx"   take the list value as argument#               (which is not costly with Tcl8 objects system#                as it's still a reference and not a copy of the values)## Is that list empty ?proc ::tcl::Lempty {list} {    expr {[llength $list]==0}}# Gets the value of one leaf of a lists treeproc ::tcl::Lget {list indexLst} {    if {[llength $indexLst] <= 1} {        return [lindex $list $indexLst];    }    Lget [lindex $list [Lfirst $indexLst]] [Lrest $indexLst];}# Sets the value of one leaf of a lists tree# (we use the version that does not create the elements because#  it would be even slower... needs to be written in C !)# (nb: there is a non trivial recursive problem with indexes 0,#  which appear because there is no difference between a list#  of 1 element and 1 element alone : [list "a"] == "a" while #  it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1#  and [listp "a b"] maybe 0. listp does not exist either...)proc ::tcl::Lvarset {listName indexLst newValue} {    upvar $listName list;    if {[llength $indexLst] <= 1} {        Lvarset1nc list $indexLst $newValue;    } else {        set idx [Lfirst $indexLst];        set targetList [lindex $list $idx];        # reduce refcount on targetList (not really usefull now,	# could be with optimizing compiler)#        Lvarset1 list $idx {};        # recursively replace in targetList        Lvarset targetList [Lrest $indexLst] $newValue;        # put updated sub list back in the tree        Lvarset1nc list $idx $targetList;    }}# Set one cell to a value, eventually create all the needed elements# (on level-1 of lists)variable emptyList {}proc ::tcl::Lvarset1 {listName index newValue} {    upvar $listName list;    if {$index < 0} {return -code error "invalid negative index"}    set lg [llength $list];    if {$index >= $lg} {        variable emptyList;        for {set i $lg} {$i<$index} {incr i} {            lappend list $emptyList;        }        lappend list $newValue;    } else {        set list [lreplace $list $index $index $newValue];    }}# same as Lvarset1 but no bound checking / creationproc ::tcl::Lvarset1nc {listName index newValue} {    upvar $listName list;    set list [lreplace $list $index $index $newValue];}# Increments the value of one leaf of a lists tree# (which must exists)proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {    upvar $listName list;    if {[llength $indexLst] <= 1} {        Lvarincr1 list $indexLst $howMuch;    } else {        set idx [Lfirst $indexLst];        set targetList [lindex $list $idx];        # reduce refcount on targetList        Lvarset1nc list $idx {};        # recursively replace in targetList        Lvarincr targetList [Lrest $indexLst] $howMuch;        # put updated sub list back in the tree        Lvarset1nc list $idx $targetList;    }}# Increments the value of one cell of a listproc ::tcl::Lvarincr1 {listName index {howMuch 1}} {    upvar $listName list;    set newValue [expr {[lindex $list $index]+$howMuch}];    set list [lreplace $list $index $index $newValue];    return $newValue;}# Returns the first element of a listproc ::tcl::Lfirst {list} {    lindex $list 0}# Returns the rest of the list minus first elementproc ::tcl::Lrest {list} {    lrange $list 1 end}# Removes the first element of a listproc ::tcl::Lvarpop {listName} {    upvar $listName list;    set list [lrange $list 1 end];}# Same but returns the removed elementproc ::tcl::Lvarpop2 {listName} {    upvar $listName list;    set el [Lfirst $list];    set list [lrange $list 1 end];    return $el;}# Assign list elements to variables and return the length of the listproc ::tcl::Lassign {list args} {    # faster than direct blown foreach (which does not byte compile)    set i 0;    set lg [llength $list];    foreach vname $args {        if {$i>=$lg} break        uplevel [list set $vname [lindex $list $i]];        incr i;    }    return $lg;}# Misc utilities# Set the varname to value if value is greater than varname's current value# or if varname is undefinedproc ::tcl::SetMax {varname value} {    upvar 1 $varname var    if {![info exists var] || $value > $var} {        set var $value    }}# Set the varname to value if value is smaller than varname's current value# or if varname is undefinedproc ::tcl::SetMin {varname value} {    upvar 1 $varname var    if {![info exists var] || $value < $var} {        set var $value    }}    # everything loaded fine, lets create the test proc:    OptCreateTestProc    # Don't need the create temp proc anymore:    rename OptCreateTestProc {}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -