File: contain.tcl

package info (click to toggle)
moomps 4.6-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,444 kB
  • ctags: 2,307
  • sloc: tcl: 34,882; sh: 167; makefile: 91
file content (63 lines) | stat: -rw-r--r-- 2,748 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# copyright (C) 1997-2005 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu

# $Id: contain.tcl,v 1.6 2005/01/02 00:45:07 jfontain Exp $


# A simple container scheme that allows hierarchical memory data storage, can be seen as a hierarchy of named associative arrays.
# A container object has a name, can store data in an internal array and knows its children.


class container {

    proc container {this {name {}}} {
        ::set ($this,name) $name                                                                                 ;# read-only member
        ::set ($this,children) {}
    }

    proc ~container {this} {
        variable ${this}data

        eval delete $($this,children)
        catch {unset ${this}data}                                                                                   ;# may not exist
    }

    # public procedures below:

    proc bind {this child} {                                                                   ;# adopt and manage a child container
        lappend ($this,children) $child
    }

    proc set {this name value} {                                                             ;# set a value in the associative array
        variable ${this}data

        ::set ${this}data($name) $value
    }

    proc get {this name} {                                                            ;# retrieve a value from the associative array
        variable ${this}data

        return [::set ${this}data($name)]
    }

    proc equal {container1 container2} {             ;# compare data stored in containers, including data held in children hierarchy
        variable ${container1}data
        variable ${container2}data

        if {\
            ![string equal $($container1,name) $($container2,name)] ||\
            ([array size ${container1}data] != [array size ${container2}data]) ||\
            ([llength $($container1,children)] != [llength $($container2,children)])\
        } {return 0}                                                            ;# stop at first trivial and fast comparison failure
        foreach\
            name1 [lsort -dictionary [array names ${container1}data]] name2 [lsort -dictionary [array names ${container2}data]] {
            if {![string equal $name1 $name2]} {return 0}
            if {![string equal [::set ${container1}data($name1)] [::set ${container2}data($name2)]]} {return 0}
        }
        foreach child1 $($container1,children) child2 $($container2,children) {
            if {![equal $child1 $child2]} {return 0}                                                        ;# recurse with children
        }
        return 1
    }

}