r00t-err0r

dict-tcl

Feb 20th, 2013
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 5.98 KB | None | 0 0
  1. proc _dict_update {dvar args} {
  2.         set name [string map {: {} ( {} ) {}} $dvar]
  3.         upvar 1 $dvar dv
  4.         upvar 1 _my_dict_array$name local
  5.  
  6.         array set local $dv
  7.         foreach {k v} [lrange $args 0 end-1] {
  8.             if {[info exists local($k)]} {
  9.                 if {![uplevel 1 [list info exists $v]]} {
  10.                     uplevel 1 [list upvar 0 _my_dict_array${name}($k) $v]
  11.                 } else {
  12.                     uplevel 1 [list set $v $local($k)]
  13.                 }
  14.             }
  15.         }
  16.         set code [catch {uplevel 1 [lindex $args end]} res]
  17.  
  18.         foreach {k v} [lrange $args 0 end-1] {
  19.             if {[uplevel 1 [list info exists $v]]} {
  20.                 set local($k) [uplevel 1 [list set $v]]
  21.             } else {
  22.                 unset -nocomplain local($k)
  23.             }
  24.         }
  25.         set dv [array get local]
  26.         unset local
  27.  
  28.         return -code $code $res
  29.     }
  30.    # Poor man's dict -- a pure tcl [dict] emulation
  31.     # Very slow, but complete.
  32.     #
  33.     # Not all error checks are implemented!
  34.     # e.g. [dict create odd arguments here] will work
  35.     #
  36.     # Implementation is based on lists, [array set/get]
  37.     # and recursion
  38.  
  39.     if {![llength [info commands dict]]} {
  40.         proc dict {cmd args} {
  41.             uplevel 1 [linsert $args 0 _dict_$cmd]
  42.         }
  43.         proc _dict_get {dv args} {
  44.             if {![llength $args]} {return $dv} else {
  45.                 array set dvx $dv
  46.                 set key [lindex $args 0]
  47.                 set dv $dvx($key)
  48.                 set args [lrange $args 1 end]
  49.                 return [eval [linsert $args 0 _dict_get $dv]]
  50.             }
  51.         }
  52.         proc _dict_exists {dv key args} {
  53.             array set dvx $dv
  54.             set r [info exists dvx($key)]
  55.             if {!$r} {return 0}
  56.             if {[llength $args]} {
  57.                 return [eval [linsert $args 0 _dict_exists $dvx($key) ]]
  58.             } else {return 1}
  59.         }
  60.         proc _dict_set {dvar key value args } {
  61.             upvar 1 $dvar dv
  62.             if {![info exists dv]} {set dv [list]}
  63.             array set dvx $dv
  64.             if {![llength $args]} {
  65.                 set dvx($key) $value
  66.             } else {
  67.                 eval [linsert $args 0 _dict_set dvx($key) $value]
  68.             }
  69.             set dv [array get dvx]
  70.         }
  71.         proc _dict_unset {dvar key args} {
  72.             upvar 1 $dvar mydvar
  73.             if {![info exists mydvar]} {return}
  74.             array set dv $mydvar
  75.             if {![llength $args]} {
  76.                 if {[info exists dv($key)]} {
  77.                     unset dv($key)
  78.                 }
  79.             } else {
  80.                 eval [linsert $args 0 _dict_unset dv($key) ]
  81.             }
  82.             set mydvar [array get dv]
  83.             return {}
  84.         }
  85.         proc _dict_keys {dv {pat *}} {
  86.             array set dvx $dv
  87.             return [array names dvx $pat]
  88.         }
  89.         proc _dict_append {dvar key {args}} {
  90.             upvar 1 $dvar dv
  91.             if {![info exists dv]} {set dv [list]}
  92.             array set dvx $dv
  93.             eval [linsert $args 0 append dvx($key) ]
  94.             set dv [array get dvx]
  95.         }
  96.         proc _dict_create {args} {
  97.             return $args
  98.         }
  99.         proc _dict_filter {dv ftype args} {
  100.             set r [list]
  101.             foreach {globpattern} $args {break}
  102.             foreach {varlist script} $args {break}
  103.  
  104.             switch $ftype {
  105.                 key {
  106.                     foreach {key value} $dv {
  107.                         if {[string match $globpattern $key]} {
  108.                             lappend r $key $value
  109.                         }
  110.                     }
  111.                 }
  112.                 value {
  113.                     foreach {key value} $dv {
  114.                         if {[string match $globpattern $value]} {
  115.                             lappend r $key $value
  116.                         }
  117.                     }
  118.                 }
  119.                 script {
  120.                     foreach {Pkey Pval} $varlist {break}
  121.                     upvar 1 $Pkey key $Pval value
  122.                     foreach {key value} $dv {
  123.                         if {[uplevel 1 $script]} {
  124.                             lappend r $key $value
  125.                         }
  126.                     }
  127.                 }
  128.                 default {
  129.                     error "Wrong filter type"
  130.                 }
  131.             }
  132.             return $r
  133.         }
  134.         proc _dict_for {kv dict body} {
  135.             uplevel 1 [list foreach $kv $dict $body]
  136.         }
  137.         proc _dict_incr {dvar key {incr 1}} {
  138.             upvar 1 $dvar dv
  139.             if {![info exists dv]} {set dv [list]}
  140.             array set dvx $dv
  141.             if {![info exists dvx($key)]} {set dvx($key) 0}
  142.             incr dvx($key) $incr
  143.             set dv [array get dvx]
  144.         }
  145.         proc _dict_info {dv} {
  146.             return "Dictionary is represented as plain list"
  147.         }
  148.         proc _dict_lappend {dvar key args} {
  149.             upvar 1 $dvar dv
  150.             if {![info exists dv]} {set dv [list]}
  151.             array set dvx $dv
  152.             eval [linsert $args 0 lappend dvx($key)]
  153.             set dv [array get dvx]
  154.         }
  155.         proc _dict_merge {args} {
  156.             foreach dv $args {
  157.                 array set dvx $dv
  158.             }
  159.             array get dvx
  160.         }
  161.         proc _dict_replace {dv args} {
  162.             foreach {k v} $args {
  163.                 _dict_set dv $k $v
  164.             }
  165.             return $dv
  166.         }
  167.         proc _dict_remove {dv args} {
  168.             foreach k $args {
  169.                 _dict_unset dv $k
  170.             }
  171.             return $dv
  172.         }
  173.         proc _dict_size {dv} {
  174.             return [expr {[llength $dv]/2}]
  175.         }
  176.         proc _dict_values {dv {gp *}} {
  177.             set r [list]
  178.             foreach {k v} $dv {
  179.                 if {[string match $gp $v]} {
  180.                     lappend r $v
  181.                 }
  182.             }
  183.             return $r
  184.         }
  185.     }
Advertisement
Add Comment
Please, Sign In to add comment