Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/media/tcl/init.tcl @ 5587

Last change on this file since 5587 was 5586, checked in by landauf, 15 years ago

fixed a problem with orxonox' wrapper of the unknown proc
added some path utilities: [pwd], [psd] and [pld] for working, start and library directory respectively ($pwd, $psd and $pld are the corresponding variables)

File size: 7.2 KB
Line 
1namespace eval orxonox {}
2
3# query --
4# Sends a query to the CommandExecutor of Orxonox and waits for the response.
5# This dummy procedure will be changed to it's real implementation by Orxonox itself.
6#
7# Arguments:
8# args - The command to send to Orxonox
9
10proc query args {
11    return -code error "Can't query Orxonox now"
12}
13
14
15# crossquery --
16# Sends a query to another Tcl-interpreter in Orxonox and waits for the response.
17# This dummy procedure will be changed to it's real implementation by Orxonox itself.
18#
19# Arguments:
20# id   - The ID of the other interpreter
21# args - The command to send to Orxonox
22
23proc crossquery {id args} {
24    return -code error "Can't query interpreter with ID $id now"
25}
26
27
28# execute --
29# Sends a command to the queue of Orxonox where it will be executed by the CommandExecutor after some time
30# This dummy procedure will be changed to it's real implementation by Orxonox itself.
31#
32# Arguments:
33# args - The command
34
35proc execute args {
36    return -code error "Can't execute a command now"
37}
38
39
40# crossexecute --
41# Sends a command to the queue of another Tcl-interpreter where it will be executed by after some time
42# This dummy procedure will be changed to it's real implementation by Orxonox itself.
43#
44# Arguments:
45# id   - The ID of the other interpreter
46# args - The command
47
48proc crossexecute {id args} {
49    return -code error "Can't execute a command now"
50}
51
52
53# running --
54# Returns true if the interpreter is still suposed to be running
55# This dummy procedure will be changed to it's real implementation by Orxonox itself.
56
57proc running {} {
58    return 1
59}
60
61
62# orxonox::while --
63# Works like while but breaks the loop if orxonox::running returns false
64
65proc ::orxonox::while {condition body} {
66    set condition_cmd [list expr $condition]
67    ::tcl::while {1} {
68        if {![uplevel 1 $condition_cmd] || ![::running]} {
69            break
70        }
71        uplevel 1 $body
72    }
73}
74
75
76# orxonox::for --
77# Works like for but breaks the loop if orxonox::running returns false
78
79proc ::orxonox::for {start condition step body} {
80    set condition_cmd [list expr $condition]
81    uplevel 1 $start
82    ::tcl::while {1} {
83        if {![uplevel 1 $condition_cmd] || ![::running]} {
84            break
85        }
86        uplevel 1 $body
87        uplevel 1 $step
88    }
89}
90
91
92# add the path to this file to the auto path
93
94set filepath [info script]
95#set ::orxonox::mediapath [string range $filepath 0 [string last "/" $filepath]]
96set ::orxonox::mediapath [file dirname $filepath]
97if {[lsearch $auto_path $::orxonox::mediapath] == -1} {
98    lappend auto_path $::orxonox::mediapath
99}
100unset filepath
101
102
103# save the start directory and the library directory
104
105proc psd {} "return [pwd]"
106proc pld {} "return $::orxonox::mediapath"
107
108set pwd [pwd]
109set psd [psd]
110set pld [pld]
111
112
113# modify cd to automatically set $pwd
114
115if {[llength [info command ::tcl::cd]] == 0} {
116    rename cd ::tcl::cd
117}
118proc cd {{path "~"}} {
119    global pwd
120    ::tcl::cd $path
121    set pwd [pwd]
122}
123
124
125# change the working directory to the media path
126
127cd $::orxonox::mediapath
128
129
130# Redefines puts to write directly into the Orxonox console if the channel is stdout or stderr.
131
132if {[llength [info command ::tcl::puts]] == 0} {
133    rename puts ::tcl::puts
134}
135proc puts args {
136    set argc [llength $args]
137    if {$argc < 1 || $argc > 3} {
138        error "wrong # args: should be \"puts ?-nonewline? ?channelId? string\""
139    }
140
141    set newline 1
142    set input $args
143
144    if {$argc > 1 && [lindex $input 0] == "-nonewline"} {
145        set newline 0
146        set input [lrange $input 1 end]
147    } elseif {$argc == 3} {
148        if {[lindex $input 2] == "nonewline"} {
149            set newline 0
150            set input [lrange $input 0 1]
151        } else {
152            error "bad argument \"[lindex $input 2]\": should be \"nonewline\""
153        }
154    }
155
156    if {[llength $input] == 1} {
157        set input [list stdout [join $input]]
158    }
159
160    foreach {channel s} $input break
161
162    if {$channel == "stdout" || $channel == "stderr"} {
163        execute puts $newline $s
164    } else {
165        ::tcl::puts $args
166    }
167}
168
169
170# Redefines unknown to send unknown commands back to orxonox
171
172if {[llength [info commands unknown]] != 0} {
173    # check if a command named "undefined_proc" exists, if yes rename it temporarily
174    set undefined_was_defined 0
175    if {[llength [info commands undefined_proc]] != 0} {
176        set undefined_was_defined 0
177        rename undefined_proc _undefined
178    }
179
180    # get the returned errormessage if an undefined_proc command is called
181    if {[llength [info commands ::tcl::unknown]] == 0} {
182        set errorcode [catch {unknown undefined_proc} result options]
183    } else {
184        set errorcode [catch {::tcl::unknown undefined_proc} result options]
185    }
186
187    if {$errorcode} {
188        set result_list [split $result]
189        set ::orxonox::errormessage_unknown [list]
190
191        # parse the error message (the original message was something like "invalid command name "undefined_proc"" but we just want "invalid command name")
192        foreach token $result_list {
193            if {![string match "*undefined_proc*" $token]} {
194                lappend ::orxonox::errormessage_unknown $token
195            }
196        }
197
198        unset result_list
199        unset token
200
201        set ::orxonox::errormessage_unknown_length [llength $::orxonox::errormessage_unknown]
202
203        # rename the original unknown procedure
204        if {[llength [info commands ::tcl::unknown]] == 0} {
205            rename unknown ::tcl::unknown
206        }
207
208        # define the modified version of unknown
209        proc unknown args {
210            global ::orxonox::errormessage_unknown ::orxonox::errormessage_unknown_length
211
212            set cmd [concat ::tcl::unknown $args]
213            set errorcode [catch {eval $cmd} result options]
214            set resultlist [split $result]
215            set success 1
216
217            if {$errorcode && [llength $resultlist] >= $::orxonox::errormessage_unknown_length} {
218                for {set i 0} {$i < $::orxonox::errormessage_unknown_length} {incr i} {
219                    if {[lindex $::orxonox::errormessage_unknown $i] != [lindex $resultlist $i]} {
220                        set success 0
221                        break
222                    }
223                }
224            } else {
225                set success 0
226            }
227
228            if {!$success} {
229                return -code $errorcode -options $options $result
230            } else {
231                return [query $args]
232            }
233        }
234
235        set success 1
236    } else {
237        set success 0
238    }
239
240    unset errorcode
241    unset result
242    unset options
243
244    # if the "undefined_proc" command was renamed previously, undo this
245    if {$undefined_was_defined} {
246        rename _undefined undefined_proc
247    }
248
249    unset undefined_was_defined
250
251    if {!$success} {
252        unset success
253        # something went wrong, use the default method
254        proc unknown args {
255            return [query $args]
256        }
257    }
258    unset success
259} else {
260    # no original unknown procedure defined, use the default method
261    proc unknown args {
262        return [query $args]
263    }
264}
Note: See TracBrowser for help on using the repository browser.