aboutsummaryrefslogtreecommitdiff
path: root/contrib/bluegnu2.0.3/lib/Types.itcl
blob: e2ef2b414bf116961d48b2ef854f38d4b61b15ad (plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# -*-Tcl-*-
#
# This [incr Tcl] library script contains type definitions
#
#
# Type super class
#

if {[string length [info commands debug]] == 0} {
    proc debug {args} {}
}

class Type {
    variable _value
    variable _valueSaved
    variable _voidPtr
    variable _bVoid
    protected variable _currentNamespace
    protected variable _lProc
    protected variable _upLevel

    constructor args {
	debug {======= Constructor: [info class] $this $args} 3
	# Go up in the inheritance tree
	debug {        Go up inheritance tree} 4
	set level 1
	if {[string compare [info class] ::Type] != 0} {
	    debug {        level set to >1<} 5
	    while {[string compare [info class] \
		    [uplevel $level {namespace current}]] != 0} {
		debug {>[info class]< != >[uplevel $level\
			{namespace current}]<} 5
		incr level
		debug {        level incrmented to >$level<} 5
	    }
	    debug {>[info class]< == >[uplevel $level\
		    {namespace current}]<} 5
	    incr level
	    regsub {^::} [uplevel $level {namespace current}] "" currentNamespace
	} else {
	    regsub {^::} [uplevel {namespace current}] "" currentNamespace
	}
	set upLevel [expr [info level] - $level]
	set lProc [info level $upLevel]
	debug {    Called from level: >$upLevel<} 4
	debug {    Called from      : >$lProc<} 4
	debug {    Current namespace: >$currentNamespace<} 4
	#catch {puts "     [uplevel "info body [lindex $lProc 0]"]"}
	set _bVoid 0
	set _voidPtr 0
	if {[llength $args] > 0} {
	    set _value [lindex $args 0]
	} else {
	    set  _value ""
	}
	if {$upLevel == 0} {
	    debug {Called from global} 4
	    set $this $_value
	    debug {this variable: [set $this]} 4
	    trace variable $this rwu traceType
	} elseif {[string length $currentNamespace] && \
		[string length $lProc]} {
	    debug {Called from procedure in namespace} 4
	    debug {   this: >$this<} 4
	    debug {set $this >$_value<}
	    catch {
		uplevel #$upLevel set [namespace tail $this] \"$_value\"
		uplevel #$upLevel trace variable [namespace tail $this] \
			rwu traceType
	    } szErrMsg; debug {    szErrMsg: >$szErrMsg<} 4
	} elseif {[string length $currentNamespace]} {
	    debug {Called from namespace} 4
	    debug {set $this >$_value<}
	    catch {
		namespace eval ${currentNamespace} "set $this \"$_value\"\n\
			trace variable $this rwu traceType"
	    } szErrMsg
	    debug {    TRACE set} 4
		debug {    szErrMsg: >$szErrMsg<} 4
	} else {
	    debug {Called from procedure} 4
	    set var [namespace tail $this]
	    uplevel "set $var $_value"
	    debug {this variable: [uplevel "set $var"]} 4
	    uplevel "trace variable $var rwu traceType"
	}
    }

    destructor {
	debug {======= destructor $this} 3
	set calledFrom [lindex [split [info level [expr [info level] - 1]]] 0]
	debug {        calledFrom: >$calledFrom<} 4
	debug {        >[info level [expr [info level] - 1]]<} 4
	# just return when called from traceType
	if {[string compare $calledFrom "traceType"] != 0} {
	    set var [namespace tail $this]
	    debug {   var: >$var<} 4
	    debug {        >[join [trace vinfo $var]]<} 4
	    debug {        >[uplevel [join [trace vinfo $var]]]<} 4
	    debug {        >[join [uplevel "trace vinfo $var"]]<} 4
	    catch {
		debug {eval uplevel \"trace vdelete $var [join [uplevel "trace vinfo $var"]]\"} 4
		eval uplevel "trace vdelete $var [join [uplevel "trace vinfo $var"]]"
		uplevel unset $var
	    } szErrMsg; debug {   #### szErrMsg: >$szErrMsg<} 4
	}
    }

    public method value {args} {
	if {[llength $args] > 0} {
	    set _value [lindex $args 0]
	}
	return $_value
    }

    public method setNull {{ptr 0}} {
	set _voidPtr $ptr
	set _bVoid 1
    }

    public method unsetNull {} {
	set _bVoid 0
    }

    public method isNull {} {
	return $_bVoid
    }

    public method getNull {} {
	return $_voidPtr
    }
}

proc traceType {name1 name2 ops} {
    debug {======= traceType >$name1< >$name2< >$ops<} 3
    upvar $name1 var
    set upLevel [expr [info level] - 1]
    set lProc [info level $upLevel]
    regsub {^::} [uplevel {namespace current}] "" currentNamespace
    debug {    Called from level: >$upLevel<} 4
    debug {    level namespace  : >[uplevel #$upLevel namespace current]<} 4
    debug {    Called from      : >$lProc<} 4
    debug {    Current namespace: >$currentNamespace<} 4
    if {$upLevel == 0} {
	debug {Called from global} 4
	switch $ops {
	    r {
		set var [uplevel $name1 value]
	    }
	    w {
		if [catch {$name1 value [set var]}] {
		    uplevel "$name1 value [set var]"
		}
	    }
	    u {
		uplevel delete object $name1
	    }
	}
    } elseif {[string length $currentNamespace] && \
		[string length $lProc]} {
	debug {Called from procedure in namespace} 4
	set var [uplevel ::itcl::find objects $name1]
	debug {    $name1 ->$var< = ><} 4
	switch $ops {
	    r {
		uplevel set $name1 [uplevel $var value]
	    }
	    w {
		if [catch {uplevel $var value [uplevel set $name1]} szErrMsg] {
		    debug {####### Error: $szErrMsg} 4
		    
		}  
	    }
	    u {
		uplevel delete object $name1
	    }
	}
    } elseif {[string length $currentNamespace]} {
	debug {Called from namespace} 4
	set var [uplevel "namespace which -variable $name1"]
	debug {    $name1 ->$var< = ><} 4
	switch $ops {
	    r {
		set $var [$var value]
	    }
	    w {
		if [catch {$var value [set $var]} szErrMsg] {
		    debug {####### Error: $szErrMsg} 4
		    
		}  
	    }
	    u {
		debug {Deleting >$name1<} 4
		debug {          [namespace current]} 4
		catch {delete object $name1}
		debug {          DONE!} 4
	    }
	}
    } else {
	debug {Called from procedure} 4
	switch $ops {
	    r {
		set $name1 [$name1 value]
	    }
	    w {
		if [catch {$name1 value [uplevel set $name1]}] {
		    uplevel "$name1 value [set $name1]"
		}
	    }
	    u {
		delete object $name1
	    }
	}
    }
}