Ignore:
Timestamp:
Oct 22, 2010, 4:06:10 PM (14 years ago)
Author:
gah
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/units.tcl

    r1342 r1929  
    2828proc Rappture::Units::define {what args} {
    2929    if {[regexp {(.+)->(.+)} $what match new fndm]} {
    30         if {[llength $args] != 2} {
    31             error "wrong # args: should be \"define units1->units2 exprTo exprFrom\""
    32         }
    33         #
    34         # Convert the units variables embedded in the conversion
    35         # expressions to something that Tcl can handle.  We'll
    36         # use ${number} to represent the variables.
    37         #
    38         foreach {exprTo exprFrom} $args { break }
    39         regsub -all $new $exprTo {${number}} exprTo
    40         regsub -all $fndm $exprFrom {${number}} exprFrom
    41 
    42         Rappture::Units::System #auto $new \
    43             -basis [list $fndm $exprTo $exprFrom]
     30        if {[llength $args] != 2} {
     31            error "wrong # args: should be \"define units1->units2 exprTo exprFrom\""
     32        }
     33        #
     34        # Convert the units variables embedded in the conversion
     35        # expressions to something that Tcl can handle.  We'll
     36        # use ${number} to represent the variables.
     37        #
     38        foreach {exprTo exprFrom} $args { break }
     39        regsub -all $new $exprTo {${number}} exprTo
     40        regsub -all $fndm $exprFrom {${number}} exprFrom
     41
     42        Rappture::Units::System #auto $new \
     43            -basis [list $fndm $exprTo $exprFrom]
    4444
    4545    } elseif {[regexp {^/?[a-zA-Z]+[0-9]*$} $what]} {
    46         array set opts {
    47             -type ""
    48             -metric 0
    49         }
    50         foreach {key val} $args {
    51             if {![info exists opts($key)]} {
    52                 error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
    53             }
    54             set opts($key) $val
    55         }
    56         eval Rappture::Units::System #auto $what [array get opts]
     46        array set opts {
     47            -type ""
     48            -metric 0
     49        }
     50        foreach {key val} $args {
     51            if {![info exists opts($key)]} {
     52                error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
     53            }
     54            set opts($key) $val
     55        }
     56        eval Rappture::Units::System #auto $what [array get opts]
    5757    } else {
    58         error "bad units definition \"$what\": should be something like m or /cm3 or A->m"
     58        error "bad units definition \"$what\": should be something like m or /cm3 or A->m"
    5959    }
    6060}
     
    7171proc Rappture::Units::convert {value args} {
    7272    array set opts {
    73         -context ""
    74         -to ""
    75         -units "on"
     73        -context ""
     74        -to ""
     75        -units "on"
    7676    }
    7777    foreach {key val} $args {
    78         if {![info exists opts($key)]} {
    79             error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
    80         }
    81         set opts($key) $val
     78        if {![info exists opts($key)]} {
     79            error "bad option \"$key\": should be [join [lsort [array names opts]] {, }]"
     80        }
     81        set opts($key) $val
    8282    }
    8383
     
    8787    set value [string trim $value]
    8888    if {![regexp {^([-+]?[0-9]+\.?([0-9]+)?([eEdD][-+]?[0-9]+)?) *(/?[a-zA-Z]+[0-9]*)?$} $value match number dummy1 dummy2 units]} {
    89         set mesg "bad value \"$value\": should be real number with units"
    90         if {$opts(-context) != ""} {
    91             append mesg " of [Rappture::Units::description $opts(-context)]"
    92         }
    93         error $mesg
     89        set mesg "bad value \"$value\": should be real number with units"
     90        if {$opts(-context) != ""} {
     91            append mesg " of [Rappture::Units::description $opts(-context)]"
     92        }
     93        error $mesg
    9494    }
    9595    if {$units == ""} {
    96         set units $opts(-context)
     96        set units $opts(-context)
    9797    }
    9898
     
    103103    set oldsys [Rappture::Units::System::for $units]
    104104    if {$oldsys == ""} {
    105         set mesg "value \"$value\" has unrecognized units"
    106         if {$opts(-context) != ""} {
    107             append mesg ".\nShould be units of [Rappture::Units::description $opts(-context)]"
    108         }
    109         error $mesg
     105        set mesg "value \"$value\" has unrecognized units"
     106        if {$opts(-context) != ""} {
     107            append mesg ".\nShould be units of [Rappture::Units::description $opts(-context)]"
     108        }
     109        error $mesg
    110110    }
    111111
     
    114114    #
    115115    if {$opts(-to) == ""} {
    116         # no units -- return the number as is
    117         return "$number$units"
     116        # no units -- return the number as is
     117        return "$number$units"
    118118    }
    119119    return [$oldsys convert "$number$units" $opts(-to) $opts(-units)]
     
    130130    set sys [Rappture::Units::System::for $units]
    131131    if {$sys == ""} {
    132         return ""
     132        return ""
    133133    }
    134134    set mesg [$sys cget -type]
    135135    set ulist [Rappture::Units::System::all $units]
    136136    if {"" != $ulist} {
    137         append mesg " ([join $ulist {, }])"
     137        append mesg " ([join $ulist {, }])"
    138138    }
    139139    return $mesg
     
    162162    private common _prefix2factor
    163163    array set _prefix2factor {
    164         c  1e-2
    165         m  1e-3
    166         u  1e-6
    167         n  1e-9
    168         p  1e-12
    169         f  1e-15
    170         a  1e-18
    171         k  1e+3
    172         M  1e+6
    173         G  1e+9
    174         T  1e+12
    175         P  1e+15
     164        c  1e-2
     165        m  1e-3
     166        u  1e-6
     167        n  1e-9
     168        p  1e-12
     169        f  1e-15
     170        a  1e-18
     171        k  1e+3
     172        M  1e+6
     173        G  1e+9
     174        T  1e+12
     175        P  1e+15
    176176    }
    177177}
     
    182182itcl::body Rappture::Units::System::constructor {name args} {
    183183    if {![regexp {^/?[a-zA-Z]+[0-9]*$} $name]} {
    184         error "bad units declaration \"$name\""
     184        error "bad units declaration \"$name\""
    185185    }
    186186    eval configure $args
     
    193193    #
    194194    if {$basis != ""} {
    195         foreach {base exprTo exprFrom} $basis { break }
    196         if {![info exists _base($base)]} {
    197             error "fundamental system of units \"$base\" not defined"
    198         }
    199         while {$type == "" && $base != ""} {
    200             set obj $_base($base)
    201             set type [$obj cget -type]
    202             set base [lindex [$obj cget -basis] 0]
    203         }
     195        foreach {base exprTo exprFrom} $basis { break }
     196        if {![info exists _base($base)]} {
     197            error "fundamental system of units \"$base\" not defined"
     198        }
     199        while {$type == "" && $base != ""} {
     200            set obj $_base($base)
     201            set type [$obj cget -type]
     202            set base [lindex [$obj cget -basis] 0]
     203        }
    204204    }
    205205    set _system $name
     
    230230itcl::body Rappture::Units::System::fundamental {} {
    231231    if {$basis != ""} {
    232         set sys [Rappture::Units::System::for [lindex $basis 0]]
    233         return [$sys fundamental]
     232        set sys [Rappture::Units::System::for [lindex $basis 0]]
     233        return [$sys fundamental]
    234234    }
    235235    return $_system
     
    246246itcl::body Rappture::Units::System::convert {value newUnits showUnits} {
    247247    if {![regexp {^([-+]?[0-9]+\.?([0-9]+)?([eEdD][-+]?[0-9]+)?) *(/?[a-zA-Z]+[0-9]*)?$} $value match number dummy1 dummy2 units]} {
    248         error "bad value \"$value\": should be real number with units"
     248        error "bad value \"$value\": should be real number with units"
    249249    }
    250250
     
    258258    set power "1"
    259259    if {$metric && [regexp {^(/?)([cmunpfakMGTP])([a-zA-Z]+)([0-9]*)$} $units match slash prefix base power]} {
    260         set baseUnits "$slash$base$power"
     260        set baseUnits "$slash$base$power"
    261261    } else {
    262         set baseUnits $units
     262        set baseUnits $units
    263263    }
    264264    if {![string equal $baseUnits $_system]
    265           && ![string equal $baseUnits [lindex $basis 0]]} {
    266         error "can't convert value \"$value\": should have units \"$_system\""
     265          && ![string equal $baseUnits [lindex $basis 0]]} {
     266        error "can't convert value \"$value\": should have units \"$_system\""
    267267    }
    268268
     
    272272    #
    273273    if {$prefix != ""} {
    274         if {$power == ""} {
    275             set power 1
    276         }
    277         if {$slash == "/"} {
    278             set number [expr {$number/pow($_prefix2factor($prefix),$power)}]
    279         } else {
    280             set number [expr {$number*pow($_prefix2factor($prefix),$power)}]
    281         }
     274        if {$power == ""} {
     275            set power 1
     276        }
     277        if {$slash == "/"} {
     278            set number [expr {$number/pow($_prefix2factor($prefix),$power)}]
     279        } else {
     280            set number [expr {$number*pow($_prefix2factor($prefix),$power)}]
     281        }
    282282    }
    283283
     
    287287    #
    288288    if {[string equal $baseUnits [lindex $basis 0]]} {
    289         foreach {base exprTo exprFrom} $basis { break }
    290         set number [expr $exprFrom]
     289        foreach {base exprTo exprFrom} $basis { break }
     290        set number [expr $exprFrom]
    291291    }
    292292
     
    300300    set power "1"
    301301    if {$metric && [regexp {^(/?)([cmunpfakMGTP])([a-zA-Z]+)([0-9]*)$} $newUnits match slash prefix base power]} {
    302         set baseUnits "$slash$base$power"
     302        set baseUnits "$slash$base$power"
    303303    } else {
    304         set baseUnits $newUnits
     304        set baseUnits $newUnits
    305305    }
    306306    if {[string equal $baseUnits $_system]} {
    307         if {$prefix != ""} {
    308             if {$power == ""} {
    309                 set power 1
    310             }
    311             if {$slash == "/"} {
    312                 set number [expr {$number*pow($_prefix2factor($prefix),$power)}]
    313             } else {
    314                 set number [expr {$number/pow($_prefix2factor($prefix),$power)}]
    315             }
    316         }
    317         if {$showUnits} {
    318             return "$number$newUnits"
    319         }
    320         return $number
     307        if {$prefix != ""} {
     308            if {$power == ""} {
     309                set power 1
     310            }
     311            if {$slash == "/"} {
     312                set number [expr {$number*pow($_prefix2factor($prefix),$power)}]
     313            } else {
     314                set number [expr {$number/pow($_prefix2factor($prefix),$power)}]
     315            }
     316        }
     317        if {$showUnits} {
     318            return "$number$newUnits"
     319        }
     320        return $number
    321321    }
    322322
     
    328328    set base $_system
    329329    if {"" != $basis} {
    330         foreach {base exprTo exprFrom} $basis { break }
    331         set number [expr $exprTo]
     330        foreach {base exprTo exprFrom} $basis { break }
     331        set number [expr $exprTo]
    332332    }
    333333
     
    341341itcl::configbody Rappture::Units::System::basis {
    342342    if {[llength $basis] != 3} {
    343         error "bad basis \"$name\": should be {units exprTo exprFrom}"
     343        error "bad basis \"$name\": should be {units exprTo exprFrom}"
    344344    }
    345345}
     
    350350itcl::configbody Rappture::Units::System::metric {
    351351    if {![string is boolean -strict $metric]} {
    352         error "bad value \"$metric\": should be boolean"
     352        error "bad value \"$metric\": should be boolean"
    353353    }
    354354}
     
    369369    #
    370370    if {[info exists _base($units)]} {
    371         return $_base($units)
     371        return $_base($units)
    372372    } else {
    373         set orig $units
    374         if {[regexp {^(/?)[cCmMuUnNpPfFaAkKgGtT](.+)$} $units match slash tail]} {
    375             set base "$slash$tail"
    376             if {[info exists _base($base)]} {
    377                 set sys $_base($base)
    378                 if {[$sys cget -metric]} {
    379                     return $sys
    380                 }
    381             }
    382 
    383             # check the base part for improper capitalization below...
    384             set units $base
    385         }
    386 
    387         set matching ""
    388         foreach u [array names _base] {
    389             if {[string equal -nocase $u $units]} {
    390                 lappend matching $_base($u)
    391             }
    392         }
    393         if {[llength $matching] == 1} {
    394             set sys [lindex $matching 0]
    395             #
    396             # If we got rid of a metric prefix above, make sure
    397             # that the system is metric.  If not, then we don't
    398             # have a match.
    399             #
    400             if {[string equal $units $orig] || [$sys cget -metric]} {
    401                 return $sys
    402             }
    403         }
     373        set orig $units
     374        if {[regexp {^(/?)[cCmMuUnNpPfFaAkKgGtT](.+)$} $units match slash tail]} {
     375            set base "$slash$tail"
     376            if {[info exists _base($base)]} {
     377                set sys $_base($base)
     378                if {[$sys cget -metric]} {
     379                    return $sys
     380                }
     381            }
     382
     383            # check the base part for improper capitalization below...
     384            set units $base
     385        }
     386
     387        set matching ""
     388        foreach u [array names _base] {
     389            if {[string equal -nocase $u $units]} {
     390                lappend matching $_base($u)
     391            }
     392        }
     393        if {[llength $matching] == 1} {
     394            set sys [lindex $matching 0]
     395            #
     396            # If we got rid of a metric prefix above, make sure
     397            # that the system is metric.  If not, then we don't
     398            # have a match.
     399            #
     400            if {[string equal $units $orig] || [$sys cget -metric]} {
     401                return $sys
     402            }
     403        }
    404404    }
    405405    return ""
     
    416416    set sys [Rappture::Units::System::for $units]
    417417    if {$sys == ""} {
    418         return ""
     418        return ""
    419419    }
    420420
    421421    if {"" != [$sys cget -basis]} {
    422         set basis [lindex [$sys cget -basis] 0]
     422        set basis [lindex [$sys cget -basis] 0]
    423423    } else {
    424         set basis $units
     424        set basis $units
    425425    }
    426426
    427427    set ulist $basis
    428428    foreach u [array names _base] {
    429         set obj $_base($u)
    430         set b [lindex [$obj cget -basis] 0]
    431         if {$b == $basis} {
    432             lappend ulist $u
    433         }
     429        set obj $_base($u)
     430        set b [lindex [$obj cget -basis] 0]
     431        if {$b == $basis} {
     432            lappend ulist $u
     433        }
    434434    }
    435435    return $ulist
     
    447447    set sys [for $units]
    448448    if {$sys == ""} {
    449         return $units
     449        return $units
    450450    }
    451451    # note: case-insensitive matching for metric prefix
    452452    if {[regexp {^(/?)([cCmMuUnNpPfFaAkKgGtT]?)([a-zA-Z]+[0-9]+|[a-zA-Z]+)$} $units match slash prefix tail]} {
    453         if {[regexp {^[CUNFAK]$} $prefix]} {
    454             # we know that these should be lower case
    455             set prefix [string tolower $prefix]
    456         } elseif {[regexp {^[GT]$} $prefix]} {
    457             # we know that these should be upper case
    458             set prefix [string toupper $prefix]
    459         }
    460         return "$slash$prefix[string trimleft [$sys basic] /]"
     453        if {[regexp {^[CUNFAK]$} $prefix]} {
     454            # we know that these should be lower case
     455            set prefix [string tolower $prefix]
     456        } elseif {[regexp {^[GT]$} $prefix]} {
     457            # we know that these should be upper case
     458            set prefix [string toupper $prefix]
     459        }
     460        return "$slash$prefix[string trimleft [$sys basic] /]"
    461461    }
    462462    return [$sys basic]
Note: See TracChangeset for help on using the changeset viewer.