Fossil SCM

Update autosetup to v0.6.6

jan.nijtmans 2017-05-10 09:22 trunk merge
Commit c5e41007050b7c48a718ca06a5aec0331ddf77bd5d2d9447261996a515fe7e1a
+110 -65
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -59,27 +59,34 @@
5959
if {[getenv WRAPPER ""] eq ""} {
6060
# Invoked directly
6161
set autosetup(srcdir) [pwd]
6262
} else {
6363
# Invoked via the configure wrapper
64
- set autosetup(srcdir) [file dirname $autosetup(exe)]
64
+ set autosetup(srcdir) [file-normalize [file dirname $autosetup(exe)]]
6565
}
6666
set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def]
6767
6868
# (c)
6969
set autosetup(builddir) [pwd]
7070
7171
set autosetup(argv) $argv
7272
set autosetup(cmdline) {}
73
+ # options is a list of known options
7374
set autosetup(options) {}
75
+ # optset is a dictionary of option values set by the user based on getopt
76
+ set autosetup(optset) {}
77
+ # optdefault is a dictionary of default values for options
78
+ set autosetup(optdefault) {}
7479
set autosetup(optionhelp) {}
7580
set autosetup(showhelp) 0
7681
7782
# Parse options
7883
use getopt
7984
80
- array set ::useropts [getopt argv]
85
+ # At the is point we don't know what is a valid option
86
+ # We simply parse anything that looks like an option
87
+ set autosetup(getopt) [getopt argv]
8188
8289
#"=Core Options:"
8390
options-add {
8491
help:=local => "display help and options. Optionally specify a module name, such as --help=system"
8592
version => "display the version of autosetup"
@@ -94,11 +101,10 @@
94101
quiet
95102
timing
96103
conf:
97104
}
98105
99
- #parray ::useropts
100106
if {[opt-bool version]} {
101107
puts $autosetup(version)
102108
exit 0
103109
}
104110
@@ -198,20 +204,41 @@
198204
}
199205
200206
exit 0
201207
}
202208
203
-# @opt-bool option ...
209
+# @opt-bool ?-nodefault? option ...
204210
#
205
-# Check each of the named, boolean options and return 1 if any of them have
206
-# been set by the user.
211
+# Check each of the named, boolean options and if any have been explicitly enabled
212
+# or disabled by the user, return 1 or 0 accordingly.
213
+#
207214
# If the option was specified more than once, the last value wins.
208215
# e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0
209216
#
217
+# If no value was specified by the user, returns the default value for the
218
+# first option. If -nodefault is given, this behaviour changes and
219
+# -1 is returned instead.
220
+#
210221
proc opt-bool {args} {
222
+ set nodefault 0
223
+ if {[lindex $args 0] eq "-nodefault"} {
224
+ set nodefault 1
225
+ set args [lrange $args 1 end]
226
+ }
211227
option-check-names {*}$args
212
- opt_bool ::useropts {*}$args
228
+
229
+ foreach opt $args {
230
+ if {[dict exists $::autosetup(optset) $opt]} {
231
+ return [dict get $::autosetup(optset) $opt]
232
+ }
233
+ }
234
+
235
+ if {$nodefault} {
236
+ return -1
237
+ }
238
+ # Default value is the default for the first option
239
+ return [dict get $::autosetup(optdefault) [lindex $args 0]]
213240
}
214241
215242
# @opt-val option-list ?default=""?
216243
#
217244
# Returns a list containing all the values given for the non-boolean options in 'option-list'.
@@ -223,11 +250,20 @@
223250
#
224251
# If no options were set, $default is returned (exactly, not as a list).
225252
#
226253
proc opt-val {names {default ""}} {
227254
option-check-names {*}$names
228
- join [opt_val ::useropts $names $default]
255
+
256
+ foreach opt $names {
257
+ if {[dict exists $::autosetup(optset) $opt]} {
258
+ lappend result {*}[dict get $::autosetup(optset) $opt]
259
+ }
260
+ }
261
+ if {[info exists result]} {
262
+ return $result
263
+ }
264
+ return $default
229265
}
230266
231267
proc option-check-names {args} {
232268
foreach o $args {
233269
if {$o ni $::autosetup(options)} {
@@ -235,14 +271,14 @@
235271
}
236272
}
237273
}
238274
239275
# Parse the option definition in $opts and update
240
-# ::useropts() and ::autosetup(optionhelp) appropriately
276
+# ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately
241277
#
242278
proc options-add {opts {header ""}} {
243
- global useropts autosetup
279
+ global autosetup
244280
245281
# First weed out comment lines
246282
set realopts {}
247283
foreach line [split $opts \n] {
248284
if {![string match "#*" [string trimleft $line]]} {
@@ -275,34 +311,70 @@
275311
set opthelp $opt
276312
} elseif {$colon eq ""} {
277313
# Boolean option
278314
lappend autosetup(options) $name
279315
280
- if {![info exists useropts($name)]} {
281
- set useropts($name) $value
282
- }
283316
if {$value eq "1"} {
284317
set opthelp "--disable-$name"
285318
} else {
286319
set opthelp "--$name"
287320
}
321
+
322
+ # Set the default
323
+ if {$value eq ""} {
324
+ set value 0
325
+ }
326
+ dict set autosetup(optdefault) $name $value
327
+
328
+ if {[dict exists $autosetup(getopt) $name]} {
329
+ # The option was specified by the user. Look at the last value.
330
+ lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue
331
+ if {$type eq "str"} {
332
+ # Can we convert the value to a boolean?
333
+ if {$setvalue in {1 enabled yes}} {
334
+ set setvalue 1
335
+ } elseif {$setvalue in {0 disabled no}} {
336
+ set setvalue 0
337
+ } else {
338
+ user-error "Boolean option $name given as --$name=$setvalue"
339
+ }
340
+ }
341
+ dict set autosetup(optset) $name $setvalue
342
+ #puts "Found boolean option --$name=$setvalue"
343
+ }
288344
} else {
289345
# String option.
290346
lappend autosetup(options) $name
291347
292348
if {$equal eq "="} {
293
- if {[info exists useropts($name)]} {
294
- # If the user specified the option with no value, the value will be "1"
295
- # Replace with the default
296
- if {$useropts($name) eq "1"} {
297
- set useropts($name) $value
298
- }
299
- }
349
+ # String option with optional value
300350
set opthelp "--$name?=$value?"
301351
} else {
352
+ # String option with required value
302353
set opthelp "--$name=$value"
303354
}
355
+ dict set autosetup(optdefault) $name $value
356
+
357
+ # Get the values specified by the user
358
+ if {[dict exists $autosetup(getopt) $name]} {
359
+ set listvalue {}
360
+
361
+ foreach pair [dict get $autosetup(getopt) $name] {
362
+ lassign $pair type setvalue
363
+ if {$type eq "bool" && $setvalue} {
364
+ if {$equal ne "="} {
365
+ user-error "Option --$name requires a value"
366
+ }
367
+ # If given as a boolean, use the default value
368
+ set setvalue $value
369
+ }
370
+ lappend listvalue $setvalue
371
+ }
372
+
373
+ #puts "Found string option --$name=$listvalue"
374
+ dict set autosetup(optset) $name $listvalue
375
+ }
304376
}
305377
306378
# Now create the help for this option if appropriate
307379
if {[lindex $opts $i+1] eq "=>"} {
308380
set desc [lindex $opts $i+2]
@@ -430,11 +502,11 @@
430502
exit 0
431503
}
432504
433505
# Check for invalid options
434506
if {[opt-bool option-checking]} {
435
- foreach o [array names ::useropts] {
507
+ foreach o [dict keys $::autosetup(getopt)] {
436508
if {$o ni $::autosetup(options)} {
437509
user-error "Unknown option --$o"
438510
}
439511
}
440512
}
@@ -1096,16 +1168,22 @@
10961168
# All rights reserved
10971169
10981170
# Simple getopt module
10991171
11001172
# Parse everything out of the argv list which looks like an option
1101
-# Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
11021173
# Everything which doesn't look like an option, or is after --, is left unchanged
1174
+# Understands --enable-xxx and --with-xxx as synonyms for --xxx to enable the boolean option xxx.
1175
+# Understands --disable-xxx and --without-xxx to disable the boolean option xxx.
11031176
#
1177
+# The returned value is a dictionary keyed by option name
1178
+# Each value is a list of {type value} ... where type is "bool" or "str".
1179
+# The value for a boolean option is 0 or 1. The value of a string option is the value given.
11041180
proc getopt {argvname} {
11051181
upvar $argvname argv
11061182
set nargv {}
1183
+
1184
+ set opts {}
11071185
11081186
for {set i 0} {$i < [llength $argv]} {incr i} {
11091187
set arg [lindex $argv $i]
11101188
11111189
#dputs arg=$arg
@@ -1116,64 +1194,31 @@
11161194
lappend nargv {*}[lrange $argv $i end]
11171195
break
11181196
}
11191197
11201198
if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} {
1121
- lappend opts($name) $value
1122
- } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} {
1123
- if {$prefix eq "disable-"} {
1124
- set value 0
1199
+ # --name=value
1200
+ dict lappend opts $name [list str $value]
1201
+ } elseif {[regexp {^--(enable-|disable-|with-|without-)?([^=]*)$} $arg -> prefix name]} {
1202
+ if {$prefix in {enable- with- ""}} {
1203
+ set value 1
11251204
} else {
1126
- set value 1
1205
+ set value 0
11271206
}
1128
- lappend opts($name) $value
1207
+ dict lappend opts $name [list bool $value]
11291208
} else {
11301209
lappend nargv $arg
11311210
}
11321211
}
11331212
11341213
#puts "getopt: argv=[join $argv] => [join $nargv]"
1135
- #parray opts
1214
+ #array set getopt $opts
1215
+ #parray getopt
11361216
11371217
set argv $nargv
11381218
1139
- return [array get opts]
1140
-}
1141
-
1142
-proc opt_val {optarrayname options {default {}}} {
1143
- upvar $optarrayname opts
1144
-
1145
- set result {}
1146
-
1147
- foreach o $options {
1148
- if {[info exists opts($o)]} {
1149
- lappend result {*}$opts($o)
1150
- }
1151
- }
1152
- if {[llength $result] == 0} {
1153
- return $default
1154
- }
1155
- return $result
1156
-}
1157
-
1158
-proc opt_bool {optarrayname args} {
1159
- upvar $optarrayname opts
1160
-
1161
- # Support the args being passed as a list
1162
- if {[llength $args] == 1} {
1163
- set args [lindex $args 0]
1164
- }
1165
-
1166
- foreach o $args {
1167
- if {[info exists opts($o)]} {
1168
- # For boolean options, the last value wins
1169
- if {[lindex $opts($o) end] in {"1" "yes"}} {
1170
- return 1
1171
- }
1172
- }
1173
- }
1174
- return 0
1219
+ return $opts
11751220
}
11761221
}
11771222
11781223
# ----- module help -----
11791224
11801225
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -59,27 +59,34 @@
59 if {[getenv WRAPPER ""] eq ""} {
60 # Invoked directly
61 set autosetup(srcdir) [pwd]
62 } else {
63 # Invoked via the configure wrapper
64 set autosetup(srcdir) [file dirname $autosetup(exe)]
65 }
66 set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def]
67
68 # (c)
69 set autosetup(builddir) [pwd]
70
71 set autosetup(argv) $argv
72 set autosetup(cmdline) {}
 
73 set autosetup(options) {}
 
 
 
 
74 set autosetup(optionhelp) {}
75 set autosetup(showhelp) 0
76
77 # Parse options
78 use getopt
79
80 array set ::useropts [getopt argv]
 
 
81
82 #"=Core Options:"
83 options-add {
84 help:=local => "display help and options. Optionally specify a module name, such as --help=system"
85 version => "display the version of autosetup"
@@ -94,11 +101,10 @@
94 quiet
95 timing
96 conf:
97 }
98
99 #parray ::useropts
100 if {[opt-bool version]} {
101 puts $autosetup(version)
102 exit 0
103 }
104
@@ -198,20 +204,41 @@
198 }
199
200 exit 0
201 }
202
203 # @opt-bool option ...
204 #
205 # Check each of the named, boolean options and return 1 if any of them have
206 # been set by the user.
 
207 # If the option was specified more than once, the last value wins.
208 # e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0
209 #
 
 
 
 
210 proc opt-bool {args} {
 
 
 
 
 
211 option-check-names {*}$args
212 opt_bool ::useropts {*}$args
 
 
 
 
 
 
 
 
 
 
 
213 }
214
215 # @opt-val option-list ?default=""?
216 #
217 # Returns a list containing all the values given for the non-boolean options in 'option-list'.
@@ -223,11 +250,20 @@
223 #
224 # If no options were set, $default is returned (exactly, not as a list).
225 #
226 proc opt-val {names {default ""}} {
227 option-check-names {*}$names
228 join [opt_val ::useropts $names $default]
 
 
 
 
 
 
 
 
 
229 }
230
231 proc option-check-names {args} {
232 foreach o $args {
233 if {$o ni $::autosetup(options)} {
@@ -235,14 +271,14 @@
235 }
236 }
237 }
238
239 # Parse the option definition in $opts and update
240 # ::useropts() and ::autosetup(optionhelp) appropriately
241 #
242 proc options-add {opts {header ""}} {
243 global useropts autosetup
244
245 # First weed out comment lines
246 set realopts {}
247 foreach line [split $opts \n] {
248 if {![string match "#*" [string trimleft $line]]} {
@@ -275,34 +311,70 @@
275 set opthelp $opt
276 } elseif {$colon eq ""} {
277 # Boolean option
278 lappend autosetup(options) $name
279
280 if {![info exists useropts($name)]} {
281 set useropts($name) $value
282 }
283 if {$value eq "1"} {
284 set opthelp "--disable-$name"
285 } else {
286 set opthelp "--$name"
287 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288 } else {
289 # String option.
290 lappend autosetup(options) $name
291
292 if {$equal eq "="} {
293 if {[info exists useropts($name)]} {
294 # If the user specified the option with no value, the value will be "1"
295 # Replace with the default
296 if {$useropts($name) eq "1"} {
297 set useropts($name) $value
298 }
299 }
300 set opthelp "--$name?=$value?"
301 } else {
 
302 set opthelp "--$name=$value"
303 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304 }
305
306 # Now create the help for this option if appropriate
307 if {[lindex $opts $i+1] eq "=>"} {
308 set desc [lindex $opts $i+2]
@@ -430,11 +502,11 @@
430 exit 0
431 }
432
433 # Check for invalid options
434 if {[opt-bool option-checking]} {
435 foreach o [array names ::useropts] {
436 if {$o ni $::autosetup(options)} {
437 user-error "Unknown option --$o"
438 }
439 }
440 }
@@ -1096,16 +1168,22 @@
1096 # All rights reserved
1097
1098 # Simple getopt module
1099
1100 # Parse everything out of the argv list which looks like an option
1101 # Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
1102 # Everything which doesn't look like an option, or is after --, is left unchanged
 
 
1103 #
 
 
 
1104 proc getopt {argvname} {
1105 upvar $argvname argv
1106 set nargv {}
 
 
1107
1108 for {set i 0} {$i < [llength $argv]} {incr i} {
1109 set arg [lindex $argv $i]
1110
1111 #dputs arg=$arg
@@ -1116,64 +1194,31 @@
1116 lappend nargv {*}[lrange $argv $i end]
1117 break
1118 }
1119
1120 if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} {
1121 lappend opts($name) $value
1122 } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} {
1123 if {$prefix eq "disable-"} {
1124 set value 0
 
1125 } else {
1126 set value 1
1127 }
1128 lappend opts($name) $value
1129 } else {
1130 lappend nargv $arg
1131 }
1132 }
1133
1134 #puts "getopt: argv=[join $argv] => [join $nargv]"
1135 #parray opts
 
1136
1137 set argv $nargv
1138
1139 return [array get opts]
1140 }
1141
1142 proc opt_val {optarrayname options {default {}}} {
1143 upvar $optarrayname opts
1144
1145 set result {}
1146
1147 foreach o $options {
1148 if {[info exists opts($o)]} {
1149 lappend result {*}$opts($o)
1150 }
1151 }
1152 if {[llength $result] == 0} {
1153 return $default
1154 }
1155 return $result
1156 }
1157
1158 proc opt_bool {optarrayname args} {
1159 upvar $optarrayname opts
1160
1161 # Support the args being passed as a list
1162 if {[llength $args] == 1} {
1163 set args [lindex $args 0]
1164 }
1165
1166 foreach o $args {
1167 if {[info exists opts($o)]} {
1168 # For boolean options, the last value wins
1169 if {[lindex $opts($o) end] in {"1" "yes"}} {
1170 return 1
1171 }
1172 }
1173 }
1174 return 0
1175 }
1176 }
1177
1178 # ----- module help -----
1179
1180
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -59,27 +59,34 @@
59 if {[getenv WRAPPER ""] eq ""} {
60 # Invoked directly
61 set autosetup(srcdir) [pwd]
62 } else {
63 # Invoked via the configure wrapper
64 set autosetup(srcdir) [file-normalize [file dirname $autosetup(exe)]]
65 }
66 set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def]
67
68 # (c)
69 set autosetup(builddir) [pwd]
70
71 set autosetup(argv) $argv
72 set autosetup(cmdline) {}
73 # options is a list of known options
74 set autosetup(options) {}
75 # optset is a dictionary of option values set by the user based on getopt
76 set autosetup(optset) {}
77 # optdefault is a dictionary of default values for options
78 set autosetup(optdefault) {}
79 set autosetup(optionhelp) {}
80 set autosetup(showhelp) 0
81
82 # Parse options
83 use getopt
84
85 # At the is point we don't know what is a valid option
86 # We simply parse anything that looks like an option
87 set autosetup(getopt) [getopt argv]
88
89 #"=Core Options:"
90 options-add {
91 help:=local => "display help and options. Optionally specify a module name, such as --help=system"
92 version => "display the version of autosetup"
@@ -94,11 +101,10 @@
101 quiet
102 timing
103 conf:
104 }
105
 
106 if {[opt-bool version]} {
107 puts $autosetup(version)
108 exit 0
109 }
110
@@ -198,20 +204,41 @@
204 }
205
206 exit 0
207 }
208
209 # @opt-bool ?-nodefault? option ...
210 #
211 # Check each of the named, boolean options and if any have been explicitly enabled
212 # or disabled by the user, return 1 or 0 accordingly.
213 #
214 # If the option was specified more than once, the last value wins.
215 # e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0
216 #
217 # If no value was specified by the user, returns the default value for the
218 # first option. If -nodefault is given, this behaviour changes and
219 # -1 is returned instead.
220 #
221 proc opt-bool {args} {
222 set nodefault 0
223 if {[lindex $args 0] eq "-nodefault"} {
224 set nodefault 1
225 set args [lrange $args 1 end]
226 }
227 option-check-names {*}$args
228
229 foreach opt $args {
230 if {[dict exists $::autosetup(optset) $opt]} {
231 return [dict get $::autosetup(optset) $opt]
232 }
233 }
234
235 if {$nodefault} {
236 return -1
237 }
238 # Default value is the default for the first option
239 return [dict get $::autosetup(optdefault) [lindex $args 0]]
240 }
241
242 # @opt-val option-list ?default=""?
243 #
244 # Returns a list containing all the values given for the non-boolean options in 'option-list'.
@@ -223,11 +250,20 @@
250 #
251 # If no options were set, $default is returned (exactly, not as a list).
252 #
253 proc opt-val {names {default ""}} {
254 option-check-names {*}$names
255
256 foreach opt $names {
257 if {[dict exists $::autosetup(optset) $opt]} {
258 lappend result {*}[dict get $::autosetup(optset) $opt]
259 }
260 }
261 if {[info exists result]} {
262 return $result
263 }
264 return $default
265 }
266
267 proc option-check-names {args} {
268 foreach o $args {
269 if {$o ni $::autosetup(options)} {
@@ -235,14 +271,14 @@
271 }
272 }
273 }
274
275 # Parse the option definition in $opts and update
276 # ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately
277 #
278 proc options-add {opts {header ""}} {
279 global autosetup
280
281 # First weed out comment lines
282 set realopts {}
283 foreach line [split $opts \n] {
284 if {![string match "#*" [string trimleft $line]]} {
@@ -275,34 +311,70 @@
311 set opthelp $opt
312 } elseif {$colon eq ""} {
313 # Boolean option
314 lappend autosetup(options) $name
315
 
 
 
316 if {$value eq "1"} {
317 set opthelp "--disable-$name"
318 } else {
319 set opthelp "--$name"
320 }
321
322 # Set the default
323 if {$value eq ""} {
324 set value 0
325 }
326 dict set autosetup(optdefault) $name $value
327
328 if {[dict exists $autosetup(getopt) $name]} {
329 # The option was specified by the user. Look at the last value.
330 lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue
331 if {$type eq "str"} {
332 # Can we convert the value to a boolean?
333 if {$setvalue in {1 enabled yes}} {
334 set setvalue 1
335 } elseif {$setvalue in {0 disabled no}} {
336 set setvalue 0
337 } else {
338 user-error "Boolean option $name given as --$name=$setvalue"
339 }
340 }
341 dict set autosetup(optset) $name $setvalue
342 #puts "Found boolean option --$name=$setvalue"
343 }
344 } else {
345 # String option.
346 lappend autosetup(options) $name
347
348 if {$equal eq "="} {
349 # String option with optional value
 
 
 
 
 
 
350 set opthelp "--$name?=$value?"
351 } else {
352 # String option with required value
353 set opthelp "--$name=$value"
354 }
355 dict set autosetup(optdefault) $name $value
356
357 # Get the values specified by the user
358 if {[dict exists $autosetup(getopt) $name]} {
359 set listvalue {}
360
361 foreach pair [dict get $autosetup(getopt) $name] {
362 lassign $pair type setvalue
363 if {$type eq "bool" && $setvalue} {
364 if {$equal ne "="} {
365 user-error "Option --$name requires a value"
366 }
367 # If given as a boolean, use the default value
368 set setvalue $value
369 }
370 lappend listvalue $setvalue
371 }
372
373 #puts "Found string option --$name=$listvalue"
374 dict set autosetup(optset) $name $listvalue
375 }
376 }
377
378 # Now create the help for this option if appropriate
379 if {[lindex $opts $i+1] eq "=>"} {
380 set desc [lindex $opts $i+2]
@@ -430,11 +502,11 @@
502 exit 0
503 }
504
505 # Check for invalid options
506 if {[opt-bool option-checking]} {
507 foreach o [dict keys $::autosetup(getopt)] {
508 if {$o ni $::autosetup(options)} {
509 user-error "Unknown option --$o"
510 }
511 }
512 }
@@ -1096,16 +1168,22 @@
1168 # All rights reserved
1169
1170 # Simple getopt module
1171
1172 # Parse everything out of the argv list which looks like an option
 
1173 # Everything which doesn't look like an option, or is after --, is left unchanged
1174 # Understands --enable-xxx and --with-xxx as synonyms for --xxx to enable the boolean option xxx.
1175 # Understands --disable-xxx and --without-xxx to disable the boolean option xxx.
1176 #
1177 # The returned value is a dictionary keyed by option name
1178 # Each value is a list of {type value} ... where type is "bool" or "str".
1179 # The value for a boolean option is 0 or 1. The value of a string option is the value given.
1180 proc getopt {argvname} {
1181 upvar $argvname argv
1182 set nargv {}
1183
1184 set opts {}
1185
1186 for {set i 0} {$i < [llength $argv]} {incr i} {
1187 set arg [lindex $argv $i]
1188
1189 #dputs arg=$arg
@@ -1116,64 +1194,31 @@
1194 lappend nargv {*}[lrange $argv $i end]
1195 break
1196 }
1197
1198 if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} {
1199 # --name=value
1200 dict lappend opts $name [list str $value]
1201 } elseif {[regexp {^--(enable-|disable-|with-|without-)?([^=]*)$} $arg -> prefix name]} {
1202 if {$prefix in {enable- with- ""}} {
1203 set value 1
1204 } else {
1205 set value 0
1206 }
1207 dict lappend opts $name [list bool $value]
1208 } else {
1209 lappend nargv $arg
1210 }
1211 }
1212
1213 #puts "getopt: argv=[join $argv] => [join $nargv]"
1214 #array set getopt $opts
1215 #parray getopt
1216
1217 set argv $nargv
1218
1219 return $opts
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1220 }
1221 }
1222
1223 # ----- module help -----
1224
1225
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -10,11 +10,11 @@
1010
module-options {}
1111
1212
# @cc-check-lfs
1313
#
1414
# The equivalent of the AC_SYS_LARGEFILE macro
15
-#
15
+#
1616
# defines 'HAVE_LFS' if LFS is available,
1717
# and defines '_FILE_OFFSET_BITS=64' if necessary
1818
#
1919
# Returns 1 if 'LFS' is available or 0 otherwise
2020
#
@@ -36,11 +36,11 @@
3636
}
3737
3838
# @cc-check-endian
3939
#
4040
# The equivalent of the AC_C_BIGENDIAN macro
41
-#
41
+#
4242
# defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
4343
# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
4444
#
4545
# Returns 1 if determined, or 0 if not.
4646
#
@@ -157,5 +157,35 @@
157157
158158
cctest_alignof _Alignof
159159
cctest_alignof __alignof__
160160
cctest_alignof __alignof
161161
}
162
+
163
+# @cc-check-alloca
164
+#
165
+# The equivalent of the AC_FUNC_ALLOCA macro
166
+#
167
+# Checks for the existence of alloca
168
+# defines HAVE_ALLOCA and returns 1 if it exists
169
+proc cc-check-alloca {} {
170
+ cc-check-some-feature alloca {
171
+ cctest -includes alloca.h -code { alloca (2 * sizeof (int)); }
172
+ }
173
+}
174
+
175
+# @cc-signal-return-type
176
+#
177
+# The equivalent of the AC_TYPE_SIGNAL macro
178
+#
179
+# defines RETSIGTYPE to int or void
180
+proc cc-signal-return-type {} {
181
+ msg-checking "Checking return type of signal handlers..."
182
+ cc-with {-includes {sys/types.h signal.h}} {
183
+ if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} {
184
+ set type int
185
+ } else {
186
+ set type void
187
+ }
188
+ define RETSIGTYPE $type
189
+ msg-result $type
190
+ }
191
+}
162192
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -10,11 +10,11 @@
10 module-options {}
11
12 # @cc-check-lfs
13 #
14 # The equivalent of the AC_SYS_LARGEFILE macro
15 #
16 # defines 'HAVE_LFS' if LFS is available,
17 # and defines '_FILE_OFFSET_BITS=64' if necessary
18 #
19 # Returns 1 if 'LFS' is available or 0 otherwise
20 #
@@ -36,11 +36,11 @@
36 }
37
38 # @cc-check-endian
39 #
40 # The equivalent of the AC_C_BIGENDIAN macro
41 #
42 # defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
43 # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
44 #
45 # Returns 1 if determined, or 0 if not.
46 #
@@ -157,5 +157,35 @@
157
158 cctest_alignof _Alignof
159 cctest_alignof __alignof__
160 cctest_alignof __alignof
161 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -10,11 +10,11 @@
10 module-options {}
11
12 # @cc-check-lfs
13 #
14 # The equivalent of the AC_SYS_LARGEFILE macro
15 #
16 # defines 'HAVE_LFS' if LFS is available,
17 # and defines '_FILE_OFFSET_BITS=64' if necessary
18 #
19 # Returns 1 if 'LFS' is available or 0 otherwise
20 #
@@ -36,11 +36,11 @@
36 }
37
38 # @cc-check-endian
39 #
40 # The equivalent of the AC_C_BIGENDIAN macro
41 #
42 # defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
43 # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
44 #
45 # Returns 1 if determined, or 0 if not.
46 #
@@ -157,5 +157,35 @@
157
158 cctest_alignof _Alignof
159 cctest_alignof __alignof__
160 cctest_alignof __alignof
161 }
162
163 # @cc-check-alloca
164 #
165 # The equivalent of the AC_FUNC_ALLOCA macro
166 #
167 # Checks for the existence of alloca
168 # defines HAVE_ALLOCA and returns 1 if it exists
169 proc cc-check-alloca {} {
170 cc-check-some-feature alloca {
171 cctest -includes alloca.h -code { alloca (2 * sizeof (int)); }
172 }
173 }
174
175 # @cc-signal-return-type
176 #
177 # The equivalent of the AC_TYPE_SIGNAL macro
178 #
179 # defines RETSIGTYPE to int or void
180 proc cc-signal-return-type {} {
181 msg-checking "Checking return type of signal handlers..."
182 cc-with {-includes {sys/types.h signal.h}} {
183 if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} {
184 set type int
185 } else {
186 set type void
187 }
188 define RETSIGTYPE $type
189 msg-result $type
190 }
191 }
192
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -62,11 +62,11 @@
6262
}
6363
sparc* {
6464
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
6565
msg-result "Found sun stdio compiler"
6666
# sun stdio compiler
67
- # XXX: These haven't been fully tested.
67
+ # XXX: These haven't been fully tested.
6868
define SHOBJ_CFLAGS -KPIC
6969
define SHOBJ_LDFLAGS "-G"
7070
define SH_CFLAGS -KPIC
7171
define SH_LINKFLAGS -Wl,-export-dynamic
7272
define SH_SOPREFIX -Wl,-h,
@@ -78,11 +78,11 @@
7878
}
7979
*-*-solaris* {
8080
if {[msg-quiet cc-check-decls __SUNPRO_C]} {
8181
msg-result "Found sun stdio compiler"
8282
# sun stdio compiler
83
- # XXX: These haven't been fully tested.
83
+ # XXX: These haven't been fully tested.
8484
define SHOBJ_CFLAGS -KPIC
8585
define SHOBJ_LDFLAGS "-G"
8686
define SH_CFLAGS -KPIC
8787
define SH_LINKFLAGS -Wl,-export-dynamic
8888
define SH_SOPREFIX -Wl,-h,
@@ -103,10 +103,15 @@
103103
define SH_LDFLAGS -shared
104104
define SH_LINKFLAGS ""
105105
define SH_SOPREFIX ""
106106
define LD_LIBRARY_PATH LIBRARY_PATH
107107
}
108
+ microblaze* {
109
+ # Microblaze generally needs -fPIC rather than -fpic
110
+ define SHOBJ_CFLAGS -fPIC
111
+ define SH_CFLAGS -fPIC
112
+ }
108113
}
109114
110115
if {![is-defined SHOBJ_LDFLAGS_R]} {
111116
define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
112117
}
113118
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -62,11 +62,11 @@
62 }
63 sparc* {
64 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
65 msg-result "Found sun stdio compiler"
66 # sun stdio compiler
67 # XXX: These haven't been fully tested.
68 define SHOBJ_CFLAGS -KPIC
69 define SHOBJ_LDFLAGS "-G"
70 define SH_CFLAGS -KPIC
71 define SH_LINKFLAGS -Wl,-export-dynamic
72 define SH_SOPREFIX -Wl,-h,
@@ -78,11 +78,11 @@
78 }
79 *-*-solaris* {
80 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
81 msg-result "Found sun stdio compiler"
82 # sun stdio compiler
83 # XXX: These haven't been fully tested.
84 define SHOBJ_CFLAGS -KPIC
85 define SHOBJ_LDFLAGS "-G"
86 define SH_CFLAGS -KPIC
87 define SH_LINKFLAGS -Wl,-export-dynamic
88 define SH_SOPREFIX -Wl,-h,
@@ -103,10 +103,15 @@
103 define SH_LDFLAGS -shared
104 define SH_LINKFLAGS ""
105 define SH_SOPREFIX ""
106 define LD_LIBRARY_PATH LIBRARY_PATH
107 }
 
 
 
 
 
108 }
109
110 if {![is-defined SHOBJ_LDFLAGS_R]} {
111 define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
112 }
113
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -62,11 +62,11 @@
62 }
63 sparc* {
64 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
65 msg-result "Found sun stdio compiler"
66 # sun stdio compiler
67 # XXX: These haven't been fully tested.
68 define SHOBJ_CFLAGS -KPIC
69 define SHOBJ_LDFLAGS "-G"
70 define SH_CFLAGS -KPIC
71 define SH_LINKFLAGS -Wl,-export-dynamic
72 define SH_SOPREFIX -Wl,-h,
@@ -78,11 +78,11 @@
78 }
79 *-*-solaris* {
80 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
81 msg-result "Found sun stdio compiler"
82 # sun stdio compiler
83 # XXX: These haven't been fully tested.
84 define SHOBJ_CFLAGS -KPIC
85 define SHOBJ_LDFLAGS "-G"
86 define SH_CFLAGS -KPIC
87 define SH_LINKFLAGS -Wl,-export-dynamic
88 define SH_SOPREFIX -Wl,-h,
@@ -103,10 +103,15 @@
103 define SH_LDFLAGS -shared
104 define SH_LINKFLAGS ""
105 define SH_SOPREFIX ""
106 define LD_LIBRARY_PATH LIBRARY_PATH
107 }
108 microblaze* {
109 # Microblaze generally needs -fPIC rather than -fpic
110 define SHOBJ_CFLAGS -fPIC
111 define SH_CFLAGS -fPIC
112 }
113 }
114
115 if {![is-defined SHOBJ_LDFLAGS_R]} {
116 define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
117 }
118
+13 -7
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -47,11 +47,12 @@
4747
}
4848
4949
# Checks for the existence of the given type/structure member.
5050
# e.g. "struct stat.st_mtime"
5151
proc cctest_member {struct_member} {
52
- lassign [split $struct_member .] struct member
52
+ # split at the first dot
53
+ regexp {^([^.]+)[.](.*)$} $struct_member -> struct member
5354
cctest -code "static $struct _s; return sizeof(_s.$member);"
5455
}
5556
5657
# Checks for the existence of the given define by compiling
5758
#
@@ -208,18 +209,18 @@
208209
# First checks for no library required, then checks each of the libraries
209210
# in turn.
210211
#
211212
# If the function is found, the feature is defined and lib_$function is defined
212213
# to -l$lib where the function was found, or "" if no library required.
213
-# In addition, -l$lib is added to the LIBS define.
214
+# In addition, -l$lib is prepended to the LIBS define.
214215
#
215216
# If additional libraries may be needed for linking, they should be specified
216217
# as $extralibs as "-lotherlib1 -lotherlib2".
217218
# These libraries are not automatically added to LIBS.
218219
#
219220
# Returns 1 if found or 0 if not.
220
-#
221
+#
221222
proc cc-check-function-in-lib {function libs {otherlibs {}}} {
222223
msg-checking "Checking libs for $function..."
223224
set found 0
224225
cc-with [list -libs $otherlibs] {
225226
if {[cctest_function $function]} {
@@ -230,11 +231,12 @@
230231
foreach lib $libs {
231232
cc-with [list -libs -l$lib] {
232233
if {[cctest_function $function]} {
233234
msg-result -l$lib
234235
define lib_$function -l$lib
235
- define-append LIBS -l$lib
236
+ # prepend to LIBS
237
+ define LIBS "-l$lib [get-define LIBS]"
236238
incr found
237239
break
238240
}
239241
}
240242
}
@@ -413,11 +415,11 @@
413415
return $result
414416
}
415417
}
416418
417419
# @cctest ?settings?
418
-#
420
+#
419421
# Low level C compiler checker. Compiles and or links a small C program
420422
# according to the arguments and returns 1 if OK, or 0 if not.
421423
#
422424
# Supported settings are:
423425
#
@@ -496,17 +498,21 @@
496498
default {
497499
autosetup-error "cctest called with unknown language: $opts(-lang)"
498500
}
499501
}
500502
501
- if {!$opts(-link)} {
503
+ if {$opts(-link)} {
504
+ lappend cmdline {*}[get-define LDFLAGS]
505
+ } else {
502506
set tmp conftest__.o
503507
lappend cmdline -c
504508
}
505509
lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
506
-
507510
lappend cmdline $src -o $tmp {*}$opts(-libs)
511
+ if {$opts(-link)} {
512
+ lappend cmdline {*}[get-define LIBS]
513
+ }
508514
509515
# At this point we have the complete command line and the
510516
# complete source to be compiled. Get the result from cache if
511517
# we can
512518
if {[info exists ::cc_cache($cmdline,$lines)]} {
513519
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -47,11 +47,12 @@
47 }
48
49 # Checks for the existence of the given type/structure member.
50 # e.g. "struct stat.st_mtime"
51 proc cctest_member {struct_member} {
52 lassign [split $struct_member .] struct member
 
53 cctest -code "static $struct _s; return sizeof(_s.$member);"
54 }
55
56 # Checks for the existence of the given define by compiling
57 #
@@ -208,18 +209,18 @@
208 # First checks for no library required, then checks each of the libraries
209 # in turn.
210 #
211 # If the function is found, the feature is defined and lib_$function is defined
212 # to -l$lib where the function was found, or "" if no library required.
213 # In addition, -l$lib is added to the LIBS define.
214 #
215 # If additional libraries may be needed for linking, they should be specified
216 # as $extralibs as "-lotherlib1 -lotherlib2".
217 # These libraries are not automatically added to LIBS.
218 #
219 # Returns 1 if found or 0 if not.
220 #
221 proc cc-check-function-in-lib {function libs {otherlibs {}}} {
222 msg-checking "Checking libs for $function..."
223 set found 0
224 cc-with [list -libs $otherlibs] {
225 if {[cctest_function $function]} {
@@ -230,11 +231,12 @@
230 foreach lib $libs {
231 cc-with [list -libs -l$lib] {
232 if {[cctest_function $function]} {
233 msg-result -l$lib
234 define lib_$function -l$lib
235 define-append LIBS -l$lib
 
236 incr found
237 break
238 }
239 }
240 }
@@ -413,11 +415,11 @@
413 return $result
414 }
415 }
416
417 # @cctest ?settings?
418 #
419 # Low level C compiler checker. Compiles and or links a small C program
420 # according to the arguments and returns 1 if OK, or 0 if not.
421 #
422 # Supported settings are:
423 #
@@ -496,17 +498,21 @@
496 default {
497 autosetup-error "cctest called with unknown language: $opts(-lang)"
498 }
499 }
500
501 if {!$opts(-link)} {
 
 
502 set tmp conftest__.o
503 lappend cmdline -c
504 }
505 lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
506
507 lappend cmdline $src -o $tmp {*}$opts(-libs)
 
 
 
508
509 # At this point we have the complete command line and the
510 # complete source to be compiled. Get the result from cache if
511 # we can
512 if {[info exists ::cc_cache($cmdline,$lines)]} {
513
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -47,11 +47,12 @@
47 }
48
49 # Checks for the existence of the given type/structure member.
50 # e.g. "struct stat.st_mtime"
51 proc cctest_member {struct_member} {
52 # split at the first dot
53 regexp {^([^.]+)[.](.*)$} $struct_member -> struct member
54 cctest -code "static $struct _s; return sizeof(_s.$member);"
55 }
56
57 # Checks for the existence of the given define by compiling
58 #
@@ -208,18 +209,18 @@
209 # First checks for no library required, then checks each of the libraries
210 # in turn.
211 #
212 # If the function is found, the feature is defined and lib_$function is defined
213 # to -l$lib where the function was found, or "" if no library required.
214 # In addition, -l$lib is prepended to the LIBS define.
215 #
216 # If additional libraries may be needed for linking, they should be specified
217 # as $extralibs as "-lotherlib1 -lotherlib2".
218 # These libraries are not automatically added to LIBS.
219 #
220 # Returns 1 if found or 0 if not.
221 #
222 proc cc-check-function-in-lib {function libs {otherlibs {}}} {
223 msg-checking "Checking libs for $function..."
224 set found 0
225 cc-with [list -libs $otherlibs] {
226 if {[cctest_function $function]} {
@@ -230,11 +231,12 @@
231 foreach lib $libs {
232 cc-with [list -libs -l$lib] {
233 if {[cctest_function $function]} {
234 msg-result -l$lib
235 define lib_$function -l$lib
236 # prepend to LIBS
237 define LIBS "-l$lib [get-define LIBS]"
238 incr found
239 break
240 }
241 }
242 }
@@ -413,11 +415,11 @@
415 return $result
416 }
417 }
418
419 # @cctest ?settings?
420 #
421 # Low level C compiler checker. Compiles and or links a small C program
422 # according to the arguments and returns 1 if OK, or 0 if not.
423 #
424 # Supported settings are:
425 #
@@ -496,17 +498,21 @@
498 default {
499 autosetup-error "cctest called with unknown language: $opts(-lang)"
500 }
501 }
502
503 if {$opts(-link)} {
504 lappend cmdline {*}[get-define LDFLAGS]
505 } else {
506 set tmp conftest__.o
507 lappend cmdline -c
508 }
509 lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
 
510 lappend cmdline $src -o $tmp {*}$opts(-libs)
511 if {$opts(-link)} {
512 lappend cmdline {*}[get-define LIBS]
513 }
514
515 # At this point we have the complete command line and the
516 # complete source to be compiled. Get the result from cache if
517 # we can
518 if {[info exists ::cc_cache($cmdline,$lines)]} {
519
+1855 -1666
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,7 +1,9 @@
11
/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */
2
+#define _GNU_SOURCE
23
#define JIM_TCL_COMPAT
4
+#define JIM_REFERENCES
35
#define JIM_ANSIC
46
#define JIM_REGEXP
57
#define HAVE_NO_AUTOCONF
68
#define _JIMAUTOCONF_H
79
#define TCL_LIBRARY "."
@@ -33,26 +35,20 @@
3335
#define HAVE_UNISTD_H
3436
#else
3537
#define TCL_PLATFORM_OS "unknown"
3638
#define TCL_PLATFORM_PLATFORM "unix"
3739
#define TCL_PLATFORM_PATH_SEPARATOR ":"
38
-#ifdef _MINIX
39
-#define vfork fork
40
-#define _POSIX_SOURCE
41
-#else
42
-#define _GNU_SOURCE
43
-#endif
4440
#define HAVE_VFORK
4541
#define HAVE_WAITPID
4642
#define HAVE_ISATTY
4743
#define HAVE_MKSTEMP
4844
#define HAVE_LINK
4945
#define HAVE_SYS_TIME_H
5046
#define HAVE_DIRENT_H
5147
#define HAVE_UNISTD_H
5248
#endif
53
-#define JIM_VERSION 77
49
+#define JIM_VERSION 76
5450
#ifndef JIM_WIN32COMPAT_H
5551
#define JIM_WIN32COMPAT_H
5652
5753
5854
@@ -109,14 +105,14 @@
109105
struct dirent {
110106
char *d_name;
111107
};
112108
113109
typedef struct DIR {
114
- long handle;
110
+ long handle;
115111
struct _finddata_t info;
116
- struct dirent result;
117
- char *name;
112
+ struct dirent result;
113
+ char *name;
118114
} DIR;
119115
120116
DIR *opendir(const char *name);
121117
int closedir(DIR *dir);
122118
struct dirent *readdir(DIR *dir);
@@ -126,11 +122,11 @@
126122
#include <stdlib.h>
127123
#define strtod __strtod
128124
129125
#endif
130126
131
-#endif
127
+#endif
132128
133129
#ifdef __cplusplus
134130
}
135131
#endif
136132
@@ -179,13 +175,13 @@
179175
extern "C" {
180176
#endif
181177
182178
#include <time.h>
183179
#include <limits.h>
184
-#include <stdio.h>
185
-#include <stdlib.h>
186
-#include <stdarg.h>
180
+#include <stdio.h>
181
+#include <stdlib.h>
182
+#include <stdarg.h>
187183
188184
189185
#ifndef HAVE_NO_AUTOCONF
190186
#endif
191187
@@ -228,31 +224,31 @@
228224
#define JIM_SIGNAL 5
229225
#define JIM_EXIT 6
230226
231227
#define JIM_EVAL 7
232228
233
-#define JIM_MAX_CALLFRAME_DEPTH 1000
234
-#define JIM_MAX_EVAL_DEPTH 2000
229
+#define JIM_MAX_CALLFRAME_DEPTH 1000
230
+#define JIM_MAX_EVAL_DEPTH 2000
235231
236232
237233
#define JIM_PRIV_FLAG_SHIFT 20
238234
239
-#define JIM_NONE 0
240
-#define JIM_ERRMSG 1
241
-#define JIM_ENUM_ABBREV 2
242
-#define JIM_UNSHARED 4
243
-#define JIM_MUSTEXIST 8
244
-
245
-
246
-#define JIM_SUBST_NOVAR 1
247
-#define JIM_SUBST_NOCMD 2
248
-#define JIM_SUBST_NOESC 4
249
-#define JIM_SUBST_FLAG 128
250
-
251
-
252
-#define JIM_CASESENS 0
253
-#define JIM_NOCASE 1
235
+#define JIM_NONE 0
236
+#define JIM_ERRMSG 1
237
+#define JIM_ENUM_ABBREV 2
238
+#define JIM_UNSHARED 4
239
+#define JIM_MUSTEXIST 8
240
+
241
+
242
+#define JIM_SUBST_NOVAR 1
243
+#define JIM_SUBST_NOCMD 2
244
+#define JIM_SUBST_NOESC 4
245
+#define JIM_SUBST_FLAG 128
246
+
247
+
248
+#define JIM_CASESENS 0
249
+#define JIM_NOCASE 1
254250
255251
256252
#define JIM_PATH_LEN 1024
257253
258254
@@ -343,79 +339,79 @@
343339
#define Jim_GetHashTableSize(ht) ((ht)->size)
344340
#define Jim_GetHashTableUsed(ht) ((ht)->used)
345341
346342
347343
typedef struct Jim_Obj {
348
- char *bytes;
349
- const struct Jim_ObjType *typePtr;
350
- int refCount;
351
- int length;
352
-
344
+ char *bytes;
345
+ const struct Jim_ObjType *typePtr;
346
+ int refCount;
347
+ int length;
348
+
353349
union {
354
-
350
+
355351
jim_wide wideValue;
356
-
352
+
357353
int intValue;
358
-
354
+
359355
double doubleValue;
360
-
356
+
361357
void *ptr;
362
-
358
+
363359
struct {
364360
void *ptr1;
365361
void *ptr2;
366362
} twoPtrValue;
367
-
363
+
368364
struct {
369365
struct Jim_Var *varPtr;
370
- unsigned long callFrameId;
371
- int global;
366
+ unsigned long callFrameId;
367
+ int global;
372368
} varValue;
373
-
369
+
374370
struct {
375371
struct Jim_Obj *nsObj;
376372
struct Jim_Cmd *cmdPtr;
377
- unsigned long procEpoch;
373
+ unsigned long procEpoch;
378374
} cmdValue;
379
-
375
+
380376
struct {
381
- struct Jim_Obj **ele;
382
- int len;
383
- int maxLen;
377
+ struct Jim_Obj **ele;
378
+ int len;
379
+ int maxLen;
384380
} listValue;
385
-
381
+
386382
struct {
387383
int maxLength;
388
- int charLength;
384
+ int charLength;
389385
} strValue;
390
-
386
+
391387
struct {
392388
unsigned long id;
393389
struct Jim_Reference *refPtr;
394390
} refValue;
395
-
391
+
396392
struct {
397393
struct Jim_Obj *fileNameObj;
398394
int lineNumber;
399395
} sourceValue;
400
-
396
+
401397
struct {
402398
struct Jim_Obj *varNameObjPtr;
403399
struct Jim_Obj *indexObjPtr;
404400
} dictSubstValue;
405
-
401
+
406402
struct {
407
- void *compre;
403
+ void *compre;
408404
unsigned flags;
409405
} regexpValue;
410406
struct {
411407
int line;
412408
int argc;
413409
} scriptLineValue;
414410
} internalRep;
415
- struct Jim_Obj *prevObjPtr;
416
- struct Jim_Obj *nextObjPtr;
411
+ struct Jim_Obj *prevObjPtr;
412
+ struct Jim_Obj *nextObjPtr;
417413
} Jim_Obj;
418414
419415
420416
#define Jim_IncrRefCount(objPtr) \
421417
++(objPtr)->refCount
@@ -446,40 +442,40 @@
446442
typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
447443
struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
448444
typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
449445
450446
typedef struct Jim_ObjType {
451
- const char *name;
447
+ const char *name;
452448
Jim_FreeInternalRepProc *freeIntRepProc;
453449
Jim_DupInternalRepProc *dupIntRepProc;
454450
Jim_UpdateStringProc *updateStringProc;
455451
int flags;
456452
} Jim_ObjType;
457453
458454
459
-#define JIM_TYPE_NONE 0
460
-#define JIM_TYPE_REFERENCES 1
455
+#define JIM_TYPE_NONE 0
456
+#define JIM_TYPE_REFERENCES 1
461457
462458
463459
464460
typedef struct Jim_CallFrame {
465
- unsigned long id;
466
- int level;
467
- struct Jim_HashTable vars;
468
- struct Jim_HashTable *staticVars;
469
- struct Jim_CallFrame *parent;
470
- Jim_Obj *const *argv;
471
- int argc;
472
- Jim_Obj *procArgsObjPtr;
473
- Jim_Obj *procBodyObjPtr;
474
- struct Jim_CallFrame *next;
475
- Jim_Obj *nsObj;
476
- Jim_Obj *fileNameObj;
461
+ unsigned long id;
462
+ int level;
463
+ struct Jim_HashTable vars;
464
+ struct Jim_HashTable *staticVars;
465
+ struct Jim_CallFrame *parent;
466
+ Jim_Obj *const *argv;
467
+ int argc;
468
+ Jim_Obj *procArgsObjPtr;
469
+ Jim_Obj *procBodyObjPtr;
470
+ struct Jim_CallFrame *next;
471
+ Jim_Obj *nsObj;
472
+ Jim_Obj *fileNameObj;
477473
int line;
478
- Jim_Stack *localCommands;
479
- struct Jim_Obj *tailcallObj;
480
- struct Jim_Cmd *tailcallCmd;
474
+ Jim_Stack *localCommands;
475
+ struct Jim_Obj *tailcallObj;
476
+ struct Jim_Cmd *tailcallCmd;
481477
} Jim_CallFrame;
482478
483479
typedef struct Jim_Var {
484480
Jim_Obj *objPtr;
485481
struct Jim_CallFrame *linkFramePtr;
@@ -491,35 +487,35 @@
491487
typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
492488
493489
494490
495491
typedef struct Jim_Cmd {
496
- int inUse;
497
- int isproc;
498
- struct Jim_Cmd *prevCmd;
492
+ int inUse;
493
+ int isproc;
494
+ struct Jim_Cmd *prevCmd;
499495
union {
500496
struct {
501
-
502
- Jim_CmdProc *cmdProc;
503
- Jim_DelCmdProc *delProc;
504
- void *privData;
497
+
498
+ Jim_CmdProc *cmdProc;
499
+ Jim_DelCmdProc *delProc;
500
+ void *privData;
505501
} native;
506502
struct {
507
-
503
+
508504
Jim_Obj *argListObjPtr;
509505
Jim_Obj *bodyObjPtr;
510
- Jim_HashTable *staticVars;
511
- int argListLen;
512
- int reqArity;
513
- int optArity;
514
- int argsPos;
515
- int upcall;
506
+ Jim_HashTable *staticVars;
507
+ int argListLen;
508
+ int reqArity;
509
+ int optArity;
510
+ int argsPos;
511
+ int upcall;
516512
struct Jim_ProcArg {
517
- Jim_Obj *nameObjPtr;
518
- Jim_Obj *defaultObjPtr;
513
+ Jim_Obj *nameObjPtr;
514
+ Jim_Obj *defaultObjPtr;
519515
} *arglist;
520
- Jim_Obj *nsObj;
516
+ Jim_Obj *nsObj;
521517
} proc;
522518
} u;
523519
} Jim_Cmd;
524520
525521
@@ -527,64 +523,64 @@
527523
unsigned char sbox[256];
528524
unsigned int i, j;
529525
} Jim_PrngState;
530526
531527
typedef struct Jim_Interp {
532
- Jim_Obj *result;
533
- int errorLine;
534
- Jim_Obj *errorFileNameObj;
535
- int addStackTrace;
536
- int maxCallFrameDepth;
537
- int maxEvalDepth;
538
- int evalDepth;
539
- int returnCode;
540
- int returnLevel;
541
- int exitCode;
542
- long id;
543
- int signal_level;
544
- jim_wide sigmask;
545
- int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
546
- Jim_CallFrame *framePtr;
547
- Jim_CallFrame *topFramePtr;
548
- struct Jim_HashTable commands;
528
+ Jim_Obj *result;
529
+ int errorLine;
530
+ Jim_Obj *errorFileNameObj;
531
+ int addStackTrace;
532
+ int maxCallFrameDepth;
533
+ int maxEvalDepth;
534
+ int evalDepth;
535
+ int returnCode;
536
+ int returnLevel;
537
+ int exitCode;
538
+ long id;
539
+ int signal_level;
540
+ jim_wide sigmask;
541
+ int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
542
+ Jim_CallFrame *framePtr;
543
+ Jim_CallFrame *topFramePtr;
544
+ struct Jim_HashTable commands;
549545
unsigned long procEpoch; /* Incremented every time the result
550546
of procedures names lookup caching
551547
may no longer be valid. */
552548
unsigned long callFrameEpoch; /* Incremented every time a new
553549
callframe is created. This id is used for the
554550
'ID' field contained in the Jim_CallFrame
555551
structure. */
556
- int local;
557
- Jim_Obj *liveList;
558
- Jim_Obj *freeList;
559
- Jim_Obj *currentScriptObj;
560
- Jim_Obj *nullScriptObj;
561
- Jim_Obj *emptyObj;
562
- Jim_Obj *trueObj;
563
- Jim_Obj *falseObj;
564
- unsigned long referenceNextId;
565
- struct Jim_HashTable references;
552
+ int local;
553
+ Jim_Obj *liveList;
554
+ Jim_Obj *freeList;
555
+ Jim_Obj *currentScriptObj;
556
+ Jim_Obj *nullScriptObj;
557
+ Jim_Obj *emptyObj;
558
+ Jim_Obj *trueObj;
559
+ Jim_Obj *falseObj;
560
+ unsigned long referenceNextId;
561
+ struct Jim_HashTable references;
566562
unsigned long lastCollectId; /* reference max Id of the last GC
567563
execution. It's set to -1 while the collection
568564
is running as sentinel to avoid to recursive
569565
calls via the [collect] command inside
570566
finalizers. */
571
- time_t lastCollectTime;
572
- Jim_Obj *stackTrace;
573
- Jim_Obj *errorProc;
574
- Jim_Obj *unknown;
575
- int unknown_called;
576
- int errorFlag;
567
+ time_t lastCollectTime;
568
+ Jim_Obj *stackTrace;
569
+ Jim_Obj *errorProc;
570
+ Jim_Obj *unknown;
571
+ int unknown_called;
572
+ int errorFlag;
577573
void *cmdPrivData; /* Used to pass the private data pointer to
578574
a command. It is set to what the user specified
579575
via Jim_CreateCommand(). */
580576
581
- struct Jim_CallFrame *freeFramesList;
582
- struct Jim_HashTable assocData;
583
- Jim_PrngState *prngState;
584
- struct Jim_HashTable packages;
585
- Jim_Stack *loadHandles;
577
+ struct Jim_CallFrame *freeFramesList;
578
+ struct Jim_HashTable assocData;
579
+ Jim_PrngState *prngState;
580
+ struct Jim_HashTable packages;
581
+ Jim_Stack *loadHandles;
586582
} Jim_Interp;
587583
588584
#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
589585
#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
590586
#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -835,14 +831,10 @@
835831
JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
836832
Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
837833
JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
838834
Jim_Obj *exprObjPtr, int *boolPtr);
839835
840
-
841
-JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr,
842
- int *booleanPtr);
843
-
844836
845837
JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
846838
jim_wide *widePtr);
847839
JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
848840
long *longPtr);
@@ -912,11 +904,11 @@
912904
913905
#ifdef __cplusplus
914906
}
915907
#endif
916908
917
-#endif
909
+#endif
918910
919911
#ifndef JIM_SUBCMD_H
920912
#define JIM_SUBCMD_H
921913
922914
@@ -923,24 +915,24 @@
923915
#ifdef __cplusplus
924916
extern "C" {
925917
#endif
926918
927919
928
-#define JIM_MODFLAG_HIDDEN 0x0001
929
-#define JIM_MODFLAG_FULLARGV 0x0002
920
+#define JIM_MODFLAG_HIDDEN 0x0001
921
+#define JIM_MODFLAG_FULLARGV 0x0002
930922
931923
932924
933925
typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
934926
935927
typedef struct {
936
- const char *cmd;
937
- const char *args;
938
- jim_subcmd_function *function;
939
- short minargs;
940
- short maxargs;
941
- unsigned short flags;
928
+ const char *cmd;
929
+ const char *args;
930
+ jim_subcmd_function *function;
931
+ short minargs;
932
+ short maxargs;
933
+ unsigned short flags;
942934
} jim_subcmd_type;
943935
944936
const jim_subcmd_type *
945937
Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv);
946938
@@ -968,36 +960,36 @@
968960
int rm_eo;
969961
} regmatch_t;
970962
971963
972964
typedef struct regexp {
973
-
974
- int re_nsub;
975
-
976
-
977
- int cflags;
978
- int err;
979
- int regstart;
980
- int reganch;
981
- int regmust;
982
- int regmlen;
983
- int *program;
984
-
985
-
986
- const char *regparse;
987
- int p;
988
- int proglen;
989
-
990
-
991
- int eflags;
992
- const char *start;
993
- const char *reginput;
994
- const char *regbol;
995
-
996
-
997
- regmatch_t *pmatch;
998
- int nmatch;
965
+
966
+ int re_nsub;
967
+
968
+
969
+ int cflags;
970
+ int err;
971
+ int regstart;
972
+ int reganch;
973
+ int regmust;
974
+ int regmlen;
975
+ int *program;
976
+
977
+
978
+ const char *regparse;
979
+ int p;
980
+ int proglen;
981
+
982
+
983
+ int eflags;
984
+ const char *start;
985
+ const char *reginput;
986
+ const char *regbol;
987
+
988
+
989
+ regmatch_t *pmatch;
990
+ int nmatch;
999991
} regexp;
1000992
1001993
typedef regexp regex_t;
1002994
1003995
#define REG_EXTENDED 0
@@ -1005,13 +997,13 @@
1005997
#define REG_ICASE 2
1006998
1007999
#define REG_NOTBOL 16
10081000
10091001
enum {
1010
- REG_NOERROR,
1011
- REG_NOMATCH,
1012
- REG_BADPAT,
1002
+ REG_NOERROR,
1003
+ REG_NOMATCH,
1004
+ REG_BADPAT,
10131005
REG_ERR_NULL_ARGUMENT,
10141006
REG_ERR_UNKNOWN,
10151007
REG_ERR_TOO_BIG,
10161008
REG_ERR_NOMEM,
10171009
REG_ERR_TOO_MANY_PAREN,
@@ -1788,11 +1780,10 @@
17881780
"}\n"
17891781
);
17901782
}
17911783
17921784
1793
-#define _GNU_SOURCE
17941785
#include <stdio.h>
17951786
#include <string.h>
17961787
#include <errno.h>
17971788
#include <fcntl.h>
17981789
#ifdef HAVE_UNISTD_H
@@ -1817,12 +1808,12 @@
18171808
#include <openssl/ssl.h>
18181809
#include <openssl/err.h>
18191810
#endif
18201811
18211812
1822
-#define AIO_CMD_LEN 32
1823
-#define AIO_BUF_LEN 256
1813
+#define AIO_CMD_LEN 32
1814
+#define AIO_BUF_LEN 256
18241815
18251816
#ifndef HAVE_FTELLO
18261817
#define ftello ftell
18271818
#endif
18281819
#ifndef HAVE_FSEEKO
@@ -1857,11 +1848,11 @@
18571848
typedef struct AioFile
18581849
{
18591850
FILE *fp;
18601851
Jim_Obj *filename;
18611852
int type;
1862
- int openFlags;
1853
+ int openFlags;
18631854
int fd;
18641855
Jim_Obj *rEvent;
18651856
Jim_Obj *wEvent;
18661857
Jim_Obj *eEvent;
18671858
int addr_family;
@@ -1888,11 +1879,11 @@
18881879
{
18891880
if (!ferror(af->fp)) {
18901881
return JIM_OK;
18911882
}
18921883
clearerr(af->fp);
1893
-
1884
+
18941885
if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
18951886
return JIM_OK;
18961887
}
18971888
#ifdef ECONNRESET
18981889
if (errno == ECONNRESET) {
@@ -1954,12 +1945,12 @@
19541945
JIM_NOTUSED(interp);
19551946
19561947
Jim_DecrRefCount(interp, af->filename);
19571948
19581949
#ifdef jim_ext_eventloop
1959
-
1960
- Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
1950
+
1951
+ Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
19611952
#endif
19621953
19631954
#if defined(JIM_SSL)
19641955
if (af->ssl != NULL) {
19651956
SSL_free(af->ssl);
@@ -1977,11 +1968,11 @@
19771968
{
19781969
AioFile *af = Jim_CmdPrivData(interp);
19791970
char buf[AIO_BUF_LEN];
19801971
Jim_Obj *objPtr;
19811972
int nonewline = 0;
1982
- jim_wide neededLen = -1;
1973
+ jim_wide neededLen = -1;
19831974
19841975
if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
19851976
nonewline = 1;
19861977
argv++;
19871978
argc--;
@@ -2016,11 +2007,11 @@
20162007
}
20172008
}
20182009
if (retval != readlen)
20192010
break;
20202011
}
2021
-
2012
+
20222013
if (JimCheckStreamError(interp, af)) {
20232014
Jim_FreeNewObj(interp, objPtr);
20242015
return JIM_ERR;
20252016
}
20262017
if (nonewline) {
@@ -2038,11 +2029,11 @@
20382029
20392030
AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command)
20402031
{
20412032
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
20422033
2043
-
2034
+
20442035
if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
20452036
return (AioFile *) cmdPtr->u.native.privData;
20462037
}
20472038
Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
20482039
return NULL;
@@ -2119,21 +2110,21 @@
21192110
}
21202111
else {
21212112
len = strlen(buf);
21222113
21232114
if (len && (buf[len - 1] == '\n')) {
2124
-
2115
+
21252116
len--;
21262117
}
21272118
21282119
Jim_AppendString(interp, objPtr, buf, len);
21292120
break;
21302121
}
21312122
}
21322123
21332124
if (JimCheckStreamError(interp, af)) {
2134
-
2125
+
21352126
Jim_FreeNewObj(interp, objPtr);
21362127
return JIM_ERR;
21372128
}
21382129
21392130
if (argc) {
@@ -2143,11 +2134,11 @@
21432134
}
21442135
21452136
len = Jim_Length(objPtr);
21462137
21472138
if (len == 0 && feof(af->fp)) {
2148
-
2139
+
21492140
len = -1;
21502141
}
21512142
Jim_SetResultInt(interp, len);
21522143
}
21532144
else {
@@ -2373,33 +2364,33 @@
23732364
23742365
static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
23752366
int argc, Jim_Obj * const *argv)
23762367
{
23772368
if (argc == 0) {
2378
-
2369
+
23792370
if (*scriptHandlerObj) {
23802371
Jim_SetResult(interp, *scriptHandlerObj);
23812372
}
23822373
return JIM_OK;
23832374
}
23842375
23852376
if (*scriptHandlerObj) {
2386
-
2387
- Jim_DeleteFileHandler(interp, af->fd, mask);
2377
+
2378
+ Jim_DeleteFileHandler(interp, af->fp, mask);
23882379
}
23892380
2390
-
2381
+
23912382
if (Jim_Length(argv[0]) == 0) {
2392
-
2383
+
23932384
return JIM_OK;
23942385
}
23952386
2396
-
2387
+
23972388
Jim_IncrRefCount(argv[0]);
23982389
*scriptHandlerObj = argv[0];
23992390
2400
- Jim_CreateFileHandler(interp, af->fd, mask,
2391
+ Jim_CreateFileHandler(interp, af->fp, mask,
24012392
JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
24022393
24032394
return JIM_OK;
24042395
}
24052396
@@ -2424,136 +2415,135 @@
24242415
return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
24252416
}
24262417
#endif
24272418
24282419
2429
-
24302420
static const jim_subcmd_type aio_command_table[] = {
24312421
{ "read",
24322422
"?-nonewline? ?len?",
24332423
aio_cmd_read,
24342424
0,
24352425
2,
2436
-
2426
+
24372427
},
24382428
{ "copyto",
24392429
"handle ?size?",
24402430
aio_cmd_copy,
24412431
1,
24422432
2,
2443
-
2433
+
24442434
},
24452435
{ "gets",
24462436
"?var?",
24472437
aio_cmd_gets,
24482438
0,
24492439
1,
2450
-
2440
+
24512441
},
24522442
{ "puts",
24532443
"?-nonewline? str",
24542444
aio_cmd_puts,
24552445
1,
24562446
2,
2457
-
2447
+
24582448
},
24592449
{ "isatty",
24602450
NULL,
24612451
aio_cmd_isatty,
24622452
0,
24632453
0,
2464
-
2454
+
24652455
},
24662456
{ "flush",
24672457
NULL,
24682458
aio_cmd_flush,
24692459
0,
24702460
0,
2471
-
2461
+
24722462
},
24732463
{ "eof",
24742464
NULL,
24752465
aio_cmd_eof,
24762466
0,
24772467
0,
2478
-
2468
+
24792469
},
24802470
{ "close",
24812471
"?r(ead)|w(rite)?",
24822472
aio_cmd_close,
24832473
0,
24842474
1,
24852475
JIM_MODFLAG_FULLARGV,
2486
-
2476
+
24872477
},
24882478
{ "seek",
24892479
"offset ?start|current|end",
24902480
aio_cmd_seek,
24912481
1,
24922482
2,
2493
-
2483
+
24942484
},
24952485
{ "tell",
24962486
NULL,
24972487
aio_cmd_tell,
24982488
0,
24992489
0,
2500
-
2490
+
25012491
},
25022492
{ "filename",
25032493
NULL,
25042494
aio_cmd_filename,
25052495
0,
25062496
0,
2507
-
2497
+
25082498
},
25092499
#ifdef O_NDELAY
25102500
{ "ndelay",
25112501
"?0|1?",
25122502
aio_cmd_ndelay,
25132503
0,
25142504
1,
2515
-
2505
+
25162506
},
25172507
#endif
25182508
#ifdef HAVE_FSYNC
25192509
{ "sync",
25202510
NULL,
25212511
aio_cmd_sync,
25222512
0,
25232513
0,
2524
-
2514
+
25252515
},
25262516
#endif
25272517
{ "buffering",
25282518
"none|line|full",
25292519
aio_cmd_buffering,
25302520
1,
25312521
1,
2532
-
2522
+
25332523
},
25342524
#ifdef jim_ext_eventloop
25352525
{ "readable",
25362526
"?readable-script?",
25372527
aio_cmd_readable,
25382528
0,
25392529
1,
2540
-
2530
+
25412531
},
25422532
{ "writable",
25432533
"?writable-script?",
25442534
aio_cmd_writable,
25452535
0,
25462536
1,
2547
-
2537
+
25482538
},
25492539
{ "onexception",
25502540
"?exception-script?",
25512541
aio_cmd_onexception,
25522542
0,
25532543
1,
2554
-
2544
+
25552545
},
25562546
#endif
25572547
{ NULL }
25582548
};
25592549
@@ -2576,11 +2566,11 @@
25762566
25772567
#ifdef jim_ext_tclcompat
25782568
{
25792569
const char *filename = Jim_String(argv[1]);
25802570
2581
-
2571
+
25822572
if (*filename == '|') {
25832573
Jim_Obj *evalObj[3];
25842574
25852575
evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
25862576
evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2633,11 +2623,11 @@
26332623
Jim_DecrRefCount(interp, filename);
26342624
return NULL;
26352625
}
26362626
}
26372627
2638
-
2628
+
26392629
af = Jim_Alloc(sizeof(*af));
26402630
memset(af, 0, sizeof(*af));
26412631
af->fp = fh;
26422632
af->fd = fileno(fh);
26432633
af->filename = filename;
@@ -2671,11 +2661,11 @@
26712661
Jim_SetResult(interp, objPtr);
26722662
return JIM_OK;
26732663
}
26742664
}
26752665
2676
-
2666
+
26772667
close(p[0]);
26782668
close(p[1]);
26792669
JimAioSetError(interp, NULL);
26802670
return JIM_ERR;
26812671
}
@@ -2705,15 +2695,15 @@
27052695
}
27062696
27072697
#if defined(S_IRWXG) && defined(S_IRWXO)
27082698
mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
27092699
#else
2710
-
2700
+
27112701
mask = umask(S_IXUSR);
27122702
#endif
27132703
2714
-
2704
+
27152705
fd = mkstemp(filenameObj->bytes);
27162706
umask(mask);
27172707
if (fd < 0) {
27182708
JimAioSetError(interp, filenameObj);
27192709
Jim_FreeNewObj(interp, filenameObj);
@@ -2741,11 +2731,11 @@
27412731
Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
27422732
#ifndef JIM_ANSIC
27432733
Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
27442734
#endif
27452735
2746
-
2736
+
27472737
JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
27482738
JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
27492739
JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
27502740
27512741
return JIM_OK;
@@ -2841,20 +2831,20 @@
28412831
{
28422832
regex_t *compre;
28432833
const char *pattern;
28442834
int ret;
28452835
2846
-
2836
+
28472837
if (objPtr->typePtr == &regexpObjType &&
28482838
objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
2849
-
2839
+
28502840
return objPtr->internalRep.regexpValue.compre;
28512841
}
28522842
2843
+
28532844
2854
-
2855
-
2845
+
28562846
pattern = Jim_String(objPtr);
28572847
compre = Jim_Alloc(sizeof(regex_t));
28582848
28592849
if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
28602850
char buf[100];
@@ -3011,11 +3001,11 @@
30113001
}
30123002
30133003
num_matches++;
30143004
30153005
if (opt_all && !opt_inline) {
3016
-
3006
+
30173007
goto try_next_match;
30183008
}
30193009
30203010
30213011
j = 0;
@@ -3051,11 +3041,11 @@
30513041
30523042
if (opt_inline) {
30533043
Jim_ListAppendElement(interp, resultListObj, resultObj);
30543044
}
30553045
else {
3056
-
3046
+
30573047
result = Jim_SetVariable(interp, argv[i], resultObj);
30583048
30593049
if (result != JIM_OK) {
30603050
Jim_FreeObj(interp, resultObj);
30613051
break;
@@ -3178,11 +3168,11 @@
31783168
31793169
source_str = Jim_GetString(argv[i + 1], &source_len);
31803170
replace_str = Jim_GetString(argv[i + 2], &replace_len);
31813171
varname = argv[i + 3];
31823172
3183
-
3173
+
31843174
resultObj = Jim_NewStringObj(interp, "", 0);
31853175
31863176
if (offset) {
31873177
if (offset < 0) {
31883178
offset += source_len + 1;
@@ -3193,11 +3183,11 @@
31933183
else if (offset < 0) {
31943184
offset = 0;
31953185
}
31963186
}
31973187
3198
-
3188
+
31993189
Jim_AppendString(interp, resultObj, source_str, offset);
32003190
32013191
32023192
n = source_len - offset;
32033193
p = source_str + offset;
@@ -3252,23 +3242,23 @@
32523242
}
32533243
32543244
p += pmatch[0].rm_eo;
32553245
n -= pmatch[0].rm_eo;
32563246
3257
-
3247
+
32583248
if (!opt_all || n == 0) {
32593249
break;
32603250
}
32613251
3262
-
3252
+
32633253
if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
32643254
break;
32653255
}
32663256
3267
-
3257
+
32683258
if (pattern[0] == '\0' && n) {
3269
-
3259
+
32703260
Jim_AppendString(interp, resultObj, p, 1);
32713261
p++;
32723262
n--;
32733263
}
32743264
@@ -3275,11 +3265,11 @@
32753265
regexec_flags |= REG_NOTBOL;
32763266
} while (n);
32773267
32783268
Jim_AppendString(interp, resultObj, p, -1);
32793269
3280
-
3270
+
32813271
if (argc - i == 4) {
32823272
result = Jim_SetVariable(interp, varname, resultObj);
32833273
32843274
if (result == JIM_OK) {
32853275
Jim_SetResultInt(interp, num_matches);
@@ -3381,11 +3371,11 @@
33813371
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
33823372
}
33833373
33843374
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
33853375
{
3386
-
3376
+
33873377
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
33883378
33893379
AppendStatElement(interp, listObj, "dev", sb->st_dev);
33903380
AppendStatElement(interp, listObj, "ino", sb->st_ino);
33913381
AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3397,25 +3387,25 @@
33973387
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
33983388
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
33993389
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
34003390
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
34013391
3402
-
3392
+
34033393
if (varName) {
34043394
Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
34053395
if (objPtr) {
34063396
if (Jim_DictSize(interp, objPtr) < 0) {
3407
-
3397
+
34083398
Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
34093399
Jim_FreeNewObj(interp, listObj);
34103400
return JIM_ERR;
34113401
}
34123402
34133403
if (Jim_IsShared(objPtr))
34143404
objPtr = Jim_DuplicateObj(interp, objPtr);
34153405
3416
-
3406
+
34173407
Jim_ListAppendList(interp, objPtr, listObj);
34183408
Jim_DictSize(interp, objPtr);
34193409
Jim_InvalidateStringRep(objPtr);
34203410
34213411
Jim_FreeNewObj(interp, listObj);
@@ -3422,11 +3412,11 @@
34223412
listObj = objPtr;
34233413
}
34243414
Jim_SetVariable(interp, varName, listObj);
34253415
}
34263416
3427
-
3417
+
34283418
Jim_SetResult(interp, listObj);
34293419
34303420
return JIM_OK;
34313421
}
34323422
@@ -3442,11 +3432,11 @@
34423432
}
34433433
else if (p == path) {
34443434
Jim_SetResultString(interp, "/", -1);
34453435
}
34463436
else if (ISWINDOWS && p[-1] == ':') {
3447
-
3437
+
34483438
Jim_SetResultString(interp, path, p - path + 1);
34493439
}
34503440
else {
34513441
Jim_SetResultString(interp, path, p - path);
34523442
}
@@ -3522,35 +3512,35 @@
35223512
char *newname = Jim_Alloc(MAXPATHLEN + 1);
35233513
char *last = newname;
35243514
35253515
*newname = 0;
35263516
3527
-
3517
+
35283518
for (i = 0; i < argc; i++) {
35293519
int len;
35303520
const char *part = Jim_GetString(argv[i], &len);
35313521
35323522
if (*part == '/') {
3533
-
3523
+
35343524
last = newname;
35353525
}
35363526
else if (ISWINDOWS && strchr(part, ':')) {
3537
-
3527
+
35383528
last = newname;
35393529
}
35403530
else if (part[0] == '.') {
35413531
if (part[1] == '/') {
35423532
part += 2;
35433533
len -= 2;
35443534
}
35453535
else if (part[1] == 0 && last != newname) {
3546
-
3536
+
35473537
continue;
35483538
}
35493539
}
35503540
3551
-
3541
+
35523542
if (last != newname && last[-1] != '/') {
35533543
*last++ = '/';
35543544
}
35553545
35563546
if (len) {
@@ -3561,22 +3551,22 @@
35613551
}
35623552
memcpy(last, part, len);
35633553
last += len;
35643554
}
35653555
3566
-
3556
+
35673557
if (last > newname + 1 && last[-1] == '/') {
3568
-
3558
+
35693559
if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
35703560
*--last = 0;
35713561
}
35723562
}
35733563
}
35743564
35753565
*last = 0;
35763566
3577
-
3567
+
35783568
35793569
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
35803570
35813571
return JIM_OK;
35823572
}
@@ -3601,11 +3591,11 @@
36013591
static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
36023592
{
36033593
#ifdef X_OK
36043594
return file_access(interp, argv[0], X_OK);
36053595
#else
3606
-
3596
+
36073597
Jim_SetResultBool(interp, 1);
36083598
return JIM_OK;
36093599
#endif
36103600
}
36113601
@@ -3626,11 +3616,11 @@
36263616
while (argc--) {
36273617
const char *path = Jim_String(argv[0]);
36283618
36293619
if (unlink(path) == -1 && errno != ENOENT) {
36303620
if (rmdir(path) == -1) {
3631
-
3621
+
36323622
if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
36333623
Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
36343624
strerror(errno));
36353625
return JIM_ERR;
36363626
}
@@ -3649,15 +3639,15 @@
36493639
36503640
static int mkdir_all(char *path)
36513641
{
36523642
int ok = 1;
36533643
3654
-
3644
+
36553645
goto first;
36563646
36573647
while (ok--) {
3658
-
3648
+
36593649
{
36603650
char *slash = strrchr(path, '/');
36613651
36623652
if (slash && slash != path) {
36633653
*slash = 0;
@@ -3670,24 +3660,24 @@
36703660
first:
36713661
if (MKDIR_DEFAULT(path) == 0) {
36723662
return 0;
36733663
}
36743664
if (errno == ENOENT) {
3675
-
3665
+
36763666
continue;
36773667
}
3678
-
3668
+
36793669
if (errno == EEXIST) {
36803670
struct stat sb;
36813671
36823672
if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
36833673
return 0;
36843674
}
3685
-
3675
+
36863676
errno = EEXIST;
36873677
}
3688
-
3678
+
36893679
break;
36903680
}
36913681
return -1;
36923682
}
36933683
@@ -3972,192 +3962,192 @@
39723962
{ "atime",
39733963
"name",
39743964
file_cmd_atime,
39753965
1,
39763966
1,
3977
-
3967
+
39783968
},
39793969
{ "mtime",
39803970
"name ?time?",
39813971
file_cmd_mtime,
39823972
1,
39833973
2,
3984
-
3974
+
39853975
},
39863976
{ "copy",
39873977
"?-force? source dest",
39883978
file_cmd_copy,
39893979
2,
39903980
3,
3991
-
3981
+
39923982
},
39933983
{ "dirname",
39943984
"name",
39953985
file_cmd_dirname,
39963986
1,
39973987
1,
3998
-
3988
+
39993989
},
40003990
{ "rootname",
40013991
"name",
40023992
file_cmd_rootname,
40033993
1,
40043994
1,
4005
-
3995
+
40063996
},
40073997
{ "extension",
40083998
"name",
40093999
file_cmd_extension,
40104000
1,
40114001
1,
4012
-
4002
+
40134003
},
40144004
{ "tail",
40154005
"name",
40164006
file_cmd_tail,
40174007
1,
40184008
1,
4019
-
4009
+
40204010
},
40214011
{ "normalize",
40224012
"name",
40234013
file_cmd_normalize,
40244014
1,
40254015
1,
4026
-
4016
+
40274017
},
40284018
{ "join",
40294019
"name ?name ...?",
40304020
file_cmd_join,
40314021
1,
40324022
-1,
4033
-
4023
+
40344024
},
40354025
{ "readable",
40364026
"name",
40374027
file_cmd_readable,
40384028
1,
40394029
1,
4040
-
4030
+
40414031
},
40424032
{ "writable",
40434033
"name",
40444034
file_cmd_writable,
40454035
1,
40464036
1,
4047
-
4037
+
40484038
},
40494039
{ "executable",
40504040
"name",
40514041
file_cmd_executable,
40524042
1,
40534043
1,
4054
-
4044
+
40554045
},
40564046
{ "exists",
40574047
"name",
40584048
file_cmd_exists,
40594049
1,
40604050
1,
4061
-
4051
+
40624052
},
40634053
{ "delete",
40644054
"?-force|--? name ...",
40654055
file_cmd_delete,
40664056
1,
40674057
-1,
4068
-
4058
+
40694059
},
40704060
{ "mkdir",
40714061
"dir ...",
40724062
file_cmd_mkdir,
40734063
1,
40744064
-1,
4075
-
4065
+
40764066
},
40774067
{ "tempfile",
40784068
"?template?",
40794069
file_cmd_tempfile,
40804070
0,
40814071
1,
4082
-
4072
+
40834073
},
40844074
{ "rename",
40854075
"?-force? source dest",
40864076
file_cmd_rename,
40874077
2,
40884078
3,
4089
-
4079
+
40904080
},
40914081
#if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
40924082
{ "link",
40934083
"?-symbolic|-hard? newname target",
40944084
file_cmd_link,
40954085
2,
40964086
3,
4097
-
4087
+
40984088
},
40994089
#endif
41004090
#if defined(HAVE_READLINK)
41014091
{ "readlink",
41024092
"name",
41034093
file_cmd_readlink,
41044094
1,
41054095
1,
4106
-
4096
+
41074097
},
41084098
#endif
41094099
{ "size",
41104100
"name",
41114101
file_cmd_size,
41124102
1,
41134103
1,
4114
-
4104
+
41154105
},
41164106
{ "stat",
41174107
"name ?var?",
41184108
file_cmd_stat,
41194109
1,
41204110
2,
4121
-
4111
+
41224112
},
41234113
{ "lstat",
41244114
"name ?var?",
41254115
file_cmd_lstat,
41264116
1,
41274117
2,
4128
-
4118
+
41294119
},
41304120
{ "type",
41314121
"name",
41324122
file_cmd_type,
41334123
1,
41344124
1,
4135
-
4125
+
41364126
},
41374127
#ifdef HAVE_GETEUID
41384128
{ "owned",
41394129
"name",
41404130
file_cmd_owned,
41414131
1,
41424132
1,
4143
-
4133
+
41444134
},
41454135
#endif
41464136
{ "isdirectory",
41474137
"name",
41484138
file_cmd_isdirectory,
41494139
1,
41504140
1,
4151
-
4141
+
41524142
},
41534143
{ "isfile",
41544144
"name",
41554145
file_cmd_isfile,
41564146
1,
41574147
1,
4158
-
4148
+
41594149
},
41604150
{
41614151
NULL
41624152
}
41634153
};
@@ -4189,11 +4179,11 @@
41894179
Jim_SetResultString(interp, "Failed to get pwd", -1);
41904180
Jim_Free(cwd);
41914181
return JIM_ERR;
41924182
}
41934183
else if (ISWINDOWS) {
4194
-
4184
+
41954185
char *p = cwd;
41964186
while ((p = strchr(p, '\\')) != NULL) {
41974187
*p++ = '/';
41984188
}
41994189
}
@@ -4213,11 +4203,10 @@
42134203
Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
42144204
Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
42154205
return JIM_OK;
42164206
}
42174207
4218
-#define _GNU_SOURCE
42194208
#include <string.h>
42204209
#include <ctype.h>
42214210
42224211
42234212
#if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4225,20 +4214,20 @@
42254214
{
42264215
Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
42274216
int i, j;
42284217
int rc;
42294218
4230
-
4219
+
42314220
for (i = 1; i < argc; i++) {
42324221
int len;
42334222
const char *arg = Jim_GetString(argv[i], &len);
42344223
42354224
if (i > 1) {
42364225
Jim_AppendString(interp, cmdlineObj, " ", 1);
42374226
}
42384227
if (strpbrk(arg, "\\\" ") == NULL) {
4239
-
4228
+
42404229
Jim_AppendString(interp, cmdlineObj, arg, len);
42414230
continue;
42424231
}
42434232
42444233
Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4279,11 +4268,11 @@
42794268
42804269
#include <errno.h>
42814270
#include <signal.h>
42824271
42834272
#if defined(__MINGW32__)
4284
-
4273
+
42854274
#ifndef STRICT
42864275
#define STRICT
42874276
#endif
42884277
#define WIN32_LEAN_AND_MEAN
42894278
#include <windows.h>
@@ -4405,14 +4394,14 @@
44054394
if (!objPtr) {
44064395
return Jim_GetEnviron();
44074396
}
44084397
44094398
4410
-
4399
+
44114400
num = Jim_ListLength(interp, objPtr);
44124401
if (num % 2) {
4413
-
4402
+
44144403
num--;
44154404
}
44164405
size = Jim_Length(objPtr) + 2;
44174406
44184407
envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4504,19 +4493,19 @@
45044493
}
45054494
45064495
45074496
struct WaitInfo
45084497
{
4509
- pidtype pid;
4510
- int status;
4511
- int flags;
4498
+ pidtype pid;
4499
+ int status;
4500
+ int flags;
45124501
};
45134502
45144503
struct WaitInfoTable {
4515
- struct WaitInfo *info;
4516
- int size;
4517
- int used;
4504
+ struct WaitInfo *info;
4505
+ int size;
4506
+ int used;
45184507
};
45194508
45204509
45214510
#define WI_DETACHED 2
45224511
@@ -4539,12 +4528,12 @@
45394528
return table;
45404529
}
45414530
45424531
static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
45434532
{
4544
- fdtype outputId;
4545
- fdtype errorId;
4533
+ fdtype outputId;
4534
+ fdtype errorId;
45464535
pidtype *pidPtr;
45474536
int numPids, result;
45484537
int child_siginfo = 1;
45494538
Jim_Obj *childErrObj;
45504539
Jim_Obj *errStrObj;
@@ -4556,11 +4545,11 @@
45564545
argc--;
45574546
numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
45584547
if (numPids < 0) {
45594548
return JIM_ERR;
45604549
}
4561
-
4550
+
45624551
listObj = Jim_NewListObj(interp, NULL, 0);
45634552
for (i = 0; i < numPids; i++) {
45644553
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
45654554
}
45664555
Jim_SetResult(interp, listObj);
@@ -4578,19 +4567,19 @@
45784567
45794568
result = JIM_OK;
45804569
45814570
errStrObj = Jim_NewStringObj(interp, "", 0);
45824571
4583
-
4572
+
45844573
if (outputId != JIM_BAD_FD) {
45854574
if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
45864575
result = JIM_ERR;
45874576
Jim_SetResultErrno(interp, "error reading from output pipe");
45884577
}
45894578
}
45904579
4591
-
4580
+
45924581
childErrObj = Jim_NewStringObj(interp, "", 0);
45934582
Jim_IncrRefCount(childErrObj);
45944583
45954584
if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
45964585
result = JIM_ERR;
@@ -4603,25 +4592,25 @@
46034592
if (ret < 0) {
46044593
Jim_SetResultErrno(interp, "error reading from error pipe");
46054594
result = JIM_ERR;
46064595
}
46074596
else if (ret > 0) {
4608
-
4597
+
46094598
child_siginfo = 0;
46104599
}
46114600
}
46124601
46134602
if (child_siginfo) {
4614
-
4603
+
46154604
Jim_AppendObj(interp, errStrObj, childErrObj);
46164605
}
46174606
Jim_DecrRefCount(interp, childErrObj);
46184607
4619
-
4608
+
46204609
Jim_RemoveTrailingNewline(errStrObj);
46214610
4622
-
4611
+
46234612
Jim_SetResult(interp, errStrObj);
46244613
46254614
return result;
46264615
}
46274616
@@ -4640,11 +4629,11 @@
46404629
for (count = table->used; count > 0; waitPtr++, count--) {
46414630
if (waitPtr->flags & WI_DETACHED) {
46424631
int status;
46434632
pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
46444633
if (pid == waitPtr->pid) {
4645
-
4634
+
46464635
table->used--;
46474636
continue;
46484637
}
46494638
}
46504639
if (waitPtr != &table->info[dest]) {
@@ -4656,36 +4645,36 @@
46564645
46574646
static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
46584647
{
46594648
int i;
46604649
4661
-
4650
+
46624651
for (i = 0; i < table->used; i++) {
46634652
if (pid == table->info[i].pid) {
4664
-
4653
+
46654654
JimWaitPid(pid, statusPtr, 0);
46664655
4667
-
4656
+
46684657
if (i != table->used - 1) {
46694658
table->info[i] = table->info[table->used - 1];
46704659
}
46714660
table->used--;
46724661
return pid;
46734662
}
46744663
}
46754664
4676
-
4665
+
46774666
return JIM_BAD_PID;
46784667
}
46794668
46804669
static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
46814670
{
46824671
int j;
46834672
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
46844673
46854674
for (j = 0; j < numPids; j++) {
4686
-
4675
+
46874676
int i;
46884677
for (i = 0; i < table->used; i++) {
46894678
if (pidPtr[j] == table->info[i].pid) {
46904679
table->info[i].flags |= WI_DETACHED;
46914680
break;
@@ -4718,16 +4707,16 @@
47184707
int cmdCount; /* Count of number of distinct commands
47194708
* found in argc/argv. */
47204709
const char *input = NULL; /* Describes input for pipeline, depending
47214710
* on "inputFile". NULL means take input
47224711
* from stdin/pipe. */
4723
- int input_len = 0;
4712
+ int input_len = 0;
47244713
4725
-#define FILE_NAME 0
4726
-#define FILE_APPEND 1
4727
-#define FILE_HANDLE 2
4728
-#define FILE_TEXT 3
4714
+#define FILE_NAME 0
4715
+#define FILE_APPEND 1
4716
+#define FILE_HANDLE 2
4717
+#define FILE_TEXT 3
47294718
47304719
int inputFile = FILE_NAME; /* 1 means input is name of input file.
47314720
* 2 means input is filehandle name.
47324721
* 0 means input holds actual
47334722
* text to be input to command. */
@@ -4748,20 +4737,20 @@
47484737
* or NULL if stderr goes to stderr/pipe. */
47494738
fdtype inputId = JIM_BAD_FD;
47504739
fdtype outputId = JIM_BAD_FD;
47514740
fdtype errorId = JIM_BAD_FD;
47524741
fdtype lastOutputId = JIM_BAD_FD;
4753
- fdtype pipeIds[2];
4742
+ fdtype pipeIds[2];
47544743
int firstArg, lastArg; /* Indexes of first and last arguments in
47554744
* current command. */
47564745
int lastBar;
47574746
int i;
47584747
pidtype pid;
47594748
char **save_environ;
47604749
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
47614750
4762
-
4751
+
47634752
char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
47644753
int arg_count = 0;
47654754
47664755
JimReapDetachedPids(table);
47674756
@@ -4807,11 +4796,11 @@
48074796
if (*output == '>') {
48084797
outputFile = FILE_APPEND;
48094798
output++;
48104799
}
48114800
if (*output == '&') {
4812
-
4801
+
48134802
output++;
48144803
dup_error = 1;
48154804
}
48164805
if (*output == '@') {
48174806
outputFile = FILE_HANDLE;
@@ -4848,11 +4837,11 @@
48484837
goto badargs;
48494838
}
48504839
lastBar = i;
48514840
cmdCount++;
48524841
}
4853
-
4842
+
48544843
arg_array[arg_count++] = (char *)arg;
48554844
continue;
48564845
}
48574846
48584847
if (i >= argc) {
@@ -4866,11 +4855,11 @@
48664855
badargs:
48674856
Jim_Free(arg_array);
48684857
return -1;
48694858
}
48704859
4871
-
4860
+
48724861
save_environ = JimSaveEnv(JimBuildEnv(interp));
48734862
48744863
if (input != NULL) {
48754864
if (inputFile == FILE_TEXT) {
48764865
inputId = JimCreateTemp(interp, input, input_len);
@@ -4877,11 +4866,11 @@
48774866
if (inputId == JIM_BAD_FD) {
48784867
goto error;
48794868
}
48804869
}
48814870
else if (inputFile == FILE_HANDLE) {
4882
-
4871
+
48834872
FILE *fh = JimGetAioFilehandle(interp, input);
48844873
48854874
if (fh == NULL) {
48864875
goto error;
48874876
}
@@ -4929,20 +4918,20 @@
49294918
}
49304919
lastOutputId = pipeIds[1];
49314920
*outPipePtr = pipeIds[0];
49324921
pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
49334922
}
4934
-
4923
+
49354924
if (error != NULL) {
49364925
if (errorFile == FILE_HANDLE) {
49374926
if (strcmp(error, "1") == 0) {
4938
-
4927
+
49394928
if (lastOutputId != JIM_BAD_FD) {
49404929
errorId = JimDupFd(lastOutputId);
49414930
}
49424931
else {
4943
-
4932
+
49444933
error = "stdout";
49454934
}
49464935
}
49474936
if (errorId == JIM_BAD_FD) {
49484937
FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4984,11 +4973,11 @@
49844973
pipe_dup_err = 1;
49854974
}
49864975
break;
49874976
}
49884977
}
4989
-
4978
+
49904979
arg_array[lastArg] = NULL;
49914980
if (lastArg == arg_count) {
49924981
outputId = lastOutputId;
49934982
}
49944983
else {
@@ -4997,16 +4986,16 @@
49974986
goto error;
49984987
}
49994988
outputId = pipeIds[1];
50004989
}
50014990
5002
-
4991
+
50034992
if (pipe_dup_err) {
50044993
errorId = outputId;
50054994
}
50064995
5007
-
4996
+
50084997
50094998
#ifdef __MINGW32__
50104999
pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
50115000
if (pid == JIM_BAD_PID) {
50125001
Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -5017,32 +5006,32 @@
50175006
if (pid < 0) {
50185007
Jim_SetResultErrno(interp, "couldn't fork child process");
50195008
goto error;
50205009
}
50215010
if (pid == 0) {
5022
-
5011
+
50235012
50245013
if (inputId != -1) dup2(inputId, 0);
50255014
if (outputId != -1) dup2(outputId, 1);
50265015
if (errorId != -1) dup2(errorId, 2);
50275016
50285017
for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
50295018
close(i);
50305019
}
50315020
5032
-
5021
+
50335022
(void)signal(SIGPIPE, SIG_DFL);
50345023
50355024
execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
50365025
5037
-
5026
+
50385027
fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
50395028
_exit(127);
50405029
}
50415030
#endif
50425031
5043
-
5032
+
50445033
50455034
if (table->used == table->size) {
50465035
table->size += WAIT_TABLE_GROW_BY;
50475036
table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
50485037
}
@@ -5051,11 +5040,11 @@
50515040
table->info[table->used].flags = 0;
50525041
table->used++;
50535042
50545043
pidPtr[numPids] = pid;
50555044
5056
-
5045
+
50575046
errorId = origErrorId;
50585047
50595048
50605049
if (inputId != JIM_BAD_FD) {
50615050
JimCloseFd(inputId);
@@ -5122,11 +5111,11 @@
51225111
{
51235112
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
51245113
int result = JIM_OK;
51255114
int i;
51265115
5127
-
5116
+
51285117
for (i = 0; i < numPids; i++) {
51295118
int waitStatus = 0;
51305119
if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
51315120
if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) {
51325121
result = JIM_ERR;
@@ -5295,21 +5284,17 @@
52955284
}
52965285
52975286
static fdtype JimOpenForRead(const char *filename)
52985287
{
52995288
return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
5300
- JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
5289
+ JimStdSecAttrs(), OPEN_EXISTING, 0, NULL);
53015290
}
53025291
53035292
static fdtype JimOpenForWrite(const char *filename, int append)
53045293
{
5305
- fdtype fd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5306
- JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
5307
- if (append && fd != JIM_BAD_FD) {
5308
- SetFilePointer(fd, 0, NULL, FILE_END);
5309
- }
5310
- return fd;
5294
+ return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5295
+ JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL);
53115296
}
53125297
53135298
static FILE *JimFdOpenForWrite(fdtype fd)
53145299
{
53155300
return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5317,11 +5302,11 @@
53175302
53185303
static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
53195304
{
53205305
DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
53215306
if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
5322
-
5307
+
53235308
return JIM_BAD_PID;
53245309
}
53255310
GetExitCodeProcess(pid, &ret);
53265311
*status = ret;
53275312
CloseHandle(pid);
@@ -5344,11 +5329,11 @@
53445329
if (handle == INVALID_HANDLE_VALUE) {
53455330
goto error;
53465331
}
53475332
53485333
if (contents != NULL) {
5349
-
5334
+
53505335
FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
53515336
if (fh == NULL) {
53525337
goto error;
53535338
}
53545339
@@ -5616,11 +5601,11 @@
56165601
#include <sys/time.h>
56175602
#endif
56185603
56195604
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
56205605
{
5621
-
5606
+
56225607
char buf[100];
56235608
time_t t;
56245609
long seconds;
56255610
56265611
const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5657,20 +5642,20 @@
56575642
56585643
if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
56595644
return -1;
56605645
}
56615646
5662
-
5647
+
56635648
localtime_r(&now, &tm);
56645649
56655650
pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
56665651
if (pt == 0 || *pt != 0) {
56675652
Jim_SetResultString(interp, "Failed to parse time according to format", -1);
56685653
return JIM_ERR;
56695654
}
56705655
5671
-
5656
+
56725657
Jim_SetResultInt(interp, mktime(&tm));
56735658
56745659
return JIM_OK;
56755660
}
56765661
#endif
@@ -5708,47 +5693,47 @@
57085693
{ "seconds",
57095694
NULL,
57105695
clock_cmd_seconds,
57115696
0,
57125697
0,
5713
-
5698
+
57145699
},
57155700
{ "clicks",
57165701
NULL,
57175702
clock_cmd_micros,
57185703
0,
57195704
0,
5720
-
5705
+
57215706
},
57225707
{ "microseconds",
57235708
NULL,
57245709
clock_cmd_micros,
57255710
0,
57265711
0,
5727
-
5712
+
57285713
},
57295714
{ "milliseconds",
57305715
NULL,
57315716
clock_cmd_millis,
57325717
0,
57335718
0,
5734
-
5719
+
57355720
},
57365721
{ "format",
57375722
"seconds ?-format format?",
57385723
clock_cmd_format,
57395724
1,
57405725
3,
5741
-
5726
+
57425727
},
57435728
#ifdef HAVE_STRPTIME
57445729
{ "scan",
57455730
"str -format format",
57465731
clock_cmd_scan,
57475732
3,
57485733
3,
5749
-
5734
+
57505735
},
57515736
#endif
57525737
{ NULL }
57535738
};
57545739
@@ -5768,11 +5753,11 @@
57685753
#include <errno.h>
57695754
57705755
57715756
static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
57725757
{
5773
-
5758
+
57745759
Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
57755760
return JIM_OK;
57765761
}
57775762
57785763
static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5784,20 +5769,20 @@
57845769
return JIM_OK;
57855770
}
57865771
57875772
patternObj = (argc == 1) ? NULL : argv[1];
57885773
5789
-
5774
+
57905775
if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
57915776
if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
5792
-
5777
+
57935778
Jim_SetResult(interp, objPtr);
57945779
return JIM_OK;
57955780
}
57965781
}
57975782
5798
-
5783
+
57995784
return Jim_DictValues(interp, objPtr, patternObj);
58005785
}
58015786
58025787
static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
58035788
{
@@ -5817,27 +5802,27 @@
58175802
Jim_Obj *resultObj;
58185803
Jim_Obj *objPtr;
58195804
Jim_Obj **dictValuesObj;
58205805
58215806
if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
5822
-
5807
+
58235808
Jim_UnsetVariable(interp, argv[0], JIM_NONE);
58245809
return JIM_OK;
58255810
}
58265811
58275812
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
58285813
58295814
if (objPtr == NULL) {
5830
-
5815
+
58315816
return JIM_OK;
58325817
}
58335818
58345819
if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
58355820
return JIM_ERR;
58365821
}
58375822
5838
-
5823
+
58395824
resultObj = Jim_NewDictObj(interp, NULL, 0);
58405825
58415826
for (i = 0; i < len; i += 2) {
58425827
if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
58435828
Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5852,11 +5837,11 @@
58525837
static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
58535838
{
58545839
Jim_Obj *objPtr;
58555840
int len = 0;
58565841
5857
-
5842
+
58585843
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
58595844
if (objPtr) {
58605845
len = Jim_DictSize(interp, objPtr);
58615846
if (len < 0) {
58625847
return JIM_ERR;
@@ -5891,11 +5876,11 @@
58915876
return JIM_ERR;
58925877
}
58935878
58945879
dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
58955880
if (!dictObj) {
5896
-
5881
+
58975882
return Jim_SetVariable(interp, argv[0], listObj);
58985883
}
58995884
else if (Jim_DictSize(interp, dictObj) < 0) {
59005885
return JIM_ERR;
59015886
}
@@ -5920,53 +5905,53 @@
59205905
{ "exists",
59215906
"arrayName",
59225907
array_cmd_exists,
59235908
1,
59245909
1,
5925
-
5910
+
59265911
},
59275912
{ "get",
59285913
"arrayName ?pattern?",
59295914
array_cmd_get,
59305915
1,
59315916
2,
5932
-
5917
+
59335918
},
59345919
{ "names",
59355920
"arrayName ?pattern?",
59365921
array_cmd_names,
59375922
1,
59385923
2,
5939
-
5924
+
59405925
},
59415926
{ "set",
59425927
"arrayName list",
59435928
array_cmd_set,
59445929
2,
59455930
2,
5946
-
5931
+
59475932
},
59485933
{ "size",
59495934
"arrayName",
59505935
array_cmd_size,
59515936
1,
59525937
1,
5953
-
5938
+
59545939
},
59555940
{ "stat",
59565941
"arrayName",
59575942
array_cmd_stat,
59585943
1,
59595944
1,
5960
-
5945
+
59615946
},
59625947
{ "unset",
59635948
"arrayName ?pattern?",
59645949
array_cmd_unset,
59655950
1,
59665951
2,
5967
-
5952
+
59685953
},
59695954
{ NULL
59705955
}
59715956
};
59725957
@@ -6002,12 +5987,11 @@
60025987
Jim_arrayInit(interp);
60035988
Jim_stdlibInit(interp);
60045989
Jim_tclcompatInit(interp);
60055990
return JIM_OK;
60065991
}
6007
-#define JIM_OPTIMIZATION
6008
-#define _GNU_SOURCE
5992
+#define JIM_OPTIMIZATION
60095993
60105994
#include <stdio.h>
60115995
#include <stdlib.h>
60125996
60135997
#include <string.h>
@@ -6072,16 +6056,10 @@
60726056
#define JimPanic(X) JimPanicDump X
60736057
#else
60746058
#define JimPanic(X)
60756059
#endif
60766060
6077
-#ifdef JIM_OPTIMIZATION
6078
-#define JIM_IF_OPTIM(X) X
6079
-#else
6080
-#define JIM_IF_OPTIM(X)
6081
-#endif
6082
-
60836061
60846062
static char JimEmptyStringRep[] = "";
60856063
60866064
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
60876065
static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -6134,34 +6112,34 @@
61346112
if (*pattern == '^') {
61356113
not++;
61366114
pattern++;
61376115
}
61386116
6139
-
6117
+
61406118
if (*pattern == ']') {
61416119
goto first;
61426120
}
61436121
}
61446122
61456123
while (*pattern && *pattern != ']') {
6146
-
6124
+
61476125
if (pattern[0] == '\\') {
61486126
first:
61496127
pattern += utf8_tounicode_case(pattern, &pchar, nocase);
61506128
}
61516129
else {
6152
-
6130
+
61536131
int start;
61546132
int end;
61556133
61566134
pattern += utf8_tounicode_case(pattern, &start, nocase);
61576135
if (pattern[0] == '-' && pattern[1]) {
6158
-
6136
+
61596137
pattern += utf8_tounicode(pattern, &pchar);
61606138
pattern += utf8_tounicode_case(pattern, &end, nocase);
61616139
6162
-
6140
+
61636141
if ((c >= start && c <= end) || (c >= end && c <= start)) {
61646142
match = 1;
61656143
}
61666144
continue;
61676145
}
@@ -6191,19 +6169,19 @@
61916169
while (pattern[1] == '*') {
61926170
pattern++;
61936171
}
61946172
pattern++;
61956173
if (!pattern[0]) {
6196
- return 1;
6174
+ return 1;
61976175
}
61986176
while (*string) {
6199
-
6177
+
62006178
if (JimGlobMatch(pattern, string, nocase))
6201
- return 1;
6179
+ return 1;
62026180
string += utf8_tounicode(string, &c);
62036181
}
6204
- return 0;
6182
+ return 0;
62056183
62066184
case '?':
62076185
string += utf8_tounicode(string, &c);
62086186
break;
62096187
@@ -6212,20 +6190,20 @@
62126190
pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
62136191
if (!pattern) {
62146192
return 0;
62156193
}
62166194
if (!*pattern) {
6217
-
6195
+
62186196
continue;
62196197
}
62206198
break;
62216199
}
62226200
case '\\':
62236201
if (pattern[1]) {
62246202
pattern++;
62256203
}
6226
-
6204
+
62276205
default:
62286206
string += utf8_tounicode_case(string, &c, nocase);
62296207
utf8_tounicode_case(pattern, &pchar, nocase);
62306208
if (pchar != c) {
62316209
return 0;
@@ -6271,11 +6249,11 @@
62716249
maxchars--;
62726250
}
62736251
if (!maxchars) {
62746252
return 0;
62756253
}
6276
-
6254
+
62776255
if (*s1) {
62786256
return 1;
62796257
}
62806258
if (*s2) {
62816259
return -1;
@@ -6312,11 +6290,11 @@
63126290
const char *p;
63136291
63146292
if (!l1 || !l2 || l1 > l2)
63156293
return -1;
63166294
6317
-
6295
+
63186296
for (p = s2 + l2 - 1; p != s2 - 1; p--) {
63196297
if (*p == *s1 && memcmp(s1, p, l1) == 0) {
63206298
return p - s2;
63216299
}
63226300
}
@@ -6371,28 +6349,28 @@
63716349
}
63726350
*sign = 1;
63736351
}
63746352
63756353
if (str[i] != '0') {
6376
-
6354
+
63776355
return 0;
63786356
}
63796357
6380
-
6358
+
63816359
switch (str[i + 1]) {
63826360
case 'x': case 'X': *base = 16; break;
63836361
case 'o': case 'O': *base = 8; break;
63846362
case 'b': case 'B': *base = 2; break;
63856363
default: return 0;
63866364
}
63876365
i += 2;
6388
-
6366
+
63896367
if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
6390
-
6368
+
63916369
return i;
63926370
}
6393
-
6371
+
63946372
*base = 10;
63956373
return 0;
63966374
}
63976375
63986376
static long jim_strtol(const char *str, char **endptr)
@@ -6406,11 +6384,11 @@
64066384
if (endptr == NULL || *endptr != str + i) {
64076385
return value * sign;
64086386
}
64096387
}
64106388
6411
-
6389
+
64126390
return strtol(str, endptr, 10);
64136391
}
64146392
64156393
64166394
static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6425,11 +6403,11 @@
64256403
if (endptr == NULL || *endptr != str + i) {
64266404
return value * sign;
64276405
}
64286406
}
64296407
6430
-
6408
+
64316409
return strtoull(str, endptr, 10);
64326410
#else
64336411
return (unsigned long)jim_strtol(str, endptr);
64346412
#endif
64356413
}
@@ -6450,40 +6428,26 @@
64506428
64516429
int Jim_StringToDouble(const char *str, double *doublePtr)
64526430
{
64536431
char *endptr;
64546432
6455
-
6433
+
64566434
errno = 0;
64576435
64586436
*doublePtr = strtod(str, &endptr);
64596437
64606438
return JimCheckConversion(str, endptr);
64616439
}
64626440
64636441
static jim_wide JimPowWide(jim_wide b, jim_wide e)
64646442
{
6465
- jim_wide res = 1;
6466
-
6467
-
6468
- if (b == 1) {
6469
-
6470
- return 1;
6471
- }
6472
- if (e < 0) {
6473
- if (b != -1) {
6474
- return 0;
6475
- }
6476
- e = -e;
6477
- }
6478
- while (e)
6479
- {
6480
- if (e & 1) {
6481
- res *= b;
6482
- }
6483
- e >>= 1;
6484
- b *= b;
6443
+ jim_wide i, res = 1;
6444
+
6445
+ if ((b == 0 && e != 0) || (e < 0))
6446
+ return 0;
6447
+ for (i = 0; i < e; i++) {
6448
+ res *= b;
64856449
}
64866450
return res;
64876451
}
64886452
64896453
#ifdef JIM_DEBUG_PANIC
@@ -6545,11 +6509,11 @@
65456509
char *Jim_StrDupLen(const char *s, int l)
65466510
{
65476511
char *copy = Jim_Alloc(l + 1);
65486512
65496513
memcpy(copy, s, l + 1);
6550
- copy[l] = 0;
6514
+ copy[l] = 0;
65516515
return copy;
65526516
}
65536517
65546518
65556519
@@ -6634,52 +6598,52 @@
66346598
}
66356599
66366600
66376601
void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
66386602
{
6639
- Jim_HashTable n;
6603
+ Jim_HashTable n;
66406604
unsigned int realsize = JimHashTableNextPower(size), i;
66416605
66426606
if (size <= ht->used)
66436607
return;
66446608
66456609
Jim_InitHashTable(&n, ht->type, ht->privdata);
66466610
n.size = realsize;
66476611
n.sizemask = realsize - 1;
66486612
n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
6649
-
6613
+
66506614
n.uniq = ht->uniq;
66516615
6652
-
6616
+
66536617
memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
66546618
66556619
n.used = ht->used;
66566620
for (i = 0; ht->used > 0; i++) {
66576621
Jim_HashEntry *he, *nextHe;
66586622
66596623
if (ht->table[i] == NULL)
66606624
continue;
66616625
6662
-
6626
+
66636627
he = ht->table[i];
66646628
while (he) {
66656629
unsigned int h;
66666630
66676631
nextHe = he->next;
6668
-
6632
+
66696633
h = Jim_HashKey(ht, he->key) & n.sizemask;
66706634
he->next = n.table[h];
66716635
n.table[h] = he;
66726636
ht->used--;
6673
-
6637
+
66746638
he = nextHe;
66756639
}
66766640
}
66776641
assert(ht->used == 0);
66786642
Jim_Free(ht->table);
66796643
6680
-
6644
+
66816645
*ht = n;
66826646
}
66836647
66846648
66856649
int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6688,11 +6652,11 @@
66886652
66896653
entry = JimInsertHashEntry(ht, key, 0);
66906654
if (entry == NULL)
66916655
return JIM_ERR;
66926656
6693
-
6657
+
66946658
Jim_SetHashKey(ht, entry, key);
66956659
Jim_SetHashVal(ht, entry, val);
66966660
return JIM_OK;
66976661
}
66986662
@@ -6714,11 +6678,11 @@
67146678
Jim_SetHashVal(ht, entry, val);
67156679
}
67166680
existed = 1;
67176681
}
67186682
else {
6719
-
6683
+
67206684
Jim_SetHashKey(ht, entry, key);
67216685
Jim_SetHashVal(ht, entry, val);
67226686
existed = 0;
67236687
}
67246688
@@ -6737,11 +6701,11 @@
67376701
he = ht->table[h];
67386702
67396703
prevHe = NULL;
67406704
while (he) {
67416705
if (Jim_CompareHashKeys(ht, key, he->key)) {
6742
-
6706
+
67436707
if (prevHe)
67446708
prevHe->next = he->next;
67456709
else
67466710
ht->table[h] = he->next;
67476711
Jim_FreeEntryKey(ht, he);
@@ -6751,19 +6715,19 @@
67516715
return JIM_OK;
67526716
}
67536717
prevHe = he;
67546718
he = he->next;
67556719
}
6756
- return JIM_ERR;
6720
+ return JIM_ERR;
67576721
}
67586722
67596723
67606724
int Jim_FreeHashTable(Jim_HashTable *ht)
67616725
{
67626726
unsigned int i;
67636727
6764
-
6728
+
67656729
for (i = 0; ht->used > 0; i++) {
67666730
Jim_HashEntry *he, *nextHe;
67676731
67686732
if ((he = ht->table[i]) == NULL)
67696733
continue;
@@ -6774,15 +6738,15 @@
67746738
Jim_Free(he);
67756739
ht->used--;
67766740
he = nextHe;
67776741
}
67786742
}
6779
-
6743
+
67806744
Jim_Free(ht->table);
6781
-
6745
+
67826746
JimResetHashTable(ht);
6783
- return JIM_OK;
6747
+ return JIM_OK;
67846748
}
67856749
67866750
Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
67876751
{
67886752
Jim_HashEntry *he;
@@ -6855,24 +6819,24 @@
68556819
static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
68566820
{
68576821
unsigned int h;
68586822
Jim_HashEntry *he;
68596823
6860
-
6824
+
68616825
JimExpandHashTableIfNeeded(ht);
68626826
6863
-
6827
+
68646828
h = Jim_HashKey(ht, key) & ht->sizemask;
6865
-
6829
+
68666830
he = ht->table[h];
68676831
while (he) {
68686832
if (Jim_CompareHashKeys(ht, key, he->key))
68696833
return replace ? he : NULL;
68706834
he = he->next;
68716835
}
68726836
6873
-
6837
+
68746838
he = Jim_Alloc(sizeof(*he));
68756839
he->next = ht->table[h];
68766840
ht->table[h] = he;
68776841
ht->used++;
68786842
he->key = NULL;
@@ -6901,16 +6865,16 @@
69016865
{
69026866
Jim_Free(key);
69036867
}
69046868
69056869
static const Jim_HashTableType JimPackageHashTableType = {
6906
- JimStringCopyHTHashFunction,
6907
- JimStringCopyHTDup,
6908
- NULL,
6909
- JimStringCopyHTKeyCompare,
6910
- JimStringCopyHTKeyDestructor,
6911
- NULL
6870
+ JimStringCopyHTHashFunction,
6871
+ JimStringCopyHTDup,
6872
+ NULL,
6873
+ JimStringCopyHTKeyCompare,
6874
+ JimStringCopyHTKeyDestructor,
6875
+ NULL
69126876
};
69136877
69146878
typedef struct AssocDataValue
69156879
{
69166880
Jim_InterpDeleteProc *delProc;
@@ -6925,16 +6889,16 @@
69256889
assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
69266890
Jim_Free(data);
69276891
}
69286892
69296893
static const Jim_HashTableType JimAssocDataHashTableType = {
6930
- JimStringCopyHTHashFunction,
6931
- JimStringCopyHTDup,
6932
- NULL,
6933
- JimStringCopyHTKeyCompare,
6934
- JimStringCopyHTKeyDestructor,
6935
- JimAssocDataHashTableValueDestructor
6894
+ JimStringCopyHTHashFunction,
6895
+ JimStringCopyHTDup,
6896
+ NULL,
6897
+ JimStringCopyHTKeyCompare,
6898
+ JimStringCopyHTKeyDestructor,
6899
+ JimAssocDataHashTableValueDestructor
69366900
};
69376901
69386902
void Jim_InitStack(Jim_Stack *stack)
69396903
{
69406904
stack->len = 0;
@@ -6987,61 +6951,56 @@
69876951
freeFunc(stack->vector[i]);
69886952
}
69896953
69906954
69916955
6992
-#define JIM_TT_NONE 0
6993
-#define JIM_TT_STR 1
6994
-#define JIM_TT_ESC 2
6995
-#define JIM_TT_VAR 3
6996
-#define JIM_TT_DICTSUGAR 4
6997
-#define JIM_TT_CMD 5
6998
-
6999
-#define JIM_TT_SEP 6
7000
-#define JIM_TT_EOL 7
7001
-#define JIM_TT_EOF 8
7002
-
7003
-#define JIM_TT_LINE 9
7004
-#define JIM_TT_WORD 10
6956
+#define JIM_TT_NONE 0
6957
+#define JIM_TT_STR 1
6958
+#define JIM_TT_ESC 2
6959
+#define JIM_TT_VAR 3
6960
+#define JIM_TT_DICTSUGAR 4
6961
+#define JIM_TT_CMD 5
6962
+
6963
+#define JIM_TT_SEP 6
6964
+#define JIM_TT_EOL 7
6965
+#define JIM_TT_EOF 8
6966
+
6967
+#define JIM_TT_LINE 9
6968
+#define JIM_TT_WORD 10
70056969
70066970
70076971
#define JIM_TT_SUBEXPR_START 11
70086972
#define JIM_TT_SUBEXPR_END 12
70096973
#define JIM_TT_SUBEXPR_COMMA 13
70106974
#define JIM_TT_EXPR_INT 14
70116975
#define JIM_TT_EXPR_DOUBLE 15
7012
-#define JIM_TT_EXPR_BOOLEAN 16
70136976
7014
-#define JIM_TT_EXPRSUGAR 17
6977
+#define JIM_TT_EXPRSUGAR 16
70156978
70166979
70176980
#define JIM_TT_EXPR_OP 20
70186981
70196982
#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
70206983
7021
-#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA)
7022
-
7023
-#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP)
7024
-
70256984
struct JimParseMissing {
7026
- int ch;
7027
- int line;
6985
+ int ch;
6986
+ int line;
70286987
};
70296988
70306989
struct JimParserCtx
70316990
{
7032
- const char *p;
7033
- int len;
7034
- int linenr;
6991
+ const char *p;
6992
+ int len;
6993
+ int linenr;
70356994
const char *tstart;
7036
- const char *tend;
7037
- int tline;
7038
- int tt;
7039
- int eof;
7040
- int inquote;
7041
- int comment;
7042
- struct JimParseMissing missing;
6995
+ const char *tend;
6996
+ int tline;
6997
+ int tt;
6998
+ int eof;
6999
+ int inquote;
7000
+ int comment;
7001
+ struct JimParseMissing missing;
70437002
};
70447003
70457004
static int JimParseScript(struct JimParserCtx *pc);
70467005
static int JimParseSep(struct JimParserCtx *pc);
70477006
static int JimParseEol(struct JimParserCtx *pc);
@@ -7071,11 +7030,11 @@
70717030
pc->missing.line = linenr;
70727031
}
70737032
70747033
static int JimParseScript(struct JimParserCtx *pc)
70757034
{
7076
- while (1) {
7035
+ while (1) {
70777036
if (!pc->len) {
70787037
pc->tstart = pc->p;
70797038
pc->tend = pc->p - 1;
70807039
pc->tline = pc->linenr;
70817040
pc->tt = JIM_TT_EOL;
@@ -7107,11 +7066,11 @@
71077066
pc->comment = 0;
71087067
return JimParseCmd(pc);
71097068
case '$':
71107069
pc->comment = 0;
71117070
if (JimParseVar(pc) == JIM_ERR) {
7112
-
7071
+
71137072
pc->tstart = pc->tend = pc->p++;
71147073
pc->len--;
71157074
pc->tt = JIM_TT_ESC;
71167075
}
71177076
return JIM_OK;
@@ -7168,11 +7127,11 @@
71687127
71697128
static void JimParseSubBrace(struct JimParserCtx *pc)
71707129
{
71717130
int level = 1;
71727131
7173
-
7132
+
71747133
pc->p++;
71757134
pc->len--;
71767135
while (pc->len) {
71777136
switch (*pc->p) {
71787137
case '\\':
@@ -7212,11 +7171,11 @@
72127171
static int JimParseSubQuote(struct JimParserCtx *pc)
72137172
{
72147173
int tt = JIM_TT_STR;
72157174
int line = pc->tline;
72167175
7217
-
7176
+
72187177
pc->p++;
72197178
pc->len--;
72207179
while (pc->len) {
72217180
switch (*pc->p) {
72227181
case '\\':
@@ -7261,11 +7220,11 @@
72617220
{
72627221
int level = 1;
72637222
int startofword = 1;
72647223
int line = pc->tline;
72657224
7266
-
7225
+
72677226
pc->p++;
72687227
pc->len--;
72697228
while (pc->len) {
72707229
switch (*pc->p) {
72717230
case '\\':
@@ -7341,17 +7300,17 @@
73417300
return JIM_OK;
73427301
}
73437302
73447303
static int JimParseVar(struct JimParserCtx *pc)
73457304
{
7346
-
7305
+
73477306
pc->p++;
73487307
pc->len--;
73497308
73507309
#ifdef EXPRSUGAR_BRACKET
73517310
if (*pc->p == '[') {
7352
-
7311
+
73537312
JimParseCmd(pc);
73547313
pc->tt = JIM_TT_EXPRSUGAR;
73557314
return JIM_OK;
73567315
}
73577316
#endif
@@ -7377,11 +7336,11 @@
73777336
pc->len--;
73787337
}
73797338
}
73807339
else {
73817340
while (1) {
7382
-
7341
+
73837342
if (pc->p[0] == ':' && pc->p[1] == ':') {
73847343
while (*pc->p == ':') {
73857344
pc->p++;
73867345
pc->len--;
73877346
}
@@ -7392,11 +7351,11 @@
73927351
pc->len--;
73937352
continue;
73947353
}
73957354
break;
73967355
}
7397
-
7356
+
73987357
if (*pc->p == '(') {
73997358
int count = 1;
74007359
const char *paren = NULL;
74017360
74027361
pc->tt = JIM_TT_DICTSUGAR;
@@ -7419,11 +7378,11 @@
74197378
if (count == 0) {
74207379
pc->p++;
74217380
pc->len--;
74227381
}
74237382
else if (paren) {
7424
-
7383
+
74257384
paren++;
74267385
pc->len += (pc->p - paren);
74277386
pc->p = paren;
74287387
}
74297388
#ifndef EXPRSUGAR_BRACKET
@@ -7444,19 +7403,19 @@
74447403
74457404
static int JimParseStr(struct JimParserCtx *pc)
74467405
{
74477406
if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
74487407
pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
7449
-
7408
+
74507409
if (*pc->p == '{') {
74517410
return JimParseBrace(pc);
74527411
}
74537412
if (*pc->p == '"') {
74547413
pc->inquote = 1;
74557414
pc->p++;
74567415
pc->len--;
7457
-
7416
+
74587417
pc->missing.line = pc->tline;
74597418
}
74607419
}
74617420
pc->tstart = pc->p;
74627421
pc->tline = pc->linenr;
@@ -7482,25 +7441,25 @@
74827441
}
74837442
pc->p++;
74847443
pc->len--;
74857444
}
74867445
else if (pc->len == 1) {
7487
-
7446
+
74887447
pc->missing.ch = '\\';
74897448
}
74907449
break;
74917450
case '(':
7492
-
7451
+
74937452
if (pc->len > 1 && pc->p[1] != '$') {
74947453
break;
74957454
}
7496
-
7455
+
74977456
case ')':
7498
-
7457
+
74997458
if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
75007459
if (pc->p == pc->tstart) {
7501
-
7460
+
75027461
pc->p++;
75037462
pc->len--;
75047463
}
75057464
pc->tend = pc->p - 1;
75067465
pc->tt = JIM_TT_ESC;
@@ -7540,11 +7499,11 @@
75407499
break;
75417500
}
75427501
pc->p++;
75437502
pc->len--;
75447503
}
7545
- return JIM_OK;
7504
+ return JIM_OK;
75467505
}
75477506
75487507
static int JimParseComment(struct JimParserCtx *pc)
75497508
{
75507509
while (*pc->p) {
@@ -7651,34 +7610,34 @@
76517610
if (c == -1) {
76527611
break;
76537612
}
76547613
val = (val << 4) | c;
76557614
}
7656
-
7615
+
76577616
if (s[i] == '{') {
76587617
if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
7659
-
7618
+
76607619
i--;
76617620
k = 0;
76627621
}
76637622
else {
7664
-
7623
+
76657624
k++;
76667625
}
76677626
}
76687627
if (k) {
7669
-
7628
+
76707629
if (s[i] == 'x') {
76717630
*p++ = val;
76727631
}
76737632
else {
76747633
p += utf8_fromunicode(p, val);
76757634
}
76767635
i += k;
76777636
break;
76787637
}
7679
-
7638
+
76807639
*p++ = s[i];
76817640
}
76827641
break;
76837642
case 'v':
76847643
*p++ = 0xb;
@@ -7687,11 +7646,11 @@
76877646
case '\0':
76887647
*p++ = '\\';
76897648
i++;
76907649
break;
76917650
case '\n':
7692
-
7651
+
76937652
*p++ = ' ';
76947653
do {
76957654
i++;
76967655
} while (s[i + 1] == ' ' || s[i + 1] == '\t');
76977656
break;
@@ -7701,11 +7660,11 @@
77017660
case '3':
77027661
case '4':
77037662
case '5':
77047663
case '6':
77057664
case '7':
7706
-
7665
+
77077666
{
77087667
int val = 0;
77097668
int c = odigitval(s[i + 1]);
77107669
77117670
val = c;
@@ -7758,16 +7717,16 @@
77587717
}
77597718
else {
77607719
len = (end - start) + 1;
77617720
token = Jim_Alloc(len + 1);
77627721
if (pc->tt != JIM_TT_ESC) {
7763
-
7722
+
77647723
memcpy(token, start, len);
77657724
token[len] = '\0';
77667725
}
77677726
else {
7768
-
7727
+
77697728
len = JimEscape(token, start, len);
77707729
}
77717730
}
77727731
77737732
return Jim_NewStringObjNoAlloc(interp, token, len);
@@ -7831,11 +7790,11 @@
78317790
while (pc->len) {
78327791
switch (*pc->p) {
78337792
case '\\':
78347793
pc->tt = JIM_TT_ESC;
78357794
if (--pc->len == 0) {
7836
-
7795
+
78377796
pc->tend = pc->p;
78387797
return JIM_OK;
78397798
}
78407799
pc->p++;
78417800
break;
@@ -7867,11 +7826,11 @@
78677826
pc->tend = pc->p - 1;
78687827
return JIM_OK;
78697828
}
78707829
if (*pc->p == '\\') {
78717830
if (--pc->len == 0) {
7872
-
7831
+
78737832
pc->tend = pc->p;
78747833
return JIM_OK;
78757834
}
78767835
pc->tt = JIM_TT_ESC;
78777836
pc->p++;
@@ -7887,24 +7846,24 @@
78877846
78887847
Jim_Obj *Jim_NewObj(Jim_Interp *interp)
78897848
{
78907849
Jim_Obj *objPtr;
78917850
7892
-
7851
+
78937852
if (interp->freeList != NULL) {
7894
-
7853
+
78957854
objPtr = interp->freeList;
78967855
interp->freeList = objPtr->nextObjPtr;
78977856
}
78987857
else {
7899
-
7858
+
79007859
objPtr = Jim_Alloc(sizeof(*objPtr));
79017860
}
79027861
79037862
objPtr->refCount = 0;
79047863
7905
-
7864
+
79067865
objPtr->prevObjPtr = NULL;
79077866
objPtr->nextObjPtr = interp->liveList;
79087867
if (interp->liveList)
79097868
interp->liveList->prevObjPtr = objPtr;
79107869
interp->liveList = objPtr;
@@ -7912,32 +7871,32 @@
79127871
return objPtr;
79137872
}
79147873
79157874
void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
79167875
{
7917
-
7876
+
79187877
JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
79197878
objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>"));
79207879
7921
-
7880
+
79227881
Jim_FreeIntRep(interp, objPtr);
7923
-
7882
+
79247883
if (objPtr->bytes != NULL) {
79257884
if (objPtr->bytes != JimEmptyStringRep)
79267885
Jim_Free(objPtr->bytes);
79277886
}
7928
-
7887
+
79297888
if (objPtr->prevObjPtr)
79307889
objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
79317890
if (objPtr->nextObjPtr)
79327891
objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
79337892
if (interp->liveList == objPtr)
79347893
interp->liveList = objPtr->nextObjPtr;
79357894
#ifdef JIM_DISABLE_OBJECT_POOL
79367895
Jim_Free(objPtr);
79377896
#else
7938
-
7897
+
79397898
objPtr->prevObjPtr = NULL;
79407899
objPtr->nextObjPtr = interp->freeList;
79417900
if (interp->freeList)
79427901
interp->freeList->prevObjPtr = objPtr;
79437902
interp->freeList = objPtr;
@@ -7960,45 +7919,45 @@
79607919
{
79617920
Jim_Obj *dupPtr;
79627921
79637922
dupPtr = Jim_NewObj(interp);
79647923
if (objPtr->bytes == NULL) {
7965
-
7924
+
79667925
dupPtr->bytes = NULL;
79677926
}
79687927
else if (objPtr->length == 0) {
7969
-
7928
+
79707929
dupPtr->bytes = JimEmptyStringRep;
79717930
dupPtr->length = 0;
79727931
dupPtr->typePtr = NULL;
79737932
return dupPtr;
79747933
}
79757934
else {
79767935
dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
79777936
dupPtr->length = objPtr->length;
7978
-
7937
+
79797938
memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
79807939
}
79817940
7982
-
7941
+
79837942
dupPtr->typePtr = objPtr->typePtr;
79847943
if (objPtr->typePtr != NULL) {
79857944
if (objPtr->typePtr->dupIntRepProc == NULL) {
79867945
dupPtr->internalRep = objPtr->internalRep;
79877946
}
79887947
else {
7989
-
7948
+
79907949
objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
79917950
}
79927951
}
79937952
return dupPtr;
79947953
}
79957954
79967955
const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
79977956
{
79987957
if (objPtr->bytes == NULL) {
7999
-
7958
+
80007959
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
80017960
objPtr->typePtr->updateStringProc(objPtr);
80027961
}
80037962
if (lenPtr)
80047963
*lenPtr = objPtr->length;
@@ -8007,11 +7966,11 @@
80077966
80087967
80097968
int Jim_Length(Jim_Obj *objPtr)
80107969
{
80117970
if (objPtr->bytes == NULL) {
8012
-
7971
+
80137972
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
80147973
objPtr->typePtr->updateStringProc(objPtr);
80157974
}
80167975
return objPtr->length;
80177976
}
@@ -8018,11 +7977,11 @@
80187977
80197978
80207979
const char *Jim_String(Jim_Obj *objPtr)
80217980
{
80227981
if (objPtr->bytes == NULL) {
8023
-
7982
+
80247983
JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
80257984
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
80267985
objPtr->typePtr->updateStringProc(objPtr);
80277986
}
80287987
return objPtr->bytes;
@@ -8078,22 +8037,22 @@
80788037
}
80798038
80808039
static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
80818040
{
80828041
if (objPtr->typePtr != &stringObjType) {
8083
-
8042
+
80848043
if (objPtr->bytes == NULL) {
8085
-
8044
+
80868045
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
80878046
objPtr->typePtr->updateStringProc(objPtr);
80888047
}
8089
-
8048
+
80908049
Jim_FreeIntRep(interp, objPtr);
8091
-
8050
+
80928051
objPtr->typePtr = &stringObjType;
80938052
objPtr->internalRep.strValue.maxLength = objPtr->length;
8094
-
8053
+
80958054
objPtr->internalRep.strValue.charLength = -1;
80968055
}
80978056
return JIM_OK;
80988057
}
80998058
@@ -8114,14 +8073,14 @@
81148073
81158074
Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
81168075
{
81178076
Jim_Obj *objPtr = Jim_NewObj(interp);
81188077
8119
-
8078
+
81208079
if (len == -1)
81218080
len = strlen(s);
8122
-
8081
+
81238082
if (len == 0) {
81248083
objPtr->bytes = JimEmptyStringRep;
81258084
}
81268085
else {
81278086
objPtr->bytes = Jim_Alloc(len + 1);
@@ -8128,25 +8087,25 @@
81288087
memcpy(objPtr->bytes, s, len);
81298088
objPtr->bytes[len] = '\0';
81308089
}
81318090
objPtr->length = len;
81328091
8133
-
8092
+
81348093
objPtr->typePtr = NULL;
81358094
return objPtr;
81368095
}
81378096
81388097
81398098
Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
81408099
{
81418100
#ifdef JIM_UTF8
8142
-
8101
+
81438102
int bytelen = utf8_index(s, charlen);
81448103
81458104
Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
81468105
8147
-
8106
+
81488107
objPtr->typePtr = &stringObjType;
81498108
objPtr->internalRep.strValue.maxLength = bytelen;
81508109
objPtr->internalRep.strValue.charLength = charlen;
81518110
81528111
return objPtr;
@@ -8173,11 +8132,11 @@
81738132
len = strlen(str);
81748133
needlen = objPtr->length + len;
81758134
if (objPtr->internalRep.strValue.maxLength < needlen ||
81768135
objPtr->internalRep.strValue.maxLength == 0) {
81778136
needlen *= 2;
8178
-
8137
+
81798138
if (needlen < 7) {
81808139
needlen = 7;
81818140
}
81828141
if (objPtr->bytes == JimEmptyStringRep) {
81838142
objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8189,11 +8148,11 @@
81898148
}
81908149
memcpy(objPtr->bytes + objPtr->length, str, len);
81918150
objPtr->bytes[objPtr->length + len] = '\0';
81928151
81938152
if (objPtr->internalRep.strValue.charLength >= 0) {
8194
-
8153
+
81958154
objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
81968155
}
81978156
objPtr->length += len;
81988157
}
81998158
@@ -8251,11 +8210,11 @@
82518210
int l1, l2;
82528211
const char *s1 = Jim_GetString(firstObjPtr, &l1);
82538212
const char *s2 = Jim_GetString(secondObjPtr, &l2);
82548213
82558214
if (nocase) {
8256
-
8215
+
82578216
return JimStringCompareLen(s1, s2, -1, nocase);
82588217
}
82598218
return JimStringCompare(s1, l1, s2, l2);
82608219
}
82618220
@@ -8353,11 +8312,11 @@
83538312
83548313
if (first == 0 && rangeLen == len) {
83558314
return strObjPtr;
83568315
}
83578316
if (len == bytelen) {
8358
-
8317
+
83598318
return Jim_NewStringObj(interp, str + first, rangeLen);
83608319
}
83618320
return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
83628321
#else
83638322
return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8382,19 +8341,19 @@
83828341
return strObjPtr;
83838342
}
83848343
83858344
str = Jim_String(strObjPtr);
83868345
8387
-
8346
+
83888347
objPtr = Jim_NewStringObjUtf8(interp, str, first);
83898348
8390
-
8349
+
83918350
if (newStrObj) {
83928351
Jim_AppendObj(interp, objPtr, newStrObj);
83938352
}
83948353
8395
-
8354
+
83968355
Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
83978356
83988357
return objPtr;
83998358
}
84008359
@@ -8493,11 +8452,11 @@
84938452
while (len) {
84948453
int c;
84958454
int n = utf8_tounicode(str, &c);
84968455
84978456
if (utf8_memchr(trimchars, trimlen, c) == NULL) {
8498
-
8457
+
84998458
break;
85008459
}
85018460
str += n;
85028461
len -= n;
85038462
}
@@ -8564,41 +8523,41 @@
85648523
85658524
len = Jim_Length(strObjPtr);
85668525
nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
85678526
85688527
if (nontrim == NULL) {
8569
-
8528
+
85708529
return Jim_NewEmptyStringObj(interp);
85718530
}
85728531
if (nontrim == strObjPtr->bytes + len) {
8573
-
8532
+
85748533
return strObjPtr;
85758534
}
85768535
85778536
if (Jim_IsShared(strObjPtr)) {
85788537
strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
85798538
}
85808539
else {
8581
-
8540
+
85828541
strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
85838542
strObjPtr->length = (nontrim - strObjPtr->bytes);
85848543
}
85858544
85868545
return strObjPtr;
85878546
}
85888547
85898548
static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
85908549
{
8591
-
8550
+
85928551
Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
85938552
8594
-
8553
+
85958554
strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
85968555
8597
-
8556
+
85988557
if (objPtr != strObjPtr && objPtr->refCount == 0) {
8599
-
8558
+
86008559
Jim_FreeNewObj(interp, objPtr);
86018560
}
86028561
86038562
return strObjPtr;
86048563
}
@@ -8616,17 +8575,17 @@
86168575
static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
86178576
{
86188577
static const char * const strclassnames[] = {
86198578
"integer", "alpha", "alnum", "ascii", "digit",
86208579
"double", "lower", "upper", "space", "xdigit",
8621
- "control", "print", "graph", "punct", "boolean",
8580
+ "control", "print", "graph", "punct",
86228581
NULL
86238582
};
86248583
enum {
86258584
STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
86268585
STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
8627
- STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN,
8586
+ STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
86288587
};
86298588
int strclass;
86308589
int len;
86318590
int i;
86328591
const char *str;
@@ -8655,17 +8614,10 @@
86558614
double d;
86568615
Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
86578616
return JIM_OK;
86588617
}
86598618
8660
- case STR_IS_BOOLEAN:
8661
- {
8662
- int b;
8663
- Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK);
8664
- return JIM_OK;
8665
- }
8666
-
86678619
case STR_IS_ALPHA: isclassfunc = isalpha; break;
86688620
case STR_IS_ALNUM: isclassfunc = isalnum; break;
86698621
case STR_IS_ASCII: isclassfunc = jim_isascii; break;
86708622
case STR_IS_DIGIT: isclassfunc = isdigit; break;
86718623
case STR_IS_LOWER: isclassfunc = islower; break;
@@ -8713,11 +8665,11 @@
87138665
87148666
if (objPtr->typePtr != &comparedStringObjType) {
87158667
Jim_FreeIntRep(interp, objPtr);
87168668
objPtr->typePtr = &comparedStringObjType;
87178669
}
8718
- objPtr->internalRep.ptr = (char *)str;
8670
+ objPtr->internalRep.ptr = (char *)str;
87198671
return 1;
87208672
}
87218673
}
87228674
87238675
static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8806,20 +8758,20 @@
88068758
int type;
88078759
} ScriptToken;
88088760
88098761
typedef struct ScriptObj
88108762
{
8811
- ScriptToken *token;
8812
- Jim_Obj *fileNameObj;
8813
- int len;
8814
- int substFlags;
8763
+ ScriptToken *token;
8764
+ Jim_Obj *fileNameObj;
8765
+ int len;
8766
+ int substFlags;
88158767
int inUse; /* Used to share a ScriptObj. Currently
88168768
only used by Jim_EvalObj() as protection against
88178769
shimmering of the currently evaluated object. */
8818
- int firstline;
8819
- int linenr;
8820
- int missing;
8770
+ int firstline;
8771
+ int linenr;
8772
+ int missing;
88218773
} ScriptObj;
88228774
88238775
static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
88248776
static int JimParseCheckMissing(Jim_Interp *interp, int ch);
88258777
static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -8847,23 +8799,23 @@
88478799
dupPtr->typePtr = NULL;
88488800
}
88498801
88508802
typedef struct
88518803
{
8852
- const char *token;
8853
- int len;
8854
- int type;
8855
- int line;
8804
+ const char *token;
8805
+ int len;
8806
+ int type;
8807
+ int line;
88568808
} ParseToken;
88578809
88588810
typedef struct
88598811
{
8860
-
8861
- ParseToken *list;
8862
- int size;
8863
- int count;
8864
- ParseToken static_list[20];
8812
+
8813
+ ParseToken *list;
8814
+ int size;
8815
+ int count;
8816
+ ParseToken static_list[20];
88658817
} ParseTokenList;
88668818
88678819
static void ScriptTokenListInit(ParseTokenList *tokenlist)
88688820
{
88698821
tokenlist->list = tokenlist->static_list;
@@ -8882,18 +8834,18 @@
88828834
int line)
88838835
{
88848836
ParseToken *t;
88858837
88868838
if (tokenlist->count == tokenlist->size) {
8887
-
8839
+
88888840
tokenlist->size *= 2;
88898841
if (tokenlist->list != tokenlist->static_list) {
88908842
tokenlist->list =
88918843
Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
88928844
}
88938845
else {
8894
-
8846
+
88958847
tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
88968848
memcpy(tokenlist->list, tokenlist->static_list,
88978849
tokenlist->count * sizeof(*tokenlist->list));
88988850
}
88998851
}
@@ -8907,20 +8859,20 @@
89078859
static int JimCountWordTokens(ParseToken *t)
89088860
{
89098861
int expand = 1;
89108862
int count = 0;
89118863
8912
-
8864
+
89138865
if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
89148866
if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
8915
-
8867
+
89168868
expand = -1;
89178869
t++;
89188870
}
89198871
}
89208872
8921
-
8873
+
89228874
while (!TOKEN_IS_SEP(t->type)) {
89238875
t++;
89248876
count++;
89258877
}
89268878
@@ -8930,11 +8882,11 @@
89308882
static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
89318883
{
89328884
Jim_Obj *objPtr;
89338885
89348886
if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
8935
-
8887
+
89368888
int len = t->len;
89378889
char *str = Jim_Alloc(len + 1);
89388890
len = JimEscape(str, t->token, len);
89398891
objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
89408892
}
@@ -8947,13 +8899,13 @@
89478899
static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
89488900
ParseTokenList *tokenlist)
89498901
{
89508902
int i;
89518903
struct ScriptToken *token;
8952
-
8904
+
89538905
int lineargs = 0;
8954
-
8906
+
89558907
ScriptToken *linefirst;
89568908
int count;
89578909
int linenr;
89588910
89598911
#ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8962,11 +8914,11 @@
89628914
printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
89638915
tokenlist->list[i].len, tokenlist->list[i].token);
89648916
}
89658917
#endif
89668918
8967
-
8919
+
89688920
count = tokenlist->count;
89698921
for (i = 0; i < tokenlist->count; i++) {
89708922
if (tokenlist->list[i].type == JIM_TT_EOL) {
89718923
count++;
89728924
}
@@ -8973,59 +8925,59 @@
89738925
}
89748926
linenr = script->firstline = tokenlist->list[0].line;
89758927
89768928
token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
89778929
8978
-
8930
+
89798931
linefirst = token++;
89808932
89818933
for (i = 0; i < tokenlist->count; ) {
8982
-
8934
+
89838935
int wordtokens;
89848936
8985
-
8937
+
89868938
while (tokenlist->list[i].type == JIM_TT_SEP) {
89878939
i++;
89888940
}
89898941
89908942
wordtokens = JimCountWordTokens(tokenlist->list + i);
89918943
89928944
if (wordtokens == 0) {
8993
-
8945
+
89948946
if (lineargs) {
89958947
linefirst->type = JIM_TT_LINE;
89968948
linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
89978949
Jim_IncrRefCount(linefirst->objPtr);
89988950
8999
-
8951
+
90008952
lineargs = 0;
90018953
linefirst = token++;
90028954
}
90038955
i++;
90048956
continue;
90058957
}
90068958
else if (wordtokens != 1) {
9007
-
8959
+
90088960
token->type = JIM_TT_WORD;
90098961
token->objPtr = Jim_NewIntObj(interp, wordtokens);
90108962
Jim_IncrRefCount(token->objPtr);
90118963
token++;
90128964
if (wordtokens < 0) {
9013
-
8965
+
90148966
i++;
90158967
wordtokens = -wordtokens - 1;
90168968
lineargs--;
90178969
}
90188970
}
90198971
90208972
if (lineargs == 0) {
9021
-
8973
+
90228974
linenr = tokenlist->list[i].line;
90238975
}
90248976
lineargs++;
90258977
9026
-
8978
+
90278979
while (wordtokens--) {
90288980
const ParseToken *t = &tokenlist->list[i++];
90298981
90308982
token->type = t->type;
90318983
token->objPtr = JimMakeScriptObj(interp, t);
@@ -9097,11 +9049,11 @@
90979049
token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
90989050
90999051
for (i = 0; i < tokenlist->count; i++) {
91009052
const ParseToken *t = &tokenlist->list[i];
91019053
9102
-
9054
+
91039055
token->type = t->type;
91049056
token->objPtr = JimMakeScriptObj(interp, t);
91059057
Jim_IncrRefCount(token->objPtr);
91069058
token++;
91079059
}
@@ -9116,29 +9068,29 @@
91169068
struct JimParserCtx parser;
91179069
struct ScriptObj *script;
91189070
ParseTokenList tokenlist;
91199071
int line = 1;
91209072
9121
-
9073
+
91229074
if (objPtr->typePtr == &sourceObjType) {
91239075
line = objPtr->internalRep.sourceValue.lineNumber;
91249076
}
91259077
9126
-
9078
+
91279079
ScriptTokenListInit(&tokenlist);
91289080
91299081
JimParserInit(&parser, scriptText, scriptTextLen, line);
91309082
while (!parser.eof) {
91319083
JimParseScript(&parser);
91329084
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
91339085
parser.tline);
91349086
}
91359087
9136
-
9088
+
91379089
ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
91389090
9139
-
9091
+
91409092
script = Jim_Alloc(sizeof(*script));
91419093
memset(script, 0, sizeof(*script));
91429094
script->inUse = 1;
91439095
if (objPtr->typePtr == &sourceObjType) {
91449096
script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -9150,14 +9102,14 @@
91509102
script->missing = parser.missing.ch;
91519103
script->linenr = parser.missing.line;
91529104
91539105
ScriptObjAddTokens(interp, script, &tokenlist);
91549106
9155
-
9107
+
91569108
ScriptTokenListFree(&tokenlist);
91579109
9158
-
9110
+
91599111
Jim_FreeIntRep(interp, objPtr);
91609112
Jim_SetIntRepPtr(objPtr, script);
91619113
objPtr->typePtr = &scriptObjType;
91629114
}
91639115
@@ -9164,11 +9116,11 @@
91649116
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
91659117
91669118
static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
91679119
{
91689120
if (objPtr == interp->emptyObj) {
9169
-
9121
+
91709122
objPtr = interp->nullScriptObj;
91719123
}
91729124
91739125
if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
91749126
JimSetScriptFromAny(interp, objPtr);
@@ -9203,17 +9155,17 @@
92039155
Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
92049156
Jim_Free(cmdPtr->u.proc.staticVars);
92059157
}
92069158
}
92079159
else {
9208
-
9160
+
92099161
if (cmdPtr->u.native.delProc) {
92109162
cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
92119163
}
92129164
}
92139165
if (cmdPtr->prevCmd) {
9214
-
9166
+
92159167
JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
92169168
}
92179169
Jim_Free(cmdPtr);
92189170
}
92199171
}
@@ -9224,46 +9176,46 @@
92249176
Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
92259177
Jim_Free(val);
92269178
}
92279179
92289180
static const Jim_HashTableType JimVariablesHashTableType = {
9229
- JimStringCopyHTHashFunction,
9230
- JimStringCopyHTDup,
9231
- NULL,
9232
- JimStringCopyHTKeyCompare,
9233
- JimStringCopyHTKeyDestructor,
9234
- JimVariablesHTValDestructor
9181
+ JimStringCopyHTHashFunction,
9182
+ JimStringCopyHTDup,
9183
+ NULL,
9184
+ JimStringCopyHTKeyCompare,
9185
+ JimStringCopyHTKeyDestructor,
9186
+ JimVariablesHTValDestructor
92359187
};
92369188
92379189
static void JimCommandsHT_ValDestructor(void *interp, void *val)
92389190
{
92399191
JimDecrCmdRefCount(interp, val);
92409192
}
92419193
92429194
static const Jim_HashTableType JimCommandsHashTableType = {
9243
- JimStringCopyHTHashFunction,
9244
- JimStringCopyHTDup,
9245
- NULL,
9246
- JimStringCopyHTKeyCompare,
9247
- JimStringCopyHTKeyDestructor,
9248
- JimCommandsHT_ValDestructor
9195
+ JimStringCopyHTHashFunction,
9196
+ JimStringCopyHTDup,
9197
+ NULL,
9198
+ JimStringCopyHTKeyCompare,
9199
+ JimStringCopyHTKeyDestructor,
9200
+ JimCommandsHT_ValDestructor
92499201
};
92509202
92519203
92529204
92539205
#ifdef jim_ext_namespace
92549206
static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
92559207
{
92569208
const char *name = Jim_String(nsObj);
92579209
if (name[0] == ':' && name[1] == ':') {
9258
-
9210
+
92599211
while (*++name == ':') {
92609212
}
92619213
nsObj = Jim_NewStringObj(interp, name, -1);
92629214
}
92639215
else if (Jim_Length(interp->framePtr->nsObj)) {
9264
-
9216
+
92659217
nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
92669218
Jim_AppendStrings(interp, nsObj, "::", name, NULL);
92679219
}
92689220
return nsObj;
92699221
}
@@ -9287,16 +9239,16 @@
92879239
static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
92889240
{
92899241
Jim_Obj *objPtr = interp->emptyObj;
92909242
92919243
if (name[0] == ':' && name[1] == ':') {
9292
-
9244
+
92939245
while (*++name == ':') {
92949246
}
92959247
}
92969248
else if (Jim_Length(interp->framePtr->nsObj)) {
9297
-
9249
+
92989250
objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
92999251
Jim_AppendStrings(interp, objPtr, "::", name, NULL);
93009252
name = Jim_String(objPtr);
93019253
}
93029254
Jim_IncrRefCount(objPtr);
@@ -9305,11 +9257,11 @@
93059257
}
93069258
93079259
#define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
93089260
93099261
#else
9310
-
9262
+
93119263
#define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
93129264
#define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
93139265
93149266
Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
93159267
{
@@ -9324,17 +9276,17 @@
93249276
93259277
Jim_InterpIncrProcEpoch(interp);
93269278
}
93279279
93289280
if (he && interp->local) {
9329
-
9281
+
93309282
cmd->prevCmd = Jim_GetHashEntryVal(he);
93319283
Jim_SetHashVal(&interp->commands, he, cmd);
93329284
}
93339285
else {
93349286
if (he) {
9335
-
9287
+
93369288
Jim_DeleteHashEntry(&interp->commands, name);
93379289
}
93389290
93399291
Jim_AddHashEntry(&interp->commands, name, cmd);
93409292
}
@@ -9345,11 +9297,11 @@
93459297
int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
93469298
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
93479299
{
93489300
Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
93499301
9350
-
9302
+
93519303
memset(cmdPtr, 0, sizeof(*cmdPtr));
93529304
cmdPtr->inUse = 1;
93539305
cmdPtr->u.native.delProc = delProc;
93549306
cmdPtr->u.native.cmdProc = cmdProc;
93559307
cmdPtr->u.native.privData = privData;
@@ -9374,11 +9326,11 @@
93749326
Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
93759327
Jim_Var *varPtr;
93769328
int subLen;
93779329
93789330
objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
9379
-
9331
+
93809332
subLen = Jim_ListLength(interp, objPtr);
93819333
if (subLen == 1 || subLen == 2) {
93829334
nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
93839335
if (subLen == 1) {
93849336
initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9420,19 +9372,19 @@
94209372
94219373
static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
94229374
{
94239375
#ifdef jim_ext_namespace
94249376
if (cmdPtr->isproc) {
9425
-
9377
+
94269378
const char *pt = strrchr(cmdname, ':');
94279379
if (pt && pt != cmdname && pt[-1] == ':') {
94289380
Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
94299381
cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
94309382
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
94319383
94329384
if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
9433
-
9385
+
94349386
Jim_InterpIncrProcEpoch(interp);
94359387
}
94369388
}
94379389
}
94389390
#endif
@@ -9445,11 +9397,11 @@
94459397
int argListLen;
94469398
int i;
94479399
94489400
argListLen = Jim_ListLength(interp, argListObjPtr);
94499401
9450
-
9402
+
94519403
cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
94529404
memset(cmdPtr, 0, sizeof(*cmdPtr));
94539405
cmdPtr->inUse = 1;
94549406
cmdPtr->isproc = 1;
94559407
cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9460,24 +9412,24 @@
94609412
cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
94619413
Jim_IncrRefCount(argListObjPtr);
94629414
Jim_IncrRefCount(bodyObjPtr);
94639415
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
94649416
9465
-
9417
+
94669418
if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
94679419
goto err;
94689420
}
94699421
9470
-
9471
-
9422
+
9423
+
94729424
for (i = 0; i < argListLen; i++) {
94739425
Jim_Obj *argPtr;
94749426
Jim_Obj *nameObjPtr;
94759427
Jim_Obj *defaultObjPtr;
94769428
int len;
94779429
9478
-
9430
+
94799431
argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
94809432
len = Jim_ListLength(interp, argPtr);
94819433
if (len == 0) {
94829434
Jim_SetResultString(interp, "argument with no name", -1);
94839435
err:
@@ -9488,16 +9440,16 @@
94889440
Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
94899441
goto err;
94909442
}
94919443
94929444
if (len == 2) {
9493
-
9445
+
94949446
nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
94959447
defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
94969448
}
94979449
else {
9498
-
9450
+
94999451
nameObjPtr = argPtr;
95009452
defaultObjPtr = NULL;
95019453
}
95029454
95039455
@@ -9558,29 +9510,29 @@
95589510
}
95599511
95609512
fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
95619513
fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
95629514
9563
-
9515
+
95649516
he = Jim_FindHashEntry(&interp->commands, fqold);
95659517
if (he == NULL) {
95669518
Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
95679519
}
95689520
else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
95699521
Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
95709522
}
95719523
else {
9572
-
9524
+
95739525
cmdPtr = Jim_GetHashEntryVal(he);
95749526
JimIncrCmdRefCount(cmdPtr);
95759527
JimUpdateProcNamespace(interp, cmdPtr, fqnew);
95769528
Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
95779529
9578
-
9530
+
95799531
Jim_DeleteHashEntry(&interp->commands, fqold);
95809532
9581
-
9533
+
95829534
Jim_InterpIncrProcEpoch(interp);
95839535
95849536
ret = JIM_OK;
95859537
}
95869538
@@ -9619,23 +9571,23 @@
96199571
objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
96209572
#ifdef jim_ext_namespace
96219573
|| !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
96229574
#endif
96239575
) {
9576
+
96249577
9625
-
9626
-
9578
+
96279579
const char *name = Jim_String(objPtr);
96289580
Jim_HashEntry *he;
96299581
96309582
if (name[0] == ':' && name[1] == ':') {
96319583
while (*++name == ':') {
96329584
}
96339585
}
96349586
#ifdef jim_ext_namespace
96359587
else if (Jim_Length(interp->framePtr->nsObj)) {
9636
-
9588
+
96379589
Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
96389590
Jim_AppendStrings(interp, nameObj, "::", name, NULL);
96399591
he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
96409592
Jim_FreeNewObj(interp, nameObj);
96419593
if (he) {
@@ -9642,11 +9594,11 @@
96429594
goto found;
96439595
}
96449596
}
96459597
#endif
96469598
9647
-
9599
+
96489600
he = Jim_FindHashEntry(&interp->commands, name);
96499601
if (he == NULL) {
96509602
if (flags & JIM_ERRMSG) {
96519603
Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
96529604
}
@@ -9655,11 +9607,11 @@
96559607
#ifdef jim_ext_namespace
96569608
found:
96579609
#endif
96589610
cmd = Jim_GetHashEntryVal(he);
96599611
9660
-
9612
+
96619613
Jim_FreeIntRep(interp, objPtr);
96629614
objPtr->typePtr = &commandObjType;
96639615
objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
96649616
objPtr->internalRep.cmdValue.cmdPtr = cmd;
96659617
objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9674,11 +9626,11 @@
96749626
return cmd;
96759627
}
96769628
96779629
96789630
9679
-#define JIM_DICT_SUGAR 100
9631
+#define JIM_DICT_SUGAR 100
96809632
96819633
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
96829634
96839635
static const Jim_ObjType variableObjType = {
96849636
"variable",
@@ -9688,11 +9640,11 @@
96889640
JIM_TYPE_REFERENCES,
96899641
};
96909642
96919643
static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
96929644
{
9693
-
9645
+
96949646
if (nameObjPtr->typePtr != &variableObjType) {
96959647
int len;
96969648
const char *str = Jim_GetString(nameObjPtr, &len);
96979649
if (memchr(str, '\0', len)) {
96989650
Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9708,18 +9660,18 @@
97089660
Jim_CallFrame *framePtr;
97099661
Jim_HashEntry *he;
97109662
int global;
97119663
int len;
97129664
9713
-
9665
+
97149666
if (objPtr->typePtr == &variableObjType) {
97159667
framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
97169668
if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
9717
-
9669
+
97189670
return JIM_OK;
97199671
}
9720
-
9672
+
97219673
}
97229674
else if (objPtr->typePtr == &dictSubstObjType) {
97239675
return JIM_DICT_SUGAR;
97249676
}
97259677
else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9727,11 +9679,11 @@
97279679
}
97289680
97299681
97309682
varName = Jim_GetString(objPtr, &len);
97319683
9732
-
9684
+
97339685
if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
97349686
return JIM_DICT_SUGAR;
97359687
}
97369688
97379689
if (varName[0] == ':' && varName[1] == ':') {
@@ -9743,23 +9695,23 @@
97439695
else {
97449696
global = 0;
97459697
framePtr = interp->framePtr;
97469698
}
97479699
9748
-
9700
+
97499701
he = Jim_FindHashEntry(&framePtr->vars, varName);
97509702
if (he == NULL) {
97519703
if (!global && framePtr->staticVars) {
9752
-
9704
+
97539705
he = Jim_FindHashEntry(framePtr->staticVars, varName);
97549706
}
97559707
if (he == NULL) {
97569708
return JIM_ERR;
97579709
}
97589710
}
97599711
9760
-
9712
+
97619713
Jim_FreeIntRep(interp, objPtr);
97629714
objPtr->typePtr = &variableObjType;
97639715
objPtr->internalRep.varValue.callFrameId = framePtr->id;
97649716
objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
97659717
objPtr->internalRep.varValue.global = global;
@@ -9774,11 +9726,11 @@
97749726
{
97759727
const char *name;
97769728
Jim_CallFrame *framePtr;
97779729
int global;
97789730
9779
-
9731
+
97809732
Jim_Var *var = Jim_Alloc(sizeof(*var));
97819733
97829734
var->objPtr = valObjPtr;
97839735
Jim_IncrRefCount(valObjPtr);
97849736
var->linkFramePtr = NULL;
@@ -9793,14 +9745,14 @@
97939745
else {
97949746
framePtr = interp->framePtr;
97959747
global = 0;
97969748
}
97979749
9798
-
9750
+
97999751
Jim_AddHashEntry(&framePtr->vars, name, var);
98009752
9801
-
9753
+
98029754
Jim_FreeIntRep(interp, nameObjPtr);
98039755
nameObjPtr->typePtr = &variableObjType;
98049756
nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
98059757
nameObjPtr->internalRep.varValue.varPtr = var;
98069758
nameObjPtr->internalRep.varValue.global = global;
@@ -9830,11 +9782,11 @@
98309782
if (var->linkFramePtr == NULL) {
98319783
Jim_IncrRefCount(valObjPtr);
98329784
Jim_DecrRefCount(interp, var->objPtr);
98339785
var->objPtr = valObjPtr;
98349786
}
9835
- else {
9787
+ else {
98369788
Jim_CallFrame *savedCallFrame;
98379789
98389790
savedCallFrame = interp->framePtr;
98399791
interp->framePtr = var->linkFramePtr;
98409792
err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9891,14 +9843,14 @@
98919843
const char *varName;
98929844
const char *targetName;
98939845
Jim_CallFrame *framePtr;
98949846
Jim_Var *varPtr;
98959847
9896
-
9848
+
98979849
switch (SetVariableFromAny(interp, nameObjPtr)) {
98989850
case JIM_DICT_SUGAR:
9899
-
9851
+
99009852
Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
99019853
return JIM_ERR;
99029854
99039855
case JIM_OK:
99049856
varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9906,23 +9858,23 @@
99069858
if (varPtr->linkFramePtr == NULL) {
99079859
Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
99089860
return JIM_ERR;
99099861
}
99109862
9911
-
9863
+
99129864
varPtr->linkFramePtr = NULL;
99139865
break;
99149866
}
99159867
9916
-
9917
-
9868
+
9869
+
99189870
varName = Jim_String(nameObjPtr);
99199871
99209872
if (varName[0] == ':' && varName[1] == ':') {
99219873
while (*++varName == ':') {
99229874
}
9923
-
9875
+
99249876
framePtr = interp->topFramePtr;
99259877
}
99269878
else {
99279879
framePtr = interp->framePtr;
99289880
}
@@ -9942,15 +9894,15 @@
99429894
nameObjPtr);
99439895
Jim_DecrRefCount(interp, targetNameObjPtr);
99449896
return JIM_ERR;
99459897
}
99469898
9947
-
9899
+
99489900
if (framePtr == targetCallFrame) {
99499901
Jim_Obj *objPtr = targetNameObjPtr;
99509902
9951
-
9903
+
99529904
while (1) {
99539905
if (strcmp(Jim_String(objPtr), varName) == 0) {
99549906
Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
99559907
Jim_DecrRefCount(interp, targetNameObjPtr);
99569908
return JIM_ERR;
@@ -9962,13 +9914,13 @@
99629914
break;
99639915
objPtr = varPtr->objPtr;
99649916
}
99659917
}
99669918
9967
-
9919
+
99689920
Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
9969
-
9921
+
99709922
nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
99719923
Jim_DecrRefCount(interp, targetNameObjPtr);
99729924
return JIM_OK;
99739925
}
99749926
@@ -9982,26 +9934,26 @@
99829934
return varPtr->objPtr;
99839935
}
99849936
else {
99859937
Jim_Obj *objPtr;
99869938
9987
-
9939
+
99889940
Jim_CallFrame *savedCallFrame = interp->framePtr;
99899941
99909942
interp->framePtr = varPtr->linkFramePtr;
99919943
objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
99929944
interp->framePtr = savedCallFrame;
99939945
if (objPtr) {
99949946
return objPtr;
99959947
}
9996
-
9948
+
99979949
}
99989950
}
99999951
break;
100009952
100019953
case JIM_DICT_SUGAR:
10002
-
9954
+
100039955
return JimDictSugarGet(interp, nameObjPtr, flags);
100049956
}
100059957
if (flags & JIM_ERRMSG) {
100069958
Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
100079959
}
@@ -10051,17 +10003,17 @@
1005110003
int retval;
1005210004
Jim_CallFrame *framePtr;
1005310005
1005410006
retval = SetVariableFromAny(interp, nameObjPtr);
1005510007
if (retval == JIM_DICT_SUGAR) {
10056
-
10008
+
1005710009
return JimDictSugarSet(interp, nameObjPtr, NULL);
1005810010
}
1005910011
else if (retval == JIM_OK) {
1006010012
varPtr = nameObjPtr->internalRep.varValue.varPtr;
1006110013
10062
-
10014
+
1006310015
if (varPtr->linkFramePtr) {
1006410016
framePtr = interp->framePtr;
1006510017
interp->framePtr = varPtr->linkFramePtr;
1006610018
retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
1006710019
interp->framePtr = framePtr;
@@ -10076,11 +10028,11 @@
1007610028
framePtr = interp->framePtr;
1007710029
}
1007810030
1007910031
retval = Jim_DeleteHashEntry(&framePtr->vars, name);
1008010032
if (retval == JIM_OK) {
10081
-
10033
+
1008210034
framePtr->id = interp->callFrameEpoch++;
1008310035
}
1008410036
}
1008510037
}
1008610038
if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -10109,11 +10061,11 @@
1010910061
keyLen = (str + len) - p;
1011010062
if (str[len - 1] == ')') {
1011110063
keyLen--;
1011210064
}
1011310065
10114
-
10066
+
1011510067
keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
1011610068
1011710069
Jim_IncrRefCount(varObjPtr);
1011810070
Jim_IncrRefCount(keyObjPtr);
1011910071
*varPtrPtr = varObjPtr;
@@ -10128,23 +10080,23 @@
1012810080
1012910081
err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
1013010082
&objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
1013110083
1013210084
if (err == JIM_OK) {
10133
-
10085
+
1013410086
Jim_SetEmptyResult(interp);
1013510087
}
1013610088
else {
1013710089
if (!valObjPtr) {
10138
-
10090
+
1013910091
if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
1014010092
Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
1014110093
objPtr);
1014210094
return err;
1014310095
}
1014410096
}
10145
-
10097
+
1014610098
Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
1014710099
(valObjPtr ? "set" : "unset"), objPtr);
1014810100
}
1014910101
return err;
1015010102
}
@@ -10166,11 +10118,11 @@
1016610118
Jim_SetResultFormatted(interp,
1016710119
"can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
1016810120
ret < 0 ? "variable isn't" : "no such element in");
1016910121
}
1017010122
else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
10171
-
10123
+
1017210124
Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
1017310125
}
1017410126
1017510127
return resObjPtr;
1017610128
}
@@ -10208,11 +10160,11 @@
1020810160
{
1020910161
if (objPtr->typePtr != &dictSubstObjType) {
1021010162
Jim_Obj *varObjPtr, *keyObjPtr;
1021110163
1021210164
if (objPtr->typePtr == &interpolatedObjType) {
10213
-
10165
+
1021410166
1021510167
varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
1021610168
keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
1021710169
1021810170
Jim_IncrRefCount(varObjPtr);
@@ -10253,11 +10205,11 @@
1025310205
static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
1025410206
{
1025510207
Jim_Obj *resultObjPtr;
1025610208
1025710209
if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
10258
-
10210
+
1025910211
resultObjPtr->refCount--;
1026010212
return resultObjPtr;
1026110213
}
1026210214
return NULL;
1026310215
}
@@ -10297,11 +10249,11 @@
1029710249
return cf;
1029810250
}
1029910251
1030010252
static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
1030110253
{
10302
-
10254
+
1030310255
if (localCommands) {
1030410256
Jim_Obj *cmdNameObj;
1030510257
1030610258
while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
1030710259
Jim_HashEntry *he;
@@ -10316,20 +10268,20 @@
1031610268
Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
1031710269
if (cmd->prevCmd) {
1031810270
Jim_Cmd *prevCmd = cmd->prevCmd;
1031910271
cmd->prevCmd = NULL;
1032010272
10321
-
10273
+
1032210274
JimDecrCmdRefCount(interp, cmd);
1032310275
10324
-
10276
+
1032510277
Jim_SetHashVal(ht, he, prevCmd);
1032610278
}
1032710279
else {
1032810280
Jim_DeleteHashEntry(ht, fqname);
10281
+ Jim_InterpIncrProcEpoch(interp);
1032910282
}
10330
- Jim_InterpIncrProcEpoch(interp);
1033110283
}
1033210284
Jim_DecrRefCount(interp, cmdNameObj);
1033310285
JimFreeQualifiedName(interp, fqObjName);
1033410286
}
1033510287
Jim_FreeStack(localCommands);
@@ -10337,12 +10289,12 @@
1033710289
}
1033810290
return JIM_OK;
1033910291
}
1034010292
1034110293
10342
-#define JIM_FCF_FULL 0
10343
-#define JIM_FCF_REUSE 1
10294
+#define JIM_FCF_FULL 0
10295
+#define JIM_FCF_REUSE 1
1034410296
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
1034510297
{
1034610298
JimDeleteLocalProcs(interp, cf->localCommands);
1034710299
1034810300
if (cf->procArgsObjPtr)
@@ -10375,10 +10327,263 @@
1037510327
cf->next = interp->freeFramesList;
1037610328
interp->freeFramesList = cf;
1037710329
}
1037810330
1037910331
10332
+#ifdef JIM_REFERENCES
10333
+
10334
+static void JimReferencesHTValDestructor(void *interp, void *val)
10335
+{
10336
+ Jim_Reference *refPtr = (void *)val;
10337
+
10338
+ Jim_DecrRefCount(interp, refPtr->objPtr);
10339
+ if (refPtr->finalizerCmdNamePtr != NULL) {
10340
+ Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10341
+ }
10342
+ Jim_Free(val);
10343
+}
10344
+
10345
+static unsigned int JimReferencesHTHashFunction(const void *key)
10346
+{
10347
+
10348
+ const unsigned long *widePtr = key;
10349
+ unsigned int intValue = (unsigned int)*widePtr;
10350
+
10351
+ return Jim_IntHashFunction(intValue);
10352
+}
10353
+
10354
+static void *JimReferencesHTKeyDup(void *privdata, const void *key)
10355
+{
10356
+ void *copy = Jim_Alloc(sizeof(unsigned long));
10357
+
10358
+ JIM_NOTUSED(privdata);
10359
+
10360
+ memcpy(copy, key, sizeof(unsigned long));
10361
+ return copy;
10362
+}
10363
+
10364
+static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2)
10365
+{
10366
+ JIM_NOTUSED(privdata);
10367
+
10368
+ return memcmp(key1, key2, sizeof(unsigned long)) == 0;
10369
+}
10370
+
10371
+static void JimReferencesHTKeyDestructor(void *privdata, void *key)
10372
+{
10373
+ JIM_NOTUSED(privdata);
10374
+
10375
+ Jim_Free(key);
10376
+}
10377
+
10378
+static const Jim_HashTableType JimReferencesHashTableType = {
10379
+ JimReferencesHTHashFunction,
10380
+ JimReferencesHTKeyDup,
10381
+ NULL,
10382
+ JimReferencesHTKeyCompare,
10383
+ JimReferencesHTKeyDestructor,
10384
+ JimReferencesHTValDestructor
10385
+};
10386
+
10387
+
10388
+
10389
+#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
10390
+
10391
+static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
10392
+{
10393
+ const char *fmt = "<reference.<%s>.%020lu>";
10394
+
10395
+ sprintf(buf, fmt, refPtr->tag, id);
10396
+ return JIM_REFERENCE_SPACE;
10397
+}
10398
+
10399
+static void UpdateStringOfReference(struct Jim_Obj *objPtr);
10400
+
10401
+static const Jim_ObjType referenceObjType = {
10402
+ "reference",
10403
+ NULL,
10404
+ NULL,
10405
+ UpdateStringOfReference,
10406
+ JIM_TYPE_REFERENCES,
10407
+};
10408
+
10409
+static void UpdateStringOfReference(struct Jim_Obj *objPtr)
10410
+{
10411
+ char buf[JIM_REFERENCE_SPACE + 1];
10412
+
10413
+ JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id);
10414
+ JimSetStringBytes(objPtr, buf);
10415
+}
10416
+
10417
+static int isrefchar(int c)
10418
+{
10419
+ return (c == '_' || isalnum(c));
10420
+}
10421
+
10422
+static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
10423
+{
10424
+ unsigned long value;
10425
+ int i, len;
10426
+ const char *str, *start, *end;
10427
+ char refId[21];
10428
+ Jim_Reference *refPtr;
10429
+ Jim_HashEntry *he;
10430
+ char *endptr;
10431
+
10432
+
10433
+ str = Jim_GetString(objPtr, &len);
10434
+
10435
+ if (len < JIM_REFERENCE_SPACE)
10436
+ goto badformat;
10437
+
10438
+ start = str;
10439
+ end = str + len - 1;
10440
+ while (*start == ' ')
10441
+ start++;
10442
+ while (*end == ' ' && end > start)
10443
+ end--;
10444
+ if (end - start + 1 != JIM_REFERENCE_SPACE)
10445
+ goto badformat;
10446
+
10447
+ if (memcmp(start, "<reference.<", 12) != 0)
10448
+ goto badformat;
10449
+ if (start[12 + JIM_REFERENCE_TAGLEN] != '>' || end[0] != '>')
10450
+ goto badformat;
10451
+
10452
+ for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10453
+ if (!isrefchar(start[12 + i]))
10454
+ goto badformat;
10455
+ }
10456
+
10457
+ memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
10458
+ refId[20] = '\0';
10459
+
10460
+ value = strtoul(refId, &endptr, 10);
10461
+ if (JimCheckConversion(refId, endptr) != JIM_OK)
10462
+ goto badformat;
10463
+
10464
+ he = Jim_FindHashEntry(&interp->references, &value);
10465
+ if (he == NULL) {
10466
+ Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
10467
+ return JIM_ERR;
10468
+ }
10469
+ refPtr = Jim_GetHashEntryVal(he);
10470
+
10471
+ Jim_FreeIntRep(interp, objPtr);
10472
+ objPtr->typePtr = &referenceObjType;
10473
+ objPtr->internalRep.refValue.id = value;
10474
+ objPtr->internalRep.refValue.refPtr = refPtr;
10475
+ return JIM_OK;
10476
+
10477
+ badformat:
10478
+ Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
10479
+ return JIM_ERR;
10480
+}
10481
+
10482
+Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
10483
+{
10484
+ struct Jim_Reference *refPtr;
10485
+ unsigned long id;
10486
+ Jim_Obj *refObjPtr;
10487
+ const char *tag;
10488
+ int tagLen, i;
10489
+
10490
+
10491
+ Jim_CollectIfNeeded(interp);
10492
+
10493
+ refPtr = Jim_Alloc(sizeof(*refPtr));
10494
+ refPtr->objPtr = objPtr;
10495
+ Jim_IncrRefCount(objPtr);
10496
+ refPtr->finalizerCmdNamePtr = cmdNamePtr;
10497
+ if (cmdNamePtr)
10498
+ Jim_IncrRefCount(cmdNamePtr);
10499
+ id = interp->referenceNextId++;
10500
+ Jim_AddHashEntry(&interp->references, &id, refPtr);
10501
+ refObjPtr = Jim_NewObj(interp);
10502
+ refObjPtr->typePtr = &referenceObjType;
10503
+ refObjPtr->bytes = NULL;
10504
+ refObjPtr->internalRep.refValue.id = id;
10505
+ refObjPtr->internalRep.refValue.refPtr = refPtr;
10506
+ interp->referenceNextId++;
10507
+ tag = Jim_GetString(tagPtr, &tagLen);
10508
+ if (tagLen > JIM_REFERENCE_TAGLEN)
10509
+ tagLen = JIM_REFERENCE_TAGLEN;
10510
+ for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10511
+ if (i < tagLen && isrefchar(tag[i]))
10512
+ refPtr->tag[i] = tag[i];
10513
+ else
10514
+ refPtr->tag[i] = '_';
10515
+ }
10516
+ refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0';
10517
+ return refObjPtr;
10518
+}
10519
+
10520
+Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr)
10521
+{
10522
+ if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR)
10523
+ return NULL;
10524
+ return objPtr->internalRep.refValue.refPtr;
10525
+}
10526
+
10527
+int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr)
10528
+{
10529
+ Jim_Reference *refPtr;
10530
+
10531
+ if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10532
+ return JIM_ERR;
10533
+ Jim_IncrRefCount(cmdNamePtr);
10534
+ if (refPtr->finalizerCmdNamePtr)
10535
+ Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10536
+ refPtr->finalizerCmdNamePtr = cmdNamePtr;
10537
+ return JIM_OK;
10538
+}
10539
+
10540
+int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr)
10541
+{
10542
+ Jim_Reference *refPtr;
10543
+
10544
+ if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10545
+ return JIM_ERR;
10546
+ *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr;
10547
+ return JIM_OK;
10548
+}
10549
+
10550
+
10551
+
10552
+static const Jim_HashTableType JimRefMarkHashTableType = {
10553
+ JimReferencesHTHashFunction,
10554
+ JimReferencesHTKeyDup,
10555
+ NULL,
10556
+ JimReferencesHTKeyCompare,
10557
+ JimReferencesHTKeyDestructor,
10558
+ NULL
10559
+};
10560
+
10561
+
10562
+int Jim_Collect(Jim_Interp *interp)
10563
+{
10564
+ int collected = 0;
10565
+ return collected;
10566
+}
10567
+
10568
+#define JIM_COLLECT_ID_PERIOD 5000
10569
+#define JIM_COLLECT_TIME_PERIOD 300
10570
+
10571
+void Jim_CollectIfNeeded(Jim_Interp *interp)
10572
+{
10573
+ unsigned long elapsedId;
10574
+ int elapsedTime;
10575
+
10576
+ elapsedId = interp->referenceNextId - interp->lastCollectId;
10577
+ elapsedTime = time(NULL) - interp->lastCollectTime;
10578
+
10579
+
10580
+ if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) {
10581
+ Jim_Collect(interp);
10582
+ }
10583
+}
10584
+#endif
1038010585
1038110586
int Jim_IsBigEndian(void)
1038210587
{
1038310588
union {
1038410589
unsigned short s;
@@ -10425,11 +10630,11 @@
1042510630
Jim_IncrRefCount(i->nullScriptObj);
1042610631
Jim_IncrRefCount(i->errorProc);
1042710632
Jim_IncrRefCount(i->trueObj);
1042810633
Jim_IncrRefCount(i->falseObj);
1042910634
10430
-
10635
+
1043110636
Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
1043210637
Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
1043310638
1043410639
Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim");
1043510640
Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
@@ -10447,11 +10652,11 @@
1044710652
{
1044810653
Jim_CallFrame *cf, *cfx;
1044910654
1045010655
Jim_Obj *objPtr, *nextObjPtr;
1045110656
10452
-
10657
+
1045310658
for (cf = i->framePtr; cf; cf = cfx) {
1045410659
cfx = cf->parent;
1045510660
JimFreeCallFrame(i, cf, JIM_FCF_FULL);
1045610661
}
1045710662
@@ -10500,27 +10705,27 @@
1050010705
printf("-------------------------------------\n\n");
1050110706
JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
1050210707
}
1050310708
#endif
1050410709
10505
-
10710
+
1050610711
objPtr = i->freeList;
1050710712
while (objPtr) {
1050810713
nextObjPtr = objPtr->nextObjPtr;
1050910714
Jim_Free(objPtr);
1051010715
objPtr = nextObjPtr;
1051110716
}
1051210717
10513
-
10718
+
1051410719
for (cf = i->freeFramesList; cf; cf = cfx) {
1051510720
cfx = cf->next;
1051610721
if (cf->vars.table)
1051710722
Jim_FreeHashTable(&cf->vars);
1051810723
Jim_Free(cf);
1051910724
}
1052010725
10521
-
10726
+
1052210727
Jim_Free(i);
1052310728
}
1052410729
1052510730
Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
1052610731
{
@@ -10541,25 +10746,25 @@
1054110746
else {
1054210747
if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
1054310748
level = -1;
1054410749
}
1054510750
else {
10546
-
10751
+
1054710752
level = interp->framePtr->level - level;
1054810753
}
1054910754
}
1055010755
}
1055110756
else {
10552
- str = "1";
10757
+ str = "1";
1055310758
level = interp->framePtr->level - 1;
1055410759
}
1055510760
1055610761
if (level == 0) {
1055710762
return interp->topFramePtr;
1055810763
}
1055910764
if (level > 0) {
10560
-
10765
+
1056110766
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
1056210767
if (framePtr->level == level) {
1056310768
return framePtr;
1056410769
}
1056510770
}
@@ -10574,19 +10779,19 @@
1057410779
long level;
1057510780
Jim_CallFrame *framePtr;
1057610781
1057710782
if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
1057810783
if (level <= 0) {
10579
-
10784
+
1058010785
level = interp->framePtr->level + level;
1058110786
}
1058210787
1058310788
if (level == 0) {
1058410789
return interp->topFramePtr;
1058510790
}
1058610791
10587
-
10792
+
1058810793
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
1058910794
if (framePtr->level == level) {
1059010795
return framePtr;
1059110796
}
1059210797
}
@@ -10605,11 +10810,11 @@
1060510810
1060610811
static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
1060710812
{
1060810813
int len;
1060910814
10610
-
10815
+
1061110816
Jim_IncrRefCount(stackTraceObj);
1061210817
Jim_DecrRefCount(interp, interp->stackTrace);
1061310818
interp->stackTrace = stackTraceObj;
1061410819
interp->errorFlag = 1;
1061510820
@@ -10626,32 +10831,32 @@
1062610831
{
1062710832
if (strcmp(procname, "unknown") == 0) {
1062810833
procname = "";
1062910834
}
1063010835
if (!*procname && !Jim_Length(fileNameObj)) {
10631
-
10836
+
1063210837
return;
1063310838
}
1063410839
1063510840
if (Jim_IsShared(interp->stackTrace)) {
1063610841
Jim_DecrRefCount(interp, interp->stackTrace);
1063710842
interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
1063810843
Jim_IncrRefCount(interp->stackTrace);
1063910844
}
1064010845
10641
-
10846
+
1064210847
if (!*procname && Jim_Length(fileNameObj)) {
10643
-
10848
+
1064410849
int len = Jim_ListLength(interp, interp->stackTrace);
1064510850
1064610851
if (len >= 3) {
1064710852
Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
1064810853
if (Jim_Length(objPtr)) {
10649
-
10854
+
1065010855
objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
1065110856
if (Jim_Length(objPtr) == 0) {
10652
-
10857
+
1065310858
ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
1065410859
ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
1065510860
return;
1065610861
}
1065710862
}
@@ -10753,18 +10958,18 @@
1075310958
{
1075410959
jim_wide wideValue;
1075510960
const char *str;
1075610961
1075710962
if (objPtr->typePtr == &coercedDoubleObjType) {
10758
-
10963
+
1075910964
objPtr->typePtr = &intObjType;
1076010965
return JIM_OK;
1076110966
}
1076210967
10763
-
10968
+
1076410969
str = Jim_String(objPtr);
10765
-
10970
+
1076610971
if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
1076710972
if (flags & JIM_ERRMSG) {
1076810973
Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
1076910974
}
1077010975
return JIM_ERR;
@@ -10771,11 +10976,11 @@
1077110976
}
1077210977
if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
1077310978
Jim_SetResultString(interp, "Integer value too big to be represented", -1);
1077410979
return JIM_ERR;
1077510980
}
10776
-
10981
+
1077710982
Jim_FreeIntRep(interp, objPtr);
1077810983
objPtr->typePtr = &intObjType;
1077910984
objPtr->internalRep.wideValue = wideValue;
1078010985
return JIM_OK;
1078110986
}
@@ -10870,17 +11075,17 @@
1087011075
{
1087111076
char buf[JIM_DOUBLE_SPACE + 1];
1087211077
int i;
1087311078
int len = sprintf(buf, "%.12g", value);
1087411079
10875
-
11080
+
1087611081
for (i = 0; i < len; i++) {
1087711082
if (buf[i] == '.' || buf[i] == 'e') {
1087811083
#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
1087911084
char *e = strchr(buf, 'e');
1088011085
if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
10881
-
11086
+
1088211087
e += 2;
1088311088
memmove(e, e + 1, len - (e - buf));
1088411089
}
1088511090
#endif
1088611091
break;
@@ -10902,38 +11107,38 @@
1090211107
const char *str;
1090311108
1090411109
str = Jim_String(objPtr);
1090511110
1090611111
#ifdef HAVE_LONG_LONG
10907
-
11112
+
1090811113
#define MIN_INT_IN_DOUBLE -(1LL << 53)
1090911114
#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
1091011115
1091111116
if (objPtr->typePtr == &intObjType
1091211117
&& JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
1091311118
&& JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
1091411119
10915
-
11120
+
1091611121
objPtr->typePtr = &coercedDoubleObjType;
1091711122
return JIM_OK;
1091811123
}
1091911124
else
1092011125
#endif
1092111126
if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
10922
-
11127
+
1092311128
Jim_FreeIntRep(interp, objPtr);
1092411129
objPtr->typePtr = &coercedDoubleObjType;
1092511130
objPtr->internalRep.wideValue = wideValue;
1092611131
return JIM_OK;
1092711132
}
1092811133
else {
10929
-
11134
+
1093011135
if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
1093111136
Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
1093211137
return JIM_ERR;
1093311138
}
10934
-
11139
+
1093511140
Jim_FreeIntRep(interp, objPtr);
1093611141
}
1093711142
objPtr->typePtr = &doubleObjType;
1093811143
objPtr->internalRep.doubleValue = doubleValue;
1093911144
return JIM_OK;
@@ -10966,50 +11171,10 @@
1096611171
objPtr->bytes = NULL;
1096711172
objPtr->internalRep.doubleValue = doubleValue;
1096811173
return objPtr;
1096911174
}
1097011175
10971
-static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags);
10972
-
10973
-int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr)
10974
-{
10975
- if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR)
10976
- return JIM_ERR;
10977
- *booleanPtr = (int) JimWideValue(objPtr);
10978
- return JIM_OK;
10979
-}
10980
-
10981
-static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
10982
-{
10983
- static const char * const falses[] = {
10984
- "0", "false", "no", "off", NULL
10985
- };
10986
- static const char * const trues[] = {
10987
- "1", "true", "yes", "on", NULL
10988
- };
10989
-
10990
- int boolean;
10991
-
10992
- int index;
10993
- if (Jim_GetEnum(interp, objPtr, falses, &index, NULL, 0) == JIM_OK) {
10994
- boolean = 0;
10995
- } else if (Jim_GetEnum(interp, objPtr, trues, &index, NULL, 0) == JIM_OK) {
10996
- boolean = 1;
10997
- } else {
10998
- if (flags & JIM_ERRMSG) {
10999
- Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr);
11000
- }
11001
- return JIM_ERR;
11002
- }
11003
-
11004
-
11005
- Jim_FreeIntRep(interp, objPtr);
11006
- objPtr->typePtr = &intObjType;
11007
- objPtr->internalRep.wideValue = boolean;
11008
- return JIM_OK;
11009
-}
11010
-
1101111176
static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
1101211177
static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
1101311178
static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
1101411179
static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
1101511180
static void UpdateStringOfList(struct Jim_Obj *objPtr);
@@ -11056,11 +11221,11 @@
1105611221
#define JIM_ELESTR_QUOTE 2
1105711222
static unsigned char ListElementQuotingType(const char *s, int len)
1105811223
{
1105911224
int i, level, blevel, trySimple = 1;
1106011225
11061
-
11226
+
1106211227
if (len == 0)
1106311228
return JIM_ELESTR_BRACE;
1106411229
if (s[0] == '"' || s[0] == '{') {
1106511230
trySimple = 0;
1106611231
goto testbrace;
@@ -11078,20 +11243,20 @@
1107811243
case '\n':
1107911244
case '\t':
1108011245
case '\f':
1108111246
case '\v':
1108211247
trySimple = 0;
11083
-
11248
+
1108411249
case '{':
1108511250
case '}':
1108611251
goto testbrace;
1108711252
}
1108811253
}
1108911254
return JIM_ELESTR_SIMPLE;
1109011255
1109111256
testbrace:
11092
-
11257
+
1109311258
if (s[len - 1] == '\\')
1109411259
return JIM_ELESTR_QUOTE;
1109511260
level = 0;
1109611261
blevel = 0;
1109711262
for (i = 0; i < len; i++) {
@@ -11207,11 +11372,11 @@
1120711372
int i, bufLen, realLength;
1120811373
const char *strRep;
1120911374
char *p;
1121011375
unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
1121111376
11212
-
11377
+
1121311378
if (objc > STATIC_QUOTING_LEN) {
1121411379
quotingType = Jim_Alloc(objc);
1121511380
}
1121611381
else {
1121711382
quotingType = staticQuoting;
@@ -11226,25 +11391,25 @@
1122611391
case JIM_ELESTR_SIMPLE:
1122711392
if (i != 0 || strRep[0] != '#') {
1122811393
bufLen += len;
1122911394
break;
1123011395
}
11231
-
11396
+
1123211397
quotingType[i] = JIM_ELESTR_BRACE;
11233
-
11398
+
1123411399
case JIM_ELESTR_BRACE:
1123511400
bufLen += len + 2;
1123611401
break;
1123711402
case JIM_ELESTR_QUOTE:
1123811403
bufLen += len * 2;
1123911404
break;
1124011405
}
11241
- bufLen++;
11406
+ bufLen++;
1124211407
}
1124311408
bufLen++;
1124411409
11245
-
11410
+
1124611411
p = objPtr->bytes = Jim_Alloc(bufLen + 1);
1124711412
realLength = 0;
1124811413
for (i = 0; i < objc; i++) {
1124911414
int len, qlen;
1125011415
@@ -11271,17 +11436,17 @@
1127111436
qlen = BackslashQuoteString(strRep, len, p);
1127211437
p += qlen;
1127311438
realLength += qlen;
1127411439
break;
1127511440
}
11276
-
11441
+
1127711442
if (i + 1 != objc) {
1127811443
*p++ = ' ';
1127911444
realLength++;
1128011445
}
1128111446
}
11282
- *p = '\0';
11447
+ *p = '\0';
1128311448
objPtr->length = realLength;
1128411449
1128511450
if (quotingType != staticQuoting) {
1128611451
Jim_Free(quotingType);
1128711452
}
@@ -11312,21 +11477,21 @@
1131211477
listObjPtrPtr = JimDictPairs(objPtr, &len);
1131311478
for (i = 0; i < len; i++) {
1131411479
Jim_IncrRefCount(listObjPtrPtr[i]);
1131511480
}
1131611481
11317
-
11482
+
1131811483
Jim_FreeIntRep(interp, objPtr);
1131911484
objPtr->typePtr = &listObjType;
1132011485
objPtr->internalRep.listValue.len = len;
1132111486
objPtr->internalRep.listValue.maxLen = len;
1132211487
objPtr->internalRep.listValue.ele = listObjPtrPtr;
1132311488
1132411489
return JIM_OK;
1132511490
}
1132611491
11327
-
11492
+
1132811493
if (objPtr->typePtr == &sourceObjType) {
1132911494
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
1133011495
linenr = objPtr->internalRep.sourceValue.lineNumber;
1133111496
}
1133211497
else {
@@ -11333,20 +11498,20 @@
1133311498
fileNameObj = interp->emptyObj;
1133411499
linenr = 1;
1133511500
}
1133611501
Jim_IncrRefCount(fileNameObj);
1133711502
11338
-
11503
+
1133911504
str = Jim_GetString(objPtr, &strLen);
1134011505
1134111506
Jim_FreeIntRep(interp, objPtr);
1134211507
objPtr->typePtr = &listObjType;
1134311508
objPtr->internalRep.listValue.len = 0;
1134411509
objPtr->internalRep.listValue.maxLen = 0;
1134511510
objPtr->internalRep.listValue.ele = NULL;
1134611511
11347
-
11512
+
1134811513
if (strLen) {
1134911514
JimParserInit(&parser, str, strLen, linenr);
1135011515
while (!parser.eof) {
1135111516
Jim_Obj *elementPtr;
1135211517
@@ -11476,11 +11641,11 @@
1147611641
Jim_Obj *compare_script;
1147711642
int rc;
1147811643
1147911644
jim_wide ret = 0;
1148011645
11481
-
11646
+
1148211647
compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
1148311648
Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
1148411649
Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
1148511650
1148611651
rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11498,23 +11663,23 @@
1149811663
int dst = 0;
1149911664
Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
1150011665
1150111666
for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
1150211667
if (comp(&ele[dst], &ele[src]) == 0) {
11503
-
11668
+
1150411669
Jim_DecrRefCount(sort_info->interp, ele[dst]);
1150511670
}
1150611671
else {
11507
-
11672
+
1150811673
dst++;
1150911674
}
1151011675
ele[dst] = ele[src];
1151111676
}
11512
-
11677
+
1151311678
ele[++dst] = ele[src];
1151411679
11515
-
11680
+
1151611681
listObjPtr->internalRep.listValue.len = dst;
1151711682
}
1151811683
1151911684
1152011685
static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11528,11 +11693,11 @@
1152811693
int rc;
1152911694
1153011695
JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
1153111696
SetListFromAny(interp, listObjPtr);
1153211697
11533
-
11698
+
1153411699
prev_info = sort_info;
1153511700
sort_info = info;
1153611701
1153711702
vector = listObjPtr->internalRep.listValue.ele;
1153811703
len = listObjPtr->internalRep.listValue.len;
@@ -11551,17 +11716,17 @@
1155111716
break;
1155211717
case JIM_LSORT_COMMAND:
1155311718
fn = ListSortCommand;
1155411719
break;
1155511720
default:
11556
- fn = NULL;
11721
+ fn = NULL;
1155711722
JimPanic((1, "ListSort called with invalid sort type"));
11558
- return -1;
11723
+ return -1;
1155911724
}
1156011725
1156111726
if (info->indexed) {
11562
-
11727
+
1156311728
info->subfn = fn;
1156411729
fn = ListSortIndexHelper;
1156511730
}
1156611731
1156711732
if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11585,11 +11750,11 @@
1158511750
int i;
1158611751
Jim_Obj **point;
1158711752
1158811753
if (requiredLen > listPtr->internalRep.listValue.maxLen) {
1158911754
if (requiredLen < 2) {
11590
-
11755
+
1159111756
requiredLen = 4;
1159211757
}
1159311758
else {
1159411759
requiredLen *= 2;
1159511760
}
@@ -11771,34 +11936,34 @@
1177111936
for (i = 0; i < objc; i++)
1177211937
ListAppendList(objPtr, objv[i]);
1177311938
return objPtr;
1177411939
}
1177511940
else {
11776
-
11941
+
1177711942
int len = 0, objLen;
1177811943
char *bytes, *p;
1177911944
11780
-
11945
+
1178111946
for (i = 0; i < objc; i++) {
1178211947
len += Jim_Length(objv[i]);
1178311948
}
1178411949
if (objc)
1178511950
len += objc - 1;
11786
-
11951
+
1178711952
p = bytes = Jim_Alloc(len + 1);
1178811953
for (i = 0; i < objc; i++) {
1178911954
const char *s = Jim_GetString(objv[i], &objLen);
1179011955
11791
-
11956
+
1179211957
while (objLen && isspace(UCHAR(*s))) {
1179311958
s++;
1179411959
objLen--;
1179511960
len--;
1179611961
}
11797
-
11962
+
1179811963
while (objLen && isspace(UCHAR(s[objLen - 1]))) {
11799
-
11964
+
1180011965
if (objLen > 1 && s[objLen - 2] == '\\') {
1180111966
break;
1180211967
}
1180311968
objLen--;
1180411969
len--;
@@ -11825,11 +11990,11 @@
1182511990
int len, rangeLen;
1182611991
1182711992
if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
1182811993
Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
1182911994
return NULL;
11830
- len = Jim_ListLength(interp, listObjPtr);
11995
+ len = Jim_ListLength(interp, listObjPtr);
1183111996
first = JimRelToAbsIndex(len, first);
1183211997
last = JimRelToAbsIndex(len, last);
1183311998
JimRelToAbsRange(len, &first, &last, &rangeLen);
1183411999
if (first == 0 && last == len) {
1183512000
return listObjPtr;
@@ -11865,16 +12030,16 @@
1186512030
{
1186612031
Jim_DecrRefCount(interp, (Jim_Obj *)val);
1186712032
}
1186812033
1186912034
static const Jim_HashTableType JimDictHashTableType = {
11870
- JimObjectHTHashFunction,
11871
- JimObjectHTKeyValDup,
11872
- JimObjectHTKeyValDup,
11873
- JimObjectHTKeyCompare,
11874
- JimObjectHTKeyValDestructor,
11875
- JimObjectHTKeyValDestructor
12035
+ JimObjectHTHashFunction,
12036
+ JimObjectHTKeyValDup,
12037
+ JimObjectHTKeyValDup,
12038
+ JimObjectHTKeyCompare,
12039
+ JimObjectHTKeyValDestructor,
12040
+ JimObjectHTKeyValDestructor
1187612041
};
1187712042
1187812043
static const Jim_ObjType dictObjType = {
1187912044
"dict",
1188012045
FreeDictInternalRep,
@@ -11895,17 +12060,17 @@
1189512060
{
1189612061
Jim_HashTable *ht, *dupHt;
1189712062
Jim_HashTableIterator htiter;
1189812063
Jim_HashEntry *he;
1189912064
11900
-
12065
+
1190112066
ht = srcPtr->internalRep.ptr;
1190212067
dupHt = Jim_Alloc(sizeof(*dupHt));
1190312068
Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
1190412069
if (ht->size != 0)
1190512070
Jim_ExpandHashTable(dupHt, ht->size);
11906
-
12071
+
1190712072
JimInitHashTableIterator(ht, &htiter);
1190812073
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1190912074
Jim_AddHashEntry(dupHt, he->key, he->u.val);
1191012075
}
1191112076
@@ -11921,11 +12086,11 @@
1192112086
Jim_Obj **objv;
1192212087
int i;
1192312088
1192412089
ht = dictPtr->internalRep.ptr;
1192512090
11926
-
12091
+
1192712092
objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
1192812093
JimInitHashTableIterator(ht, &htiter);
1192912094
i = 0;
1193012095
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1193112096
objv[i++] = Jim_GetHashEntryKey(he);
@@ -11935,15 +12100,15 @@
1193512100
return objv;
1193612101
}
1193712102
1193812103
static void UpdateStringOfDict(struct Jim_Obj *objPtr)
1193912104
{
11940
-
12105
+
1194112106
int len;
1194212107
Jim_Obj **objv = JimDictPairs(objPtr, &len);
1194312108
11944
-
12109
+
1194512110
JimMakeListStringRep(objPtr, objv, len);
1194612111
1194712112
Jim_Free(objv);
1194812113
}
1194912114
@@ -11957,18 +12122,18 @@
1195712122
1195812123
if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
1195912124
Jim_String(objPtr);
1196012125
}
1196112126
11962
-
12127
+
1196312128
listlen = Jim_ListLength(interp, objPtr);
1196412129
if (listlen % 2) {
1196512130
Jim_SetResultString(interp, "missing value to go with key", -1);
1196612131
return JIM_ERR;
1196712132
}
1196812133
else {
11969
-
12134
+
1197012135
Jim_HashTable *ht;
1197112136
int i;
1197212137
1197312138
ht = Jim_Alloc(sizeof(*ht));
1197412139
Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -11993,11 +12158,11 @@
1199312158
static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
1199412159
Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
1199512160
{
1199612161
Jim_HashTable *ht = objPtr->internalRep.ptr;
1199712162
11998
- if (valueObjPtr == NULL) {
12163
+ if (valueObjPtr == NULL) {
1199912164
return Jim_DeleteHashEntry(ht, keyObjPtr);
1200012165
}
1200112166
Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
1200212167
return JIM_OK;
1200312168
}
@@ -12093,11 +12258,11 @@
1209312258
int shared, i;
1209412259
1209512260
varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
1209612261
if (objPtr == NULL) {
1209712262
if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
12098
-
12263
+
1209912264
return JIM_ERR;
1210012265
}
1210112266
varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
1210212267
if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
1210312268
Jim_FreeNewObj(interp, varObjPtr);
@@ -12107,26 +12272,26 @@
1210712272
if ((shared = Jim_IsShared(objPtr)))
1210812273
varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
1210912274
for (i = 0; i < keyc; i++) {
1211012275
dictObjPtr = objPtr;
1211112276
12112
-
12277
+
1211312278
if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
1211412279
goto err;
1211512280
}
1211612281
1211712282
if (i == keyc - 1) {
12118
-
12283
+
1211912284
if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
1212012285
if (newObjPtr || (flags & JIM_MUSTEXIST)) {
1212112286
goto err;
1212212287
}
1212312288
}
1212412289
break;
1212512290
}
1212612291
12127
-
12292
+
1212812293
Jim_InvalidateStringRep(dictObjPtr);
1212912294
if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
1213012295
newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
1213112296
if (Jim_IsShared(objPtr)) {
1213212297
objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12139,11 +12304,11 @@
1213912304
}
1214012305
objPtr = Jim_NewDictObj(interp, NULL, 0);
1214112306
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
1214212307
}
1214312308
}
12144
-
12309
+
1214512310
Jim_InvalidateStringRep(objPtr);
1214612311
Jim_InvalidateStringRep(varObjPtr);
1214712312
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
1214812313
goto err;
1214912314
}
@@ -12176,11 +12341,11 @@
1217612341
char buf[JIM_INTEGER_SPACE + 1];
1217712342
if (objPtr->internalRep.intValue >= 0) {
1217812343
sprintf(buf, "%d", objPtr->internalRep.intValue);
1217912344
}
1218012345
else {
12181
-
12346
+
1218212347
sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
1218312348
}
1218412349
JimSetStringBytes(objPtr, buf);
1218512350
}
1218612351
}
@@ -12189,14 +12354,14 @@
1218912354
{
1219012355
int idx, end = 0;
1219112356
const char *str;
1219212357
char *endptr;
1219312358
12194
-
12359
+
1219512360
str = Jim_String(objPtr);
1219612361
12197
-
12362
+
1219812363
if (strncmp(str, "end", 3) == 0) {
1219912364
end = 1;
1220012365
str += 3;
1220112366
idx = 0;
1220212367
}
@@ -12207,21 +12372,21 @@
1220712372
goto badindex;
1220812373
}
1220912374
str = endptr;
1221012375
}
1221112376
12212
-
12377
+
1221312378
if (*str == '+' || *str == '-') {
1221412379
int sign = (*str == '+' ? 1 : -1);
1221512380
1221612381
idx += sign * jim_strtol(++str, &endptr);
1221712382
if (str == endptr || *endptr) {
1221812383
goto badindex;
1221912384
}
1222012385
str = endptr;
1222112386
}
12222
-
12387
+
1222312388
while (isspace(UCHAR(*str))) {
1222412389
str++;
1222512390
}
1222612391
if (*str) {
1222712392
goto badindex;
@@ -12229,19 +12394,19 @@
1222912394
if (end) {
1223012395
if (idx > 0) {
1223112396
idx = INT_MAX;
1223212397
}
1223312398
else {
12234
-
12399
+
1223512400
idx--;
1223612401
}
1223712402
}
1223812403
else if (idx < 0) {
1223912404
idx = -INT_MAX;
1224012405
}
1224112406
12242
-
12407
+
1224312408
Jim_FreeIntRep(interp, objPtr);
1224412409
objPtr->typePtr = &indexObjType;
1224512410
objPtr->internalRep.intValue = idx;
1224612411
return JIM_OK;
1224712412
@@ -12251,11 +12416,11 @@
1225112416
return JIM_ERR;
1225212417
}
1225312418
1225412419
int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
1225512420
{
12256
-
12421
+
1225712422
if (objPtr->typePtr == &intObjType) {
1225812423
jim_wide val = JimWideValue(objPtr);
1225912424
1226012425
if (val < 0)
1226112426
*indexPtr = -INT_MAX;
@@ -12308,18 +12473,18 @@
1230812473
static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
1230912474
{
1231012475
int returnCode;
1231112476
jim_wide wideValue;
1231212477
12313
-
12478
+
1231412479
if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
1231512480
returnCode = (int)wideValue;
1231612481
else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
1231712482
Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
1231812483
return JIM_ERR;
1231912484
}
12320
-
12485
+
1232112486
Jim_FreeIntRep(interp, objPtr);
1232212487
objPtr->typePtr = &returnCodeObjType;
1232312488
objPtr->internalRep.intValue = returnCode;
1232412489
return JIM_OK;
1232512490
}
@@ -12333,20 +12498,19 @@
1233312498
}
1233412499
1233512500
static int JimParseExprOperator(struct JimParserCtx *pc);
1233612501
static int JimParseExprNumber(struct JimParserCtx *pc);
1233712502
static int JimParseExprIrrational(struct JimParserCtx *pc);
12338
-static int JimParseExprBoolean(struct JimParserCtx *pc);
1233912503
1234012504
1234112505
1234212506
1234312507
enum
1234412508
{
12345
-
12346
-
12347
- JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
12509
+
12510
+
12511
+ JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
1234812512
JIM_EXPROP_DIV,
1234912513
JIM_EXPROP_MOD,
1235012514
JIM_EXPROP_SUB,
1235112515
JIM_EXPROP_ADD,
1235212516
JIM_EXPROP_LSHIFT,
@@ -12357,67 +12521,66 @@
1235712521
JIM_EXPROP_GT,
1235812522
JIM_EXPROP_LTE,
1235912523
JIM_EXPROP_GTE,
1236012524
JIM_EXPROP_NUMEQ,
1236112525
JIM_EXPROP_NUMNE,
12362
- JIM_EXPROP_BITAND,
12526
+ JIM_EXPROP_BITAND,
1236312527
JIM_EXPROP_BITXOR,
1236412528
JIM_EXPROP_BITOR,
1236512529
12366
-
12367
- JIM_EXPROP_LOGICAND,
12530
+
12531
+ JIM_EXPROP_LOGICAND,
1236812532
JIM_EXPROP_LOGICAND_LEFT,
1236912533
JIM_EXPROP_LOGICAND_RIGHT,
1237012534
12371
-
12372
- JIM_EXPROP_LOGICOR,
12535
+
12536
+ JIM_EXPROP_LOGICOR,
1237312537
JIM_EXPROP_LOGICOR_LEFT,
1237412538
JIM_EXPROP_LOGICOR_RIGHT,
1237512539
12376
-
12377
-
12378
- JIM_EXPROP_TERNARY,
12540
+
12541
+
12542
+ JIM_EXPROP_TERNARY,
1237912543
JIM_EXPROP_TERNARY_LEFT,
1238012544
JIM_EXPROP_TERNARY_RIGHT,
1238112545
12382
-
12383
- JIM_EXPROP_COLON,
12546
+
12547
+ JIM_EXPROP_COLON,
1238412548
JIM_EXPROP_COLON_LEFT,
1238512549
JIM_EXPROP_COLON_RIGHT,
1238612550
12387
- JIM_EXPROP_POW,
12551
+ JIM_EXPROP_POW,
1238812552
1238912553
12390
- JIM_EXPROP_STREQ,
12554
+ JIM_EXPROP_STREQ,
1239112555
JIM_EXPROP_STRNE,
1239212556
JIM_EXPROP_STRIN,
1239312557
JIM_EXPROP_STRNI,
1239412558
1239512559
12396
- JIM_EXPROP_NOT,
12560
+ JIM_EXPROP_NOT,
1239712561
JIM_EXPROP_BITNOT,
1239812562
JIM_EXPROP_UNARYMINUS,
1239912563
JIM_EXPROP_UNARYPLUS,
1240012564
12401
-
12402
- JIM_EXPROP_FUNC_FIRST,
12565
+
12566
+ JIM_EXPROP_FUNC_FIRST,
1240312567
JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
1240412568
JIM_EXPROP_FUNC_WIDE,
1240512569
JIM_EXPROP_FUNC_ABS,
1240612570
JIM_EXPROP_FUNC_DOUBLE,
1240712571
JIM_EXPROP_FUNC_ROUND,
1240812572
JIM_EXPROP_FUNC_RAND,
1240912573
JIM_EXPROP_FUNC_SRAND,
1241012574
12411
-
12412
- JIM_EXPROP_FUNC_SIN,
12575
+
12576
+ JIM_EXPROP_FUNC_SIN,
1241312577
JIM_EXPROP_FUNC_COS,
1241412578
JIM_EXPROP_FUNC_TAN,
1241512579
JIM_EXPROP_FUNC_ASIN,
1241612580
JIM_EXPROP_FUNC_ACOS,
1241712581
JIM_EXPROP_FUNC_ATAN,
12418
- JIM_EXPROP_FUNC_ATAN2,
1241912582
JIM_EXPROP_FUNC_SINH,
1242012583
JIM_EXPROP_FUNC_COSH,
1242112584
JIM_EXPROP_FUNC_TANH,
1242212585
JIM_EXPROP_FUNC_CEIL,
1242312586
JIM_EXPROP_FUNC_FLOOR,
@@ -12424,12 +12587,10 @@
1242412587
JIM_EXPROP_FUNC_EXP,
1242512588
JIM_EXPROP_FUNC_LOG,
1242612589
JIM_EXPROP_FUNC_LOG10,
1242712590
JIM_EXPROP_FUNC_SQRT,
1242812591
JIM_EXPROP_FUNC_POW,
12429
- JIM_EXPROP_FUNC_HYPOT,
12430
- JIM_EXPROP_FUNC_FMOD,
1243112592
};
1243212593
1243312594
struct JimExprState
1243412595
{
1243512596
Jim_Obj **stack;
@@ -12506,15 +12667,11 @@
1250612667
case JIM_EXPROP_UNARYPLUS:
1250712668
dC = dA;
1250812669
intresult = 0;
1250912670
break;
1251012671
case JIM_EXPROP_FUNC_ABS:
12511
-#ifdef JIM_MATH_FUNCTIONS
12512
- dC = fabs(dA);
12513
-#else
1251412672
dC = dA >= 0 ? dA : -dA;
12515
-#endif
1251612673
intresult = 0;
1251712674
break;
1251812675
case JIM_EXPROP_UNARYMINUS:
1251912676
dC = -dA;
1252012677
intresult = 0;
@@ -12702,16 +12859,16 @@
1270212859
}
1270312860
}
1270412861
break;
1270512862
case JIM_EXPROP_ROTL:
1270612863
case JIM_EXPROP_ROTR:{
12707
-
12864
+
1270812865
unsigned long uA = (unsigned long)wA;
1270912866
unsigned long uB = (unsigned long)wB;
1271012867
const unsigned int S = sizeof(unsigned long) * 8;
1271112868
12712
-
12869
+
1271312870
uB %= S;
1271412871
1271512872
if (e->opcode == JIM_EXPROP_ROTR) {
1271612873
uB = S - uB;
1271712874
}
@@ -12733,10 +12890,11 @@
1273312890
1273412891
1273512892
1273612893
static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
1273712894
{
12895
+ int intresult = 1;
1273812896
int rc = JIM_OK;
1273912897
double dA, dB, dC = 0;
1274012898
jim_wide wA, wB, wC = 0;
1274112899
1274212900
Jim_Obj *B = ExprPop(e);
@@ -12744,36 +12902,30 @@
1274412902
1274512903
if ((A->typePtr != &doubleObjType || A->bytes) &&
1274612904
(B->typePtr != &doubleObjType || B->bytes) &&
1274712905
JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
1274812906
12749
-
12907
+
1275012908
1275112909
switch (e->opcode) {
1275212910
case JIM_EXPROP_POW:
1275312911
case JIM_EXPROP_FUNC_POW:
12754
- if (wA == 0 && wB < 0) {
12755
- Jim_SetResultString(interp, "exponentiation of zero by negative power", -1);
12756
- rc = JIM_ERR;
12757
- goto done;
12758
- }
1275912912
wC = JimPowWide(wA, wB);
12760
- goto intresult;
12913
+ break;
1276112914
case JIM_EXPROP_ADD:
1276212915
wC = wA + wB;
12763
- goto intresult;
12916
+ break;
1276412917
case JIM_EXPROP_SUB:
1276512918
wC = wA - wB;
12766
- goto intresult;
12919
+ break;
1276712920
case JIM_EXPROP_MUL:
1276812921
wC = wA * wB;
12769
- goto intresult;
12922
+ break;
1277012923
case JIM_EXPROP_DIV:
1277112924
if (wB == 0) {
1277212925
Jim_SetResultString(interp, "Division by zero", -1);
1277312926
rc = JIM_ERR;
12774
- goto done;
1277512927
}
1277612928
else {
1277712929
if (wB < 0) {
1277812930
wB = -wB;
1277912931
wA = -wA;
@@ -12780,67 +12932,55 @@
1278012932
}
1278112933
wC = wA / wB;
1278212934
if (wA % wB < 0) {
1278312935
wC--;
1278412936
}
12785
- goto intresult;
12786
- }
12787
- case JIM_EXPROP_LT:
12788
- wC = wA < wB;
12789
- goto intresult;
12790
- case JIM_EXPROP_GT:
12791
- wC = wA > wB;
12792
- goto intresult;
12793
- case JIM_EXPROP_LTE:
12794
- wC = wA <= wB;
12795
- goto intresult;
12796
- case JIM_EXPROP_GTE:
12797
- wC = wA >= wB;
12798
- goto intresult;
12799
- case JIM_EXPROP_NUMEQ:
12800
- wC = wA == wB;
12801
- goto intresult;
12802
- case JIM_EXPROP_NUMNE:
12803
- wC = wA != wB;
12804
- goto intresult;
12805
- }
12806
- }
12807
- if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12808
- switch (e->opcode) {
12809
-#ifndef JIM_MATH_FUNCTIONS
12810
- case JIM_EXPROP_POW:
12811
- case JIM_EXPROP_FUNC_POW:
12812
- case JIM_EXPROP_FUNC_ATAN2:
12813
- case JIM_EXPROP_FUNC_HYPOT:
12814
- case JIM_EXPROP_FUNC_FMOD:
12815
- Jim_SetResultString(interp, "unsupported", -1);
12816
- rc = JIM_ERR;
12817
- goto done;
12818
-#else
12819
- case JIM_EXPROP_POW:
12820
- case JIM_EXPROP_FUNC_POW:
12821
- dC = pow(dA, dB);
12822
- goto doubleresult;
12823
- case JIM_EXPROP_FUNC_ATAN2:
12824
- dC = atan2(dA, dB);
12825
- goto doubleresult;
12826
- case JIM_EXPROP_FUNC_HYPOT:
12827
- dC = hypot(dA, dB);
12828
- goto doubleresult;
12829
- case JIM_EXPROP_FUNC_FMOD:
12830
- dC = fmod(dA, dB);
12831
- goto doubleresult;
12832
-#endif
12833
- case JIM_EXPROP_ADD:
12834
- dC = dA + dB;
12835
- goto doubleresult;
12836
- case JIM_EXPROP_SUB:
12837
- dC = dA - dB;
12838
- goto doubleresult;
12839
- case JIM_EXPROP_MUL:
12840
- dC = dA * dB;
12841
- goto doubleresult;
12937
+ }
12938
+ break;
12939
+ case JIM_EXPROP_LT:
12940
+ wC = wA < wB;
12941
+ break;
12942
+ case JIM_EXPROP_GT:
12943
+ wC = wA > wB;
12944
+ break;
12945
+ case JIM_EXPROP_LTE:
12946
+ wC = wA <= wB;
12947
+ break;
12948
+ case JIM_EXPROP_GTE:
12949
+ wC = wA >= wB;
12950
+ break;
12951
+ case JIM_EXPROP_NUMEQ:
12952
+ wC = wA == wB;
12953
+ break;
12954
+ case JIM_EXPROP_NUMNE:
12955
+ wC = wA != wB;
12956
+ break;
12957
+ default:
12958
+ abort();
12959
+ }
12960
+ }
12961
+ else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12962
+ intresult = 0;
12963
+ switch (e->opcode) {
12964
+ case JIM_EXPROP_POW:
12965
+ case JIM_EXPROP_FUNC_POW:
12966
+#ifdef JIM_MATH_FUNCTIONS
12967
+ dC = pow(dA, dB);
12968
+#else
12969
+ Jim_SetResultString(interp, "unsupported", -1);
12970
+ rc = JIM_ERR;
12971
+#endif
12972
+ break;
12973
+ case JIM_EXPROP_ADD:
12974
+ dC = dA + dB;
12975
+ break;
12976
+ case JIM_EXPROP_SUB:
12977
+ dC = dA - dB;
12978
+ break;
12979
+ case JIM_EXPROP_MUL:
12980
+ dC = dA * dB;
12981
+ break;
1284212982
case JIM_EXPROP_DIV:
1284312983
if (dB == 0) {
1284412984
#ifdef INFINITY
1284512985
dC = dA < 0 ? -INFINITY : INFINITY;
1284612986
#else
@@ -12848,70 +12988,83 @@
1284812988
#endif
1284912989
}
1285012990
else {
1285112991
dC = dA / dB;
1285212992
}
12853
- goto doubleresult;
12993
+ break;
1285412994
case JIM_EXPROP_LT:
1285512995
wC = dA < dB;
12856
- goto intresult;
12996
+ intresult = 1;
12997
+ break;
1285712998
case JIM_EXPROP_GT:
1285812999
wC = dA > dB;
12859
- goto intresult;
13000
+ intresult = 1;
13001
+ break;
1286013002
case JIM_EXPROP_LTE:
1286113003
wC = dA <= dB;
12862
- goto intresult;
13004
+ intresult = 1;
13005
+ break;
1286313006
case JIM_EXPROP_GTE:
1286413007
wC = dA >= dB;
12865
- goto intresult;
13008
+ intresult = 1;
13009
+ break;
1286613010
case JIM_EXPROP_NUMEQ:
1286713011
wC = dA == dB;
12868
- goto intresult;
13012
+ intresult = 1;
13013
+ break;
1286913014
case JIM_EXPROP_NUMNE:
1287013015
wC = dA != dB;
12871
- goto intresult;
13016
+ intresult = 1;
13017
+ break;
13018
+ default:
13019
+ abort();
1287213020
}
1287313021
}
1287413022
else {
13023
+
1287513024
12876
-
12877
-
13025
+
1287813026
int i = Jim_StringCompareObj(interp, A, B, 0);
1287913027
1288013028
switch (e->opcode) {
1288113029
case JIM_EXPROP_LT:
1288213030
wC = i < 0;
12883
- goto intresult;
13031
+ break;
1288413032
case JIM_EXPROP_GT:
1288513033
wC = i > 0;
12886
- goto intresult;
13034
+ break;
1288713035
case JIM_EXPROP_LTE:
1288813036
wC = i <= 0;
12889
- goto intresult;
13037
+ break;
1289013038
case JIM_EXPROP_GTE:
1289113039
wC = i >= 0;
12892
- goto intresult;
13040
+ break;
1289313041
case JIM_EXPROP_NUMEQ:
1289413042
wC = i == 0;
12895
- goto intresult;
13043
+ break;
1289613044
case JIM_EXPROP_NUMNE:
1289713045
wC = i != 0;
12898
- goto intresult;
13046
+ break;
13047
+ default:
13048
+ rc = JIM_ERR;
13049
+ break;
1289913050
}
1290013051
}
1290113052
12902
- rc = JIM_ERR;
12903
-done:
13053
+ if (rc == JIM_OK) {
13054
+ if (intresult) {
13055
+ ExprPush(e, Jim_NewIntObj(interp, wC));
13056
+ }
13057
+ else {
13058
+ ExprPush(e, Jim_NewDoubleObj(interp, dC));
13059
+ }
13060
+ }
13061
+
1290413062
Jim_DecrRefCount(interp, A);
1290513063
Jim_DecrRefCount(interp, B);
13064
+
1290613065
return rc;
12907
-intresult:
12908
- ExprPush(e, Jim_NewIntObj(interp, wC));
12909
- goto done;
12910
-doubleresult:
12911
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
12912
- goto done;
1291313066
}
1291413067
1291513068
static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
1291613069
{
1291713070
int listlen;
@@ -12960,21 +13113,17 @@
1296013113
1296113114
static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
1296213115
{
1296313116
long l;
1296413117
double d;
12965
- int b;
1296613118
1296713119
if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
1296813120
return l != 0;
1296913121
}
1297013122
if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
1297113123
return d != 0;
1297213124
}
12973
- if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
12974
- return b != 0;
12975
- }
1297613125
return -1;
1297713126
}
1297813127
1297913128
static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
1298013129
{
@@ -12982,21 +13131,21 @@
1298213131
Jim_Obj *A = ExprPop(e);
1298313132
int rc = JIM_OK;
1298413133
1298513134
switch (ExprBool(interp, A)) {
1298613135
case 0:
12987
-
13136
+
1298813137
e->skip = JimWideValue(skip);
1298913138
ExprPush(e, Jim_NewIntObj(interp, 0));
1299013139
break;
1299113140
1299213141
case 1:
12993
-
13142
+
1299413143
break;
1299513144
1299613145
case -1:
12997
-
13146
+
1299813147
rc = JIM_ERR;
1299913148
}
1300013149
Jim_DecrRefCount(interp, A);
1300113150
Jim_DecrRefCount(interp, skip);
1300213151
@@ -13009,21 +13158,21 @@
1300913158
Jim_Obj *A = ExprPop(e);
1301013159
int rc = JIM_OK;
1301113160
1301213161
switch (ExprBool(interp, A)) {
1301313162
case 0:
13014
-
13163
+
1301513164
break;
1301613165
1301713166
case 1:
13018
-
13167
+
1301913168
e->skip = JimWideValue(skip);
1302013169
ExprPush(e, Jim_NewIntObj(interp, 1));
1302113170
break;
1302213171
1302313172
case -1:
13024
-
13173
+
1302513174
rc = JIM_ERR;
1302613175
break;
1302713176
}
1302813177
Jim_DecrRefCount(interp, A);
1302913178
Jim_DecrRefCount(interp, skip);
@@ -13044,11 +13193,11 @@
1304413193
case 1:
1304513194
ExprPush(e, Jim_NewIntObj(interp, 1));
1304613195
break;
1304713196
1304813197
case -1:
13049
-
13198
+
1305013199
rc = JIM_ERR;
1305113200
break;
1305213201
}
1305313202
Jim_DecrRefCount(interp, A);
1305413203
@@ -13059,27 +13208,27 @@
1305913208
{
1306013209
Jim_Obj *skip = ExprPop(e);
1306113210
Jim_Obj *A = ExprPop(e);
1306213211
int rc = JIM_OK;
1306313212
13064
-
13213
+
1306513214
ExprPush(e, A);
1306613215
1306713216
switch (ExprBool(interp, A)) {
1306813217
case 0:
13069
-
13218
+
1307013219
e->skip = JimWideValue(skip);
13071
-
13220
+
1307213221
ExprPush(e, Jim_NewIntObj(interp, 0));
1307313222
break;
1307413223
1307513224
case 1:
13076
-
13225
+
1307713226
break;
1307813227
1307913228
case -1:
13080
-
13229
+
1308113230
rc = JIM_ERR;
1308213231
break;
1308313232
}
1308413233
Jim_DecrRefCount(interp, A);
1308513234
Jim_DecrRefCount(interp, skip);
@@ -13091,15 +13240,15 @@
1309113240
{
1309213241
Jim_Obj *skip = ExprPop(e);
1309313242
Jim_Obj *B = ExprPop(e);
1309413243
Jim_Obj *A = ExprPop(e);
1309513244
13096
-
13245
+
1309713246
if (ExprBool(interp, A)) {
13098
-
13247
+
1309913248
e->skip = JimWideValue(skip);
13100
-
13249
+
1310113250
ExprPush(e, B);
1310213251
}
1310313252
1310413253
Jim_DecrRefCount(interp, skip);
1310513254
Jim_DecrRefCount(interp, A);
@@ -13115,16 +13264,15 @@
1311513264
enum
1311613265
{
1311713266
LAZY_NONE,
1311813267
LAZY_OP,
1311913268
LAZY_LEFT,
13120
- LAZY_RIGHT,
13121
- RIGHT_ASSOC,
13269
+ LAZY_RIGHT
1312213270
};
1312313271
13124
-#define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1}
13125
-#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, LAZY_NONE)
13272
+#define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1}
13273
+#define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1}
1312613274
1312713275
static const struct Jim_ExprOperator Jim_ExprOperators[] = {
1312813276
OPRINIT("*", 110, 2, JimExprOpBin),
1312913277
OPRINIT("/", 110, 2, JimExprOpBin),
1313013278
OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13148,28 +13296,27 @@
1314813296
1314913297
OPRINIT("&", 50, 2, JimExprOpIntBin),
1315013298
OPRINIT("^", 49, 2, JimExprOpIntBin),
1315113299
OPRINIT("|", 48, 2, JimExprOpIntBin),
1315213300
13153
- OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP),
13154
- OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13155
- OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13156
-
13157
- OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP),
13158
- OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13159
- OPRINIT_ATTR(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13160
-
13161
- OPRINIT_ATTR("?", 5, 2, JimExprOpNull, LAZY_OP),
13162
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13163
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13164
-
13165
- OPRINIT_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP),
13166
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13167
- OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13168
-
13169
-
13170
- OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC),
13301
+ OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP),
13302
+ OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13303
+ OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13304
+
13305
+ OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP),
13306
+ OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13307
+ OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13308
+
13309
+ OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP),
13310
+ OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13311
+ OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13312
+
13313
+ OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP),
13314
+ OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13315
+ OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13316
+
13317
+ OPRINIT("**", 250, 2, JimExprOpBin),
1317113318
1317213319
OPRINIT("eq", 60, 2, JimExprOpStrBin),
1317313320
OPRINIT("ne", 60, 2, JimExprOpStrBin),
1317413321
1317513322
OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13195,11 +13342,10 @@
1319513342
OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
1319613343
OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
1319713344
OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
1319813345
OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
1319913346
OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
13200
- OPRINIT("atan2", 200, 2, JimExprOpBin),
1320113347
OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
1320213348
OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
1320313349
OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
1320413350
OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
1320513351
OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13206,12 +13352,10 @@
1320613352
OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
1320713353
OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
1320813354
OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
1320913355
OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
1321013356
OPRINIT("pow", 200, 2, JimExprOpBin),
13211
- OPRINIT("hypot", 200, 2, JimExprOpBin),
13212
- OPRINIT("fmod", 200, 2, JimExprOpBin),
1321313357
#endif
1321413358
};
1321513359
#undef OPRINIT
1321613360
#undef OPRINIT_LAZY
1321713361
@@ -13218,20 +13362,20 @@
1321813362
#define JIM_EXPR_OPERATORS_NUM \
1321913363
(sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
1322013364
1322113365
static int JimParseExpression(struct JimParserCtx *pc)
1322213366
{
13223
-
13367
+
1322413368
while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
1322513369
if (*pc->p == '\n') {
1322613370
pc->linenr++;
1322713371
}
1322813372
pc->p++;
1322913373
pc->len--;
1323013374
}
1323113375
13232
-
13376
+
1323313377
pc->tline = pc->linenr;
1323413378
pc->tstart = pc->p;
1323513379
1323613380
if (pc->len == 0) {
1323713381
pc->tend = pc->p;
@@ -13257,11 +13401,11 @@
1325713401
return JimParseCmd(pc);
1325813402
case '$':
1325913403
if (JimParseVar(pc) == JIM_ERR)
1326013404
return JimParseExprOperator(pc);
1326113405
else {
13262
-
13406
+
1326313407
if (pc->tt == JIM_TT_EXPRSUGAR) {
1326413408
return JIM_ERR;
1326513409
}
1326613410
return JIM_OK;
1326713411
}
@@ -13286,18 +13430,10 @@
1328613430
case 'N':
1328713431
case 'I':
1328813432
case 'n':
1328913433
case 'i':
1329013434
if (JimParseExprIrrational(pc) == JIM_ERR)
13291
- if (JimParseExprBoolean(pc) == JIM_ERR)
13292
- return JimParseExprOperator(pc);
13293
- break;
13294
- case 't':
13295
- case 'f':
13296
- case 'o':
13297
- case 'y':
13298
- if (JimParseExprBoolean(pc) == JIM_ERR)
1329913435
return JimParseExprOperator(pc);
1330013436
break;
1330113437
default:
1330213438
return JimParseExprOperator(pc);
1330313439
break;
@@ -13307,21 +13443,21 @@
1330713443
1330813444
static int JimParseExprNumber(struct JimParserCtx *pc)
1330913445
{
1331013446
char *end;
1331113447
13312
-
13448
+
1331313449
pc->tt = JIM_TT_EXPR_INT;
1331413450
1331513451
jim_strtoull(pc->p, (char **)&pc->p);
13316
-
13452
+
1331713453
if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
13318
- if (strtod(pc->tstart, &end)) { }
13454
+ if (strtod(pc->tstart, &end)) { }
1331913455
if (end == pc->tstart)
1332013456
return JIM_ERR;
1332113457
if (end > pc->p) {
13322
-
13458
+
1332313459
pc->tt = JIM_TT_EXPR_DOUBLE;
1332413460
pc->p = end;
1332513461
}
1332613462
}
1332713463
pc->tend = pc->p - 1;
@@ -13346,37 +13482,16 @@
1334613482
}
1334713483
}
1334813484
return JIM_ERR;
1334913485
}
1335013486
13351
-static int JimParseExprBoolean(struct JimParserCtx *pc)
13352
-{
13353
- const char *booleans[] = { "false", "no", "off", "true", "yes", "on", NULL };
13354
- const int lengths[] = { 5, 2, 3, 4, 3, 2, 0 };
13355
- int i;
13356
-
13357
- for (i = 0; booleans[i]; i++) {
13358
- const char *boolean = booleans[i];
13359
- int length = lengths[i];
13360
-
13361
- if (strncmp(boolean, pc->p, length) == 0) {
13362
- pc->p += length;
13363
- pc->len -= length;
13364
- pc->tend = pc->p - 1;
13365
- pc->tt = JIM_TT_EXPR_BOOLEAN;
13366
- return JIM_OK;
13367
- }
13368
- }
13369
- return JIM_ERR;
13370
-}
13371
-
1337213487
static int JimParseExprOperator(struct JimParserCtx *pc)
1337313488
{
1337413489
int i;
1337513490
int bestIdx = -1, bestLen = 0;
1337613491
13377
-
13492
+
1337813493
for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
1337913494
const char * const opname = Jim_ExprOperators[i].name;
1338013495
const int oplen = Jim_ExprOperators[i].namelen;
1338113496
1338213497
if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13390,11 +13505,11 @@
1339013505
}
1339113506
if (bestIdx == -1) {
1339213507
return JIM_ERR;
1339313508
}
1339413509
13395
-
13510
+
1339613511
if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
1339713512
const char *p = pc->p + bestLen;
1339813513
int len = pc->len - bestLen;
1339913514
1340013515
while (len && isspace(UCHAR(*p))) {
@@ -13424,20 +13539,14 @@
1342413539
1342513540
const char *jim_tt_name(int type)
1342613541
{
1342713542
static const char * const tt_names[JIM_TT_EXPR_OP] =
1342813543
{ "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
13429
- "DBL", "BOO", "$()" };
13544
+ "DBL", "$()" };
1343013545
if (type < JIM_TT_EXPR_OP) {
1343113546
return tt_names[type];
1343213547
}
13433
- else if (type == JIM_EXPROP_UNARYMINUS) {
13434
- return "-VE";
13435
- }
13436
- else if (type == JIM_EXPROP_UNARYPLUS) {
13437
- return "+VE";
13438
- }
1343913548
else {
1344013549
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
1344113550
static char buf[20];
1344213551
1344313552
if (op->name) {
@@ -13461,13 +13570,13 @@
1346113570
};
1346213571
1346313572
1346413573
typedef struct ExprByteCode
1346513574
{
13466
- ScriptToken *token;
13467
- int len;
13468
- int inUse;
13575
+ ScriptToken *token;
13576
+ int len;
13577
+ int inUse;
1346913578
} ExprByteCode;
1347013579
1347113580
static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
1347213581
{
1347313582
int i;
@@ -13495,29 +13604,26 @@
1349513604
static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
1349613605
{
1349713606
JIM_NOTUSED(interp);
1349813607
JIM_NOTUSED(srcPtr);
1349913608
13500
-
13609
+
1350113610
dupPtr->typePtr = NULL;
1350213611
}
1350313612
13504
-static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr)
13613
+
13614
+static int ExprCheckCorrectness(ExprByteCode * expr)
1350513615
{
1350613616
int i;
1350713617
int stacklen = 0;
1350813618
int ternary = 0;
13509
- int lasttt = JIM_TT_NONE;
13510
- const char *errmsg;
1351113619
1351213620
for (i = 0; i < expr->len; i++) {
1351313621
ScriptToken *t = &expr->token[i];
1351413622
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13515
- lasttt = t->type;
1351613623
1351713624
stacklen -= op->arity;
13518
-
1351913625
if (stacklen < 0) {
1352013626
break;
1352113627
}
1352213628
if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
1352313629
ternary++;
@@ -13524,47 +13630,26 @@
1352413630
}
1352513631
else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
1352613632
ternary--;
1352713633
}
1352813634
13529
-
13635
+
1353013636
stacklen++;
1353113637
}
13532
- if (stacklen == 1 && ternary == 0) {
13533
- return JIM_OK;
13534
- }
13535
-
13536
- if (stacklen <= 0) {
13537
-
13538
- if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
13539
- errmsg = "too few arguments for math function";
13540
- Jim_SetResultString(interp, "too few arguments for math function", -1);
13541
- } else {
13542
- errmsg = "premature end of expression";
13543
- }
13544
- }
13545
- else if (stacklen > 1) {
13546
- if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
13547
- errmsg = "too many arguments for math function";
13548
- } else {
13549
- errmsg = "extra tokens at end of expression";
13550
- }
13551
- }
13552
- else {
13553
- errmsg = "invalid ternary expression";
13554
- }
13555
- Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg);
13556
- return JIM_ERR;
13638
+ if (stacklen != 1 || ternary != 0) {
13639
+ return JIM_ERR;
13640
+ }
13641
+ return JIM_OK;
1355713642
}
1355813643
1355913644
static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
1356013645
{
1356113646
int i;
1356213647
1356313648
int leftindex, arity, offset;
1356413649
13565
-
13650
+
1356613651
leftindex = expr->len - 1;
1356713652
1356813653
arity = 1;
1356913654
while (arity) {
1357013655
ScriptToken *tt = &expr->token[leftindex];
@@ -13577,11 +13662,11 @@
1357713662
return JIM_ERR;
1357813663
}
1357913664
}
1358013665
leftindex++;
1358113666
13582
-
13667
+
1358313668
memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
1358413669
sizeof(*expr->token) * (expr->len - leftindex));
1358513670
expr->len += 2;
1358613671
offset = (expr->len - leftindex) - 1;
1358713672
@@ -13589,16 +13674,16 @@
1358913674
expr->token[leftindex + 1].objPtr = interp->emptyObj;
1359013675
1359113676
expr->token[leftindex].type = JIM_TT_EXPR_INT;
1359213677
expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
1359313678
13594
-
13679
+
1359513680
expr->token[expr->len].objPtr = interp->emptyObj;
1359613681
expr->token[expr->len].type = t->type + 2;
1359713682
expr->len++;
1359813683
13599
-
13684
+
1360013685
for (i = leftindex - 1; i > 0; i--) {
1360113686
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
1360213687
if (op->lazy == LAZY_LEFT) {
1360313688
if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
1360413689
JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13644,11 +13729,11 @@
1364413729
return right_index;
1364513730
}
1364613731
right_index--;
1364713732
}
1364813733
13649
-
13734
+
1365013735
return -1;
1365113736
}
1365213737
1365313738
static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
1365413739
{
@@ -13686,11 +13771,11 @@
1368613771
1368713772
if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
1368813773
continue;
1368913774
}
1369013775
13691
-
13776
+
1369213777
if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
1369313778
continue;
1369413779
}
1369513780
1369613781
tmp = expr->token[prev_right_index];
@@ -13699,25 +13784,25 @@
1369913784
}
1370013785
expr->token[i] = tmp;
1370113786
1370213787
JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
1370313788
13704
-
13789
+
1370513790
i++;
1370613791
}
1370713792
}
1370813793
13709
-static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
13794
+static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj)
1371013795
{
1371113796
Jim_Stack stack;
1371213797
ExprByteCode *expr;
1371313798
int ok = 1;
1371413799
int i;
1371513800
int prevtt = JIM_TT_NONE;
1371613801
int have_ternary = 0;
1371713802
13718
-
13803
+
1371913804
int count = tokenlist->count - 1;
1372013805
1372113806
expr = Jim_Alloc(sizeof(*expr));
1372213807
expr->inUse = 1;
1372313808
expr->len = 0;
@@ -13728,11 +13813,11 @@
1372813813
ParseToken *t = &tokenlist->list[i];
1372913814
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
1373013815
1373113816
if (op->lazy == LAZY_OP) {
1373213817
count += 2;
13733
-
13818
+
1373413819
if (t->type == JIM_EXPROP_TERNARY) {
1373513820
have_ternary = 1;
1373613821
}
1373713822
}
1373813823
}
@@ -13740,128 +13825,128 @@
1374013825
expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
1374113826
1374213827
for (i = 0; i < tokenlist->count && ok; i++) {
1374313828
ParseToken *t = &tokenlist->list[i];
1374413829
13745
-
13830
+
1374613831
struct ScriptToken *token = &expr->token[expr->len];
1374713832
1374813833
if (t->type == JIM_TT_EOL) {
1374913834
break;
1375013835
}
1375113836
13752
- if (TOKEN_IS_EXPR_OP(t->type)) {
13753
- const struct Jim_ExprOperator *op;
13754
- ParseToken *tt;
13755
-
13756
-
13757
- if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) {
13758
- if (t->type == JIM_EXPROP_SUB) {
13759
- t->type = JIM_EXPROP_UNARYMINUS;
13760
- }
13761
- else if (t->type == JIM_EXPROP_ADD) {
13762
- t->type = JIM_EXPROP_UNARYPLUS;
13763
- }
13764
- }
13765
-
13766
- op = JimExprOperatorInfoByOpcode(t->type);
13767
-
13768
-
13769
- while ((tt = Jim_StackPeek(&stack)) != NULL) {
13770
- const struct Jim_ExprOperator *tt_op =
13771
- JimExprOperatorInfoByOpcode(tt->type);
13772
-
13773
-
13774
- if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13775
-
13776
- if (tt_op->precedence == op->precedence && tt_op->lazy == RIGHT_ASSOC) {
13777
- break;
13778
- }
13779
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13780
- ok = 0;
13781
- goto err;
13782
- }
13783
- Jim_StackPop(&stack);
13784
- }
13785
- else {
13786
- break;
13787
- }
13788
- }
13789
- Jim_StackPush(&stack, t);
13790
- }
13791
- else if (t->type == JIM_TT_SUBEXPR_START) {
13792
- Jim_StackPush(&stack, t);
13793
- }
13794
- else if (t->type == JIM_TT_SUBEXPR_END || t->type == JIM_TT_SUBEXPR_COMMA) {
13795
-
13796
- ok = 0;
13797
- while (Jim_StackLen(&stack)) {
13798
- ParseToken *tt = Jim_StackPop(&stack);
13799
-
13800
- if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) {
13801
- if (t->type == JIM_TT_SUBEXPR_COMMA) {
13802
-
13803
- Jim_StackPush(&stack, tt);
13804
- }
13805
- ok = 1;
13806
- break;
13807
- }
13808
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13809
- goto err;
13810
- }
13811
- }
13812
- if (!ok) {
13813
- Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr);
13814
- goto err;
13815
- }
13816
- }
13817
- else {
13818
- Jim_Obj *objPtr = NULL;
13819
-
13820
-
13821
- token->type = t->type;
13822
-
13823
-
13824
- if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) {
13825
- Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr);
13826
- ok = 0;
13827
- goto err;
13828
- }
13829
-
13830
-
13831
- if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) {
13832
- char *endptr;
13833
- if (t->type == JIM_TT_EXPR_INT) {
13834
- objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13835
- }
13836
- else {
13837
- objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13838
- }
13839
- if (endptr != t->token + t->len) {
13840
-
13841
- Jim_FreeNewObj(interp, objPtr);
13842
- objPtr = NULL;
13843
- }
13844
- }
13845
-
13846
- if (objPtr) {
13847
- token->objPtr = objPtr;
13848
- }
13849
- else {
13850
-
13851
- token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13852
- if (t->type == JIM_TT_CMD) {
13853
-
13854
- JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13855
- }
13856
- }
13857
- expr->len++;
13837
+ switch (t->type) {
13838
+ case JIM_TT_STR:
13839
+ case JIM_TT_ESC:
13840
+ case JIM_TT_VAR:
13841
+ case JIM_TT_DICTSUGAR:
13842
+ case JIM_TT_EXPRSUGAR:
13843
+ case JIM_TT_CMD:
13844
+ token->type = t->type;
13845
+strexpr:
13846
+ token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13847
+ if (t->type == JIM_TT_CMD) {
13848
+
13849
+ JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13850
+ }
13851
+ expr->len++;
13852
+ break;
13853
+
13854
+ case JIM_TT_EXPR_INT:
13855
+ case JIM_TT_EXPR_DOUBLE:
13856
+ {
13857
+ char *endptr;
13858
+ if (t->type == JIM_TT_EXPR_INT) {
13859
+ token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13860
+ }
13861
+ else {
13862
+ token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13863
+ }
13864
+ if (endptr != t->token + t->len) {
13865
+
13866
+ Jim_FreeNewObj(interp, token->objPtr);
13867
+ token->type = JIM_TT_STR;
13868
+ goto strexpr;
13869
+ }
13870
+ token->type = t->type;
13871
+ expr->len++;
13872
+ }
13873
+ break;
13874
+
13875
+ case JIM_TT_SUBEXPR_START:
13876
+ Jim_StackPush(&stack, t);
13877
+ prevtt = JIM_TT_NONE;
13878
+ continue;
13879
+
13880
+ case JIM_TT_SUBEXPR_COMMA:
13881
+
13882
+ continue;
13883
+
13884
+ case JIM_TT_SUBEXPR_END:
13885
+ ok = 0;
13886
+ while (Jim_StackLen(&stack)) {
13887
+ ParseToken *tt = Jim_StackPop(&stack);
13888
+
13889
+ if (tt->type == JIM_TT_SUBEXPR_START) {
13890
+ ok = 1;
13891
+ break;
13892
+ }
13893
+
13894
+ if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13895
+ goto err;
13896
+ }
13897
+ }
13898
+ if (!ok) {
13899
+ Jim_SetResultString(interp, "Unexpected close parenthesis", -1);
13900
+ goto err;
13901
+ }
13902
+ break;
13903
+
13904
+
13905
+ default:{
13906
+
13907
+ const struct Jim_ExprOperator *op;
13908
+ ParseToken *tt;
13909
+
13910
+
13911
+ if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) {
13912
+ if (t->type == JIM_EXPROP_SUB) {
13913
+ t->type = JIM_EXPROP_UNARYMINUS;
13914
+ }
13915
+ else if (t->type == JIM_EXPROP_ADD) {
13916
+ t->type = JIM_EXPROP_UNARYPLUS;
13917
+ }
13918
+ }
13919
+
13920
+ op = JimExprOperatorInfoByOpcode(t->type);
13921
+
13922
+
13923
+ while ((tt = Jim_StackPeek(&stack)) != NULL) {
13924
+ const struct Jim_ExprOperator *tt_op =
13925
+ JimExprOperatorInfoByOpcode(tt->type);
13926
+
13927
+
13928
+
13929
+ if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13930
+ if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13931
+ ok = 0;
13932
+ goto err;
13933
+ }
13934
+ Jim_StackPop(&stack);
13935
+ }
13936
+ else {
13937
+ break;
13938
+ }
13939
+ }
13940
+ Jim_StackPush(&stack, t);
13941
+ break;
13942
+ }
1385813943
}
1385913944
prevtt = t->type;
1386013945
}
1386113946
13862
-
13947
+
1386313948
while (Jim_StackLen(&stack)) {
1386413949
ParseToken *tt = Jim_StackPop(&stack);
1386513950
1386613951
if (tt->type == JIM_TT_SUBEXPR_START) {
1386713952
ok = 0;
@@ -13877,11 +13962,11 @@
1387713962
if (have_ternary) {
1387813963
ExprTernaryReorderExpression(interp, expr);
1387913964
}
1388013965
1388113966
err:
13882
-
13967
+
1388313968
Jim_FreeStack(&stack);
1388413969
1388513970
for (i = 0; i < expr->len; i++) {
1388613971
Jim_IncrRefCount(expr->token[i].objPtr);
1388713972
}
@@ -13904,11 +13989,11 @@
1390413989
ParseTokenList tokenlist;
1390513990
int line;
1390613991
Jim_Obj *fileNameObj;
1390713992
int rc = JIM_ERR;
1390813993
13909
-
13994
+
1391013995
if (objPtr->typePtr == &sourceObjType) {
1391113996
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
1391213997
line = objPtr->internalRep.sourceValue.lineNumber;
1391313998
}
1391413999
else {
@@ -13917,17 +14002,18 @@
1391714002
}
1391814003
Jim_IncrRefCount(fileNameObj);
1391914004
1392014005
exprText = Jim_GetString(objPtr, &exprTextLen);
1392114006
13922
-
14007
+
1392314008
ScriptTokenListInit(&tokenlist);
1392414009
1392514010
JimParserInit(&parser, exprText, exprTextLen, line);
1392614011
while (!parser.eof) {
1392714012
if (JimParseExpression(&parser) != JIM_OK) {
1392814013
ScriptTokenListFree(&tokenlist);
14014
+ invalidexpr:
1392914015
Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
1393014016
expr = NULL;
1393114017
goto err;
1393214018
}
1393314019
@@ -13950,14 +14036,14 @@
1395014036
ScriptTokenListFree(&tokenlist);
1395114037
Jim_DecrRefCount(interp, fileNameObj);
1395214038
return JIM_ERR;
1395314039
}
1395414040
14041
+
14042
+ expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj);
1395514043
13956
- expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj);
13957
-
13958
-
14044
+
1395914045
ScriptTokenListFree(&tokenlist);
1396014046
1396114047
if (!expr) {
1396214048
goto err;
1396314049
}
@@ -13973,22 +14059,20 @@
1397314059
printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
1397414060
}
1397514061
}
1397614062
#endif
1397714063
13978
-
13979
- if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) {
13980
-
14064
+
14065
+ if (ExprCheckCorrectness(expr) != JIM_OK) {
1398114066
ExprFreeByteCode(interp, expr);
13982
- expr = NULL;
13983
- goto err;
14067
+ goto invalidexpr;
1398414068
}
1398514069
1398614070
rc = JIM_OK;
1398714071
1398814072
err:
13989
-
14073
+
1399014074
Jim_DecrRefCount(interp, fileNameObj);
1399114075
Jim_FreeIntRep(interp, objPtr);
1399214076
Jim_SetIntRepPtr(objPtr, expr);
1399314077
objPtr->typePtr = &exprObjType;
1399414078
return rc;
@@ -14028,11 +14112,11 @@
1402814112
int retcode = JIM_OK;
1402914113
struct JimExprState e;
1403014114
1403114115
expr = JimGetExpression(interp, exprObjPtr);
1403214116
if (!expr) {
14033
- return JIM_ERR;
14117
+ return JIM_ERR;
1403414118
}
1403514119
1403614120
#ifdef JIM_OPTIMIZATION
1403714121
{
1403814122
Jim_Obj *objPtr;
@@ -14101,27 +14185,26 @@
1410114185
noopt:
1410214186
#endif
1410314187
1410414188
expr->inUse++;
1410514189
14106
-
14190
+
1410714191
1410814192
if (expr->len > JIM_EE_STATICSTACK_LEN)
1410914193
e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
1411014194
else
1411114195
e.stack = staticStack;
1411214196
1411314197
e.stacklen = 0;
1411414198
14115
-
14199
+
1411614200
for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
1411714201
Jim_Obj *objPtr;
1411814202
1411914203
switch (expr->token[i].type) {
1412014204
case JIM_TT_EXPR_INT:
1412114205
case JIM_TT_EXPR_DOUBLE:
14122
- case JIM_TT_EXPR_BOOLEAN:
1412314206
case JIM_TT_STR:
1412414207
ExprPush(&e, expr->token[i].objPtr);
1412514208
break;
1412614209
1412714210
case JIM_TT_VAR:
@@ -14157,16 +14240,16 @@
1415714240
ExprPush(&e, Jim_GetResult(interp));
1415814241
}
1415914242
break;
1416014243
1416114244
default:{
14162
-
14245
+
1416314246
e.skip = 0;
1416414247
e.opcode = expr->token[i].type;
1416514248
1416614249
retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
14167
-
14250
+
1416814251
i += e.skip;
1416914252
continue;
1417014253
}
1417114254
}
1417214255
}
@@ -14190,27 +14273,20 @@
1419014273
int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
1419114274
{
1419214275
int retcode;
1419314276
jim_wide wideValue;
1419414277
double doubleValue;
14195
- int booleanValue;
1419614278
Jim_Obj *exprResultPtr;
1419714279
1419814280
retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
1419914281
if (retcode != JIM_OK)
1420014282
return retcode;
1420114283
1420214284
if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
1420314285
if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
14204
- if (Jim_GetBoolean(interp, exprResultPtr, &booleanValue) != JIM_OK) {
14205
- Jim_DecrRefCount(interp, exprResultPtr);
14206
- return JIM_ERR;
14207
- } else {
14208
- Jim_DecrRefCount(interp, exprResultPtr);
14209
- *boolPtr = booleanValue;
14210
- return JIM_OK;
14211
- }
14286
+ Jim_DecrRefCount(interp, exprResultPtr);
14287
+ return JIM_ERR;
1421214288
}
1421314289
else {
1421414290
Jim_DecrRefCount(interp, exprResultPtr);
1421514291
*boolPtr = doubleValue != 0;
1421614292
return JIM_OK;
@@ -14225,29 +14301,29 @@
1422514301
1422614302
1422714303
1422814304
typedef struct ScanFmtPartDescr
1422914305
{
14230
- char *arg;
14231
- char *prefix;
14232
- size_t width;
14233
- int pos;
14234
- char type;
14235
- char modifier;
14306
+ char *arg;
14307
+ char *prefix;
14308
+ size_t width;
14309
+ int pos;
14310
+ char type;
14311
+ char modifier;
1423614312
} ScanFmtPartDescr;
1423714313
1423814314
1423914315
typedef struct ScanFmtStringObj
1424014316
{
14241
- jim_wide size;
14242
- char *stringRep;
14243
- size_t count;
14244
- size_t convCount;
14245
- size_t maxPos;
14246
- const char *error;
14247
- char *scratch;
14248
- ScanFmtPartDescr descr[1];
14317
+ jim_wide size;
14318
+ char *stringRep;
14319
+ size_t count;
14320
+ size_t convCount;
14321
+ size_t maxPos;
14322
+ const char *error;
14323
+ char *scratch;
14324
+ ScanFmtPartDescr descr[1];
1424914325
} ScanFmtStringObj;
1425014326
1425114327
1425214328
static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
1425314329
static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14294,22 +14370,22 @@
1429414370
int maxFmtLen = objPtr->length;
1429514371
const char *fmtEnd = fmt + maxFmtLen;
1429614372
int curr;
1429714373
1429814374
Jim_FreeIntRep(interp, objPtr);
14299
-
14375
+
1430014376
for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
1430114377
if (fmt[i] == '%')
1430214378
++maxCount;
14303
-
14304
- approxSize = sizeof(ScanFmtStringObj)
14305
- +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14306
- +maxFmtLen * sizeof(char) + 3 + 1
14307
- + maxFmtLen * sizeof(char) + 1
14308
- + maxFmtLen * sizeof(char)
14309
- +(maxCount + 1) * sizeof(char)
14310
- +1;
14379
+
14380
+ approxSize = sizeof(ScanFmtStringObj)
14381
+ +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14382
+ +maxFmtLen * sizeof(char) + 3 + 1
14383
+ + maxFmtLen * sizeof(char) + 1
14384
+ + maxFmtLen * sizeof(char)
14385
+ +(maxCount + 1) * sizeof(char)
14386
+ +1;
1431114387
fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
1431214388
memset(fmtObj, 0, approxSize);
1431314389
fmtObj->size = approxSize;
1431414390
fmtObj->maxPos = 0;
1431514391
fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14321,12 +14397,12 @@
1432114397
for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
1432214398
int width = 0, skip;
1432314399
ScanFmtPartDescr *descr = &fmtObj->descr[curr];
1432414400
1432514401
fmtObj->count++;
14326
- descr->width = 0;
14327
-
14402
+ descr->width = 0;
14403
+
1432814404
if (*fmt != '%' || fmt[1] == '%') {
1432914405
descr->type = 0;
1433014406
descr->prefix = &buffer[i];
1433114407
for (; fmt < fmtEnd; ++fmt) {
1433214408
if (*fmt == '%') {
@@ -14336,65 +14412,65 @@
1433614412
}
1433714413
buffer[i++] = *fmt;
1433814414
}
1433914415
buffer[i++] = 0;
1434014416
}
14341
-
14417
+
1434214418
++fmt;
14343
-
14419
+
1434414420
if (fmt >= fmtEnd)
1434514421
goto done;
14346
- descr->pos = 0;
14422
+ descr->pos = 0;
1434714423
if (*fmt == '*') {
14348
- descr->pos = -1;
14424
+ descr->pos = -1;
1434914425
++fmt;
1435014426
}
1435114427
else
14352
- fmtObj->convCount++;
14353
-
14428
+ fmtObj->convCount++;
14429
+
1435414430
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
1435514431
fmt += skip;
14356
-
14432
+
1435714433
if (descr->pos != -1 && *fmt == '$') {
1435814434
int prev;
1435914435
1436014436
++fmt;
1436114437
descr->pos = width;
1436214438
width = 0;
14363
-
14439
+
1436414440
if ((lastPos == 0 && descr->pos > 0)
1436514441
|| (lastPos > 0 && descr->pos == 0)) {
1436614442
fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
1436714443
return JIM_ERR;
1436814444
}
14369
-
14445
+
1437014446
for (prev = 0; prev < curr; ++prev) {
1437114447
if (fmtObj->descr[prev].pos == -1)
1437214448
continue;
1437314449
if (fmtObj->descr[prev].pos == descr->pos) {
1437414450
fmtObj->error =
1437514451
"variable is assigned by multiple \"%n$\" conversion specifiers";
1437614452
return JIM_ERR;
1437714453
}
1437814454
}
14379
-
14455
+
1438014456
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
1438114457
descr->width = width;
1438214458
fmt += skip;
1438314459
}
1438414460
if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
1438514461
fmtObj->maxPos = descr->pos;
1438614462
}
1438714463
else {
14388
-
14464
+
1438914465
descr->width = width;
1439014466
}
1439114467
}
14392
-
14468
+
1439314469
if (lastPos == -1)
1439414470
lastPos = descr->pos;
14395
-
14471
+
1439614472
if (*fmt == '[') {
1439714473
int swapped = 1, beg = i, end, j;
1439814474
1439914475
descr->type = '[';
1440014476
descr->arg = &buffer[i];
@@ -14409,11 +14485,11 @@
1440914485
fmtObj->error = "unmatched [ in format string";
1441014486
return JIM_ERR;
1441114487
}
1441214488
end = i;
1441314489
buffer[i++] = 0;
14414
-
14490
+
1441514491
while (swapped) {
1441614492
swapped = 0;
1441714493
for (j = beg + 1; j < end - 1; ++j) {
1441814494
if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
1441914495
char tmp = buffer[j - 1];
@@ -14424,11 +14500,11 @@
1442414500
}
1442514501
}
1442614502
}
1442714503
}
1442814504
else {
14429
-
14505
+
1443014506
if (strchr("hlL", *fmt) != 0)
1443114507
descr->modifier = tolower((int)*fmt++);
1443214508
1443314509
descr->type = *fmt;
1443414510
if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14467,11 +14543,11 @@
1446714543
while (*str) {
1446814544
int c;
1446914545
int n;
1447014546
1447114547
if (!sdescr && isspace(UCHAR(*str)))
14472
- break;
14548
+ break;
1447314549
1447414550
n = utf8_tounicode(str, &c);
1447514551
if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
1447614552
break;
1447714553
while (n--)
@@ -14490,89 +14566,89 @@
1449014566
size_t scanned = 0;
1449114567
size_t anchor = pos;
1449214568
int i;
1449314569
Jim_Obj *tmpObj = NULL;
1449414570
14495
-
14571
+
1449614572
*valObjPtr = 0;
1449714573
if (descr->prefix) {
1449814574
for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
14499
-
14575
+
1450014576
if (isspace(UCHAR(descr->prefix[i])))
1450114577
while (pos < strLen && isspace(UCHAR(str[pos])))
1450214578
++pos;
1450314579
else if (descr->prefix[i] != str[pos])
14504
- break;
14580
+ break;
1450514581
else
14506
- ++pos;
14582
+ ++pos;
1450714583
}
1450814584
if (pos >= strLen) {
14509
- return -1;
14585
+ return -1;
1451014586
}
1451114587
else if (descr->prefix[i] != 0)
14512
- return 0;
14588
+ return 0;
1451314589
}
14514
-
14590
+
1451514591
if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
1451614592
while (isspace(UCHAR(str[pos])))
1451714593
++pos;
14518
-
14594
+
1451914595
scanned = pos - anchor;
1452014596
14521
-
14597
+
1452214598
if (descr->type == 'n') {
14523
-
14599
+
1452414600
*valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
1452514601
}
1452614602
else if (pos >= strLen) {
14527
-
14603
+
1452814604
return -1;
1452914605
}
1453014606
else if (descr->type == 'c') {
1453114607
int c;
1453214608
scanned += utf8_tounicode(&str[pos], &c);
1453314609
*valObjPtr = Jim_NewIntObj(interp, c);
1453414610
return scanned;
1453514611
}
1453614612
else {
14537
-
14613
+
1453814614
if (descr->width > 0) {
1453914615
size_t sLen = utf8_strlen(&str[pos], strLen - pos);
1454014616
size_t tLen = descr->width > sLen ? sLen : descr->width;
1454114617
1454214618
tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
1454314619
tok = tmpObj->bytes;
1454414620
}
1454514621
else {
14546
-
14622
+
1454714623
tok = &str[pos];
1454814624
}
1454914625
switch (descr->type) {
1455014626
case 'd':
1455114627
case 'o':
1455214628
case 'x':
1455314629
case 'u':
1455414630
case 'i':{
14555
- char *endp;
14631
+ char *endp;
1455614632
jim_wide w;
1455714633
1455814634
int base = descr->type == 'o' ? 8
1455914635
: descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
1456014636
14561
-
14637
+
1456214638
if (base == 0) {
1456314639
w = jim_strtoull(tok, &endp);
1456414640
}
1456514641
else {
1456614642
w = strtoull(tok, &endp, base);
1456714643
}
1456814644
1456914645
if (endp != tok) {
14570
-
14646
+
1457114647
*valObjPtr = Jim_NewIntObj(interp, w);
1457214648
14573
-
14649
+
1457414650
scanned += endp - tok;
1457514651
}
1457614652
else {
1457714653
scanned = *tok ? 0 : -1;
1457814654
}
@@ -14589,13 +14665,13 @@
1458914665
case 'g':{
1459014666
char *endp;
1459114667
double value = strtod(tok, &endp);
1459214668
1459314669
if (endp != tok) {
14594
-
14670
+
1459514671
*valObjPtr = Jim_NewDoubleObj(interp, value);
14596
-
14672
+
1459714673
scanned += endp - tok;
1459814674
}
1459914675
else {
1460014676
scanned = *tok ? 0 : -1;
1460114677
}
@@ -14620,65 +14696,65 @@
1462014696
Jim_Obj **resultVec = 0;
1462114697
int resultc;
1462214698
Jim_Obj *emptyStr = 0;
1462314699
ScanFmtStringObj *fmtObj;
1462414700
14625
-
14701
+
1462614702
JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
1462714703
1462814704
fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
14629
-
14705
+
1463014706
if (fmtObj->error != 0) {
1463114707
if (flags & JIM_ERRMSG)
1463214708
Jim_SetResultString(interp, fmtObj->error, -1);
1463314709
return 0;
1463414710
}
14635
-
14711
+
1463614712
emptyStr = Jim_NewEmptyStringObj(interp);
1463714713
Jim_IncrRefCount(emptyStr);
14638
-
14714
+
1463914715
resultList = Jim_NewListObj(interp, NULL, 0);
1464014716
if (fmtObj->maxPos > 0) {
1464114717
for (i = 0; i < fmtObj->maxPos; ++i)
1464214718
Jim_ListAppendElement(interp, resultList, emptyStr);
1464314719
JimListGetElements(interp, resultList, &resultc, &resultVec);
1464414720
}
14645
-
14721
+
1464614722
for (i = 0, pos = 0; i < fmtObj->count; ++i) {
1464714723
ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
1464814724
Jim_Obj *value = 0;
1464914725
14650
-
14726
+
1465114727
if (descr->type == 0)
1465214728
continue;
14653
-
14729
+
1465414730
if (scanned > 0)
1465514731
scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
14656
-
14732
+
1465714733
if (scanned == -1 && i == 0)
1465814734
goto eof;
14659
-
14735
+
1466014736
pos += scanned;
1466114737
14662
-
14738
+
1466314739
if (value == 0)
1466414740
value = Jim_NewEmptyStringObj(interp);
14665
-
14741
+
1466614742
if (descr->pos == -1) {
1466714743
Jim_FreeNewObj(interp, value);
1466814744
}
1466914745
else if (descr->pos == 0)
14670
-
14746
+
1467114747
Jim_ListAppendElement(interp, resultList, value);
1467214748
else if (resultVec[descr->pos - 1] == emptyStr) {
14673
-
14749
+
1467414750
Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
1467514751
Jim_IncrRefCount(value);
1467614752
resultVec[descr->pos - 1] = value;
1467714753
}
1467814754
else {
14679
-
14755
+
1468014756
Jim_FreeNewObj(interp, value);
1468114757
goto err;
1468214758
}
1468314759
}
1468414760
Jim_DecrRefCount(interp, emptyStr);
@@ -14716,15 +14792,15 @@
1471614792
{
1471714793
Jim_PrngState *prng;
1471814794
unsigned char *destByte = (unsigned char *)dest;
1471914795
unsigned int si, sj, x;
1472014796
14721
-
14797
+
1472214798
if (interp->prngState == NULL)
1472314799
JimPrngInit(interp);
1472414800
prng = interp->prngState;
14725
-
14801
+
1472614802
for (x = 0; x < len; x++) {
1472714803
prng->i = (prng->i + 1) & 0xff;
1472814804
si = prng->sbox[prng->i];
1472914805
prng->j = (prng->j + si) & 0xff;
1473014806
sj = prng->sbox[prng->j];
@@ -14738,19 +14814,19 @@
1473814814
static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
1473914815
{
1474014816
int i;
1474114817
Jim_PrngState *prng;
1474214818
14743
-
14819
+
1474414820
if (interp->prngState == NULL)
1474514821
JimPrngInit(interp);
1474614822
prng = interp->prngState;
1474714823
14748
-
14824
+
1474914825
for (i = 0; i < 256; i++)
1475014826
prng->sbox[i] = i;
14751
-
14827
+
1475214828
for (i = 0; i < seedLen; i++) {
1475314829
unsigned char t;
1475414830
1475514831
t = prng->sbox[i & 0xFF];
1475614832
prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14777,11 +14853,11 @@
1477714853
if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
1477814854
return JIM_ERR;
1477914855
}
1478014856
intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1478114857
if (!intObjPtr) {
14782
-
14858
+
1478314859
wideValue = 0;
1478414860
}
1478514861
else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
1478614862
return JIM_ERR;
1478714863
}
@@ -14791,26 +14867,26 @@
1479114867
Jim_FreeNewObj(interp, intObjPtr);
1479214868
return JIM_ERR;
1479314869
}
1479414870
}
1479514871
else {
14796
-
14872
+
1479714873
Jim_InvalidateStringRep(intObjPtr);
1479814874
JimWideValue(intObjPtr) = wideValue + increment;
1479914875
1480014876
if (argv[1]->typePtr != &variableObjType) {
14801
-
14877
+
1480214878
Jim_SetVariable(interp, argv[1], intObjPtr);
1480314879
}
1480414880
}
1480514881
Jim_SetResult(interp, intObjPtr);
1480614882
return JIM_OK;
1480714883
}
1480814884
1480914885
14810
-#define JIM_EVAL_SARGV_LEN 8
14811
-#define JIM_EVAL_SINTV_LEN 8
14886
+#define JIM_EVAL_SARGV_LEN 8
14887
+#define JIM_EVAL_SINTV_LEN 8
1481214888
1481314889
1481414890
static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1481514891
{
1481614892
int retcode;
@@ -14818,16 +14894,16 @@
1481814894
if (interp->unknown_called > 50) {
1481914895
return JIM_ERR;
1482014896
}
1482114897
1482214898
14823
-
14899
+
1482414900
if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
1482514901
return JIM_ERR;
1482614902
1482714903
interp->unknown_called++;
14828
-
14904
+
1482914905
retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
1483014906
interp->unknown_called--;
1483114907
1483214908
return retcode;
1483314909
}
@@ -14845,11 +14921,11 @@
1484514921
}
1484614922
printf("\n");
1484714923
#endif
1484814924
1484914925
if (interp->framePtr->tailcallCmd) {
14850
-
14926
+
1485114927
cmdPtr = interp->framePtr->tailcallCmd;
1485214928
interp->framePtr->tailcallCmd = NULL;
1485314929
}
1485414930
else {
1485514931
cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14864,11 +14940,11 @@
1486414940
retcode = JIM_ERR;
1486514941
goto out;
1486614942
}
1486714943
interp->evalDepth++;
1486814944
14869
-
14945
+
1487014946
Jim_SetEmptyResult(interp);
1487114947
if (cmdPtr->isproc) {
1487214948
retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
1487314949
}
1487414950
else {
@@ -14885,17 +14961,17 @@
1488514961
1488614962
int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
1488714963
{
1488814964
int i, retcode;
1488914965
14890
-
14966
+
1489114967
for (i = 0; i < objc; i++)
1489214968
Jim_IncrRefCount(objv[i]);
1489314969
1489414970
retcode = JimInvokeCommand(interp, objc, objv);
1489514971
14896
-
14972
+
1489714973
for (i = 0; i < objc; i++)
1489814974
Jim_DecrRefCount(interp, objv[i]);
1489914975
1490014976
return retcode;
1490114977
}
@@ -14913,25 +14989,25 @@
1491314989
}
1491414990
1491514991
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
1491614992
{
1491714993
if (!interp->errorFlag) {
14918
-
14994
+
1491914995
interp->errorFlag = 1;
1492014996
Jim_IncrRefCount(script->fileNameObj);
1492114997
Jim_DecrRefCount(interp, interp->errorFileNameObj);
1492214998
interp->errorFileNameObj = script->fileNameObj;
1492314999
interp->errorLine = script->linenr;
1492415000
1492515001
JimResetStackTrace(interp);
14926
-
15002
+
1492715003
interp->addStackTrace++;
1492815004
}
1492915005
14930
-
15006
+
1493115007
if (interp->addStackTrace > 0) {
14932
-
15008
+
1493315009
1493415010
JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
1493515011
1493615012
if (Jim_Length(script->fileNameObj)) {
1493715013
interp->addStackTrace = 0;
@@ -14966,14 +15042,14 @@
1496615042
case JIM_OK:
1496715043
case JIM_RETURN:
1496815044
objPtr = interp->result;
1496915045
break;
1497015046
case JIM_BREAK:
14971
-
15047
+
1497215048
return JIM_BREAK;
1497315049
case JIM_CONTINUE:
14974
-
15050
+
1497515051
return JIM_CONTINUE;
1497615052
default:
1497715053
return JIM_ERR;
1497815054
}
1497915055
break;
@@ -15008,23 +15084,23 @@
1500815084
case JIM_OK:
1500915085
case JIM_RETURN:
1501015086
break;
1501115087
case JIM_BREAK:
1501215088
if (flags & JIM_SUBST_FLAG) {
15013
-
15089
+
1501415090
tokens = i;
1501515091
continue;
1501615092
}
15017
-
15018
-
15093
+
15094
+
1501915095
case JIM_CONTINUE:
1502015096
if (flags & JIM_SUBST_FLAG) {
1502115097
intv[i] = NULL;
1502215098
continue;
1502315099
}
15024
-
15025
-
15100
+
15101
+
1502615102
default:
1502715103
while (i--) {
1502815104
Jim_DecrRefCount(interp, intv[i]);
1502915105
}
1503015106
if (intv != sintv) {
@@ -15035,28 +15111,28 @@
1503515111
Jim_IncrRefCount(intv[i]);
1503615112
Jim_String(intv[i]);
1503715113
totlen += intv[i]->length;
1503815114
}
1503915115
15040
-
15116
+
1504115117
if (tokens == 1 && intv[0] && intv == sintv) {
1504215118
Jim_DecrRefCount(interp, intv[0]);
1504315119
return intv[0];
1504415120
}
1504515121
1504615122
objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
1504715123
1504815124
if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
1504915125
&& token[2].type == JIM_TT_VAR) {
15050
-
15126
+
1505115127
objPtr->typePtr = &interpolatedObjType;
1505215128
objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
1505315129
objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
1505415130
Jim_IncrRefCount(intv[2]);
1505515131
}
1505615132
else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
15057
-
15133
+
1505815134
JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
1505915135
}
1506015136
1506115137
1506215138
s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -15067,11 +15143,11 @@
1506715143
s += intv[i]->length;
1506815144
Jim_DecrRefCount(interp, intv[i]);
1506915145
}
1507015146
}
1507115147
objPtr->bytes[totlen] = '\0';
15072
-
15148
+
1507315149
if (intv != sintv) {
1507415150
Jim_Free(intv);
1507515151
}
1507615152
1507715153
return objPtr;
@@ -15111,11 +15187,11 @@
1511115187
1511215188
if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
1511315189
return JimEvalObjList(interp, scriptObjPtr);
1511415190
}
1511515191
15116
- Jim_IncrRefCount(scriptObjPtr);
15192
+ Jim_IncrRefCount(scriptObjPtr);
1511715193
script = JimGetScript(interp, scriptObjPtr);
1511815194
if (!JimScriptValid(interp, script)) {
1511915195
Jim_DecrRefCount(interp, scriptObjPtr);
1512015196
return JIM_ERR;
1512115197
}
@@ -15147,11 +15223,11 @@
1514715223
}
1514815224
#endif
1514915225
1515015226
script->inUse++;
1515115227
15152
-
15228
+
1515315229
prevScriptObj = interp->currentScriptObj;
1515415230
interp->currentScriptObj = scriptObjPtr;
1515515231
1515615232
interp->errorFlag = 0;
1515715233
argv = sargv;
@@ -15158,19 +15234,19 @@
1515815234
1515915235
for (i = 0; i < script->len && retcode == JIM_OK; ) {
1516015236
int argc;
1516115237
int j;
1516215238
15163
-
15239
+
1516415240
argc = token[i].objPtr->internalRep.scriptLineValue.argc;
1516515241
script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
1516615242
15167
-
15243
+
1516815244
if (argc > JIM_EVAL_SARGV_LEN)
1516915245
argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
1517015246
15171
-
15247
+
1517215248
i++;
1517315249
1517415250
for (j = 0; j < argc; j++) {
1517515251
long wordtokens = 1;
1517615252
int expand = 0;
@@ -15226,11 +15302,11 @@
1522615302
1522715303
if (!expand) {
1522815304
argv[j] = wordObjPtr;
1522915305
}
1523015306
else {
15231
-
15307
+
1523215308
int len = Jim_ListLength(interp, wordObjPtr);
1523315309
int newargc = argc + len - 1;
1523415310
int k;
1523515311
1523615312
if (len > 1) {
@@ -15239,39 +15315,39 @@
1523915315
argv = Jim_Alloc(sizeof(*argv) * newargc);
1524015316
memcpy(argv, sargv, sizeof(*argv) * j);
1524115317
}
1524215318
}
1524315319
else {
15244
-
15320
+
1524515321
argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
1524615322
}
1524715323
}
1524815324
15249
-
15325
+
1525015326
for (k = 0; k < len; k++) {
1525115327
argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
1525215328
Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
1525315329
}
1525415330
1525515331
Jim_DecrRefCount(interp, wordObjPtr);
1525615332
15257
-
15333
+
1525815334
j--;
1525915335
argc += len - 1;
1526015336
}
1526115337
}
1526215338
1526315339
if (retcode == JIM_OK && argc) {
15264
-
15340
+
1526515341
retcode = JimInvokeCommand(interp, argc, argv);
15266
-
15342
+
1526715343
if (Jim_CheckSignal(interp)) {
1526815344
retcode = JIM_SIGNAL;
1526915345
}
1527015346
}
1527115347
15272
-
15348
+
1527315349
while (j-- > 0) {
1527415350
Jim_DecrRefCount(interp, argv[j]);
1527515351
}
1527615352
1527715353
if (argv != sargv) {
@@ -15278,21 +15354,21 @@
1527815354
Jim_Free(argv);
1527915355
argv = sargv;
1528015356
}
1528115357
}
1528215358
15283
-
15359
+
1528415360
if (retcode == JIM_ERR) {
1528515361
JimAddErrorToStack(interp, script);
1528615362
}
15287
-
15363
+
1528815364
else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
15289
-
15365
+
1529015366
interp->addStackTrace = 0;
1529115367
}
1529215368
15293
-
15369
+
1529415370
interp->currentScriptObj = prevScriptObj;
1529515371
1529615372
Jim_FreeIntRep(interp, scriptObjPtr);
1529715373
scriptObjPtr->typePtr = &scriptObjType;
1529815374
Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15302,14 +15378,14 @@
1530215378
}
1530315379
1530415380
static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
1530515381
{
1530615382
int retcode;
15307
-
15383
+
1530815384
const char *varname = Jim_String(argNameObj);
1530915385
if (*varname == '&') {
15310
-
15386
+
1531115387
Jim_Obj *objPtr;
1531215388
Jim_CallFrame *savedCallFrame = interp->framePtr;
1531315389
1531415390
interp->framePtr = interp->framePtr->parent;
1531515391
objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15316,11 +15392,11 @@
1531615392
interp->framePtr = savedCallFrame;
1531715393
if (!objPtr) {
1531815394
return JIM_ERR;
1531915395
}
1532015396
15321
-
15397
+
1532215398
objPtr = Jim_NewStringObj(interp, varname + 1, -1);
1532315399
Jim_IncrRefCount(objPtr);
1532415400
retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
1532515401
Jim_DecrRefCount(interp, objPtr);
1532615402
}
@@ -15330,26 +15406,26 @@
1533015406
return retcode;
1533115407
}
1533215408
1533315409
static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
1533415410
{
15335
-
15411
+
1533615412
Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
1533715413
int i;
1533815414
1533915415
for (i = 0; i < cmd->u.proc.argListLen; i++) {
1534015416
Jim_AppendString(interp, argmsg, " ", 1);
1534115417
1534215418
if (i == cmd->u.proc.argsPos) {
1534315419
if (cmd->u.proc.arglist[i].defaultObjPtr) {
15344
-
15420
+
1534515421
Jim_AppendString(interp, argmsg, "?", 1);
1534615422
Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
1534715423
Jim_AppendString(interp, argmsg, " ...?", -1);
1534815424
}
1534915425
else {
15350
-
15426
+
1535115427
Jim_AppendString(interp, argmsg, "?arg...?", -1);
1535215428
}
1535315429
}
1535415430
else {
1535515431
if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15374,11 +15450,11 @@
1537415450
int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
1537515451
{
1537615452
Jim_CallFrame *callFramePtr;
1537715453
int retcode;
1537815454
15379
-
15455
+
1538015456
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
1538115457
callFramePtr->argv = &interp->emptyObj;
1538215458
callFramePtr->argc = 0;
1538315459
callFramePtr->procArgsObjPtr = NULL;
1538415460
callFramePtr->procBodyObjPtr = scriptObj;
@@ -15386,21 +15462,21 @@
1538615462
callFramePtr->fileNameObj = interp->emptyObj;
1538715463
callFramePtr->line = 0;
1538815464
Jim_IncrRefCount(scriptObj);
1538915465
interp->framePtr = callFramePtr;
1539015466
15391
-
15467
+
1539215468
if (interp->framePtr->level == interp->maxCallFrameDepth) {
1539315469
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
1539415470
retcode = JIM_ERR;
1539515471
}
1539615472
else {
15397
-
15473
+
1539815474
retcode = Jim_EvalObj(interp, scriptObj);
1539915475
}
1540015476
15401
-
15477
+
1540215478
interp->framePtr = interp->framePtr->parent;
1540315479
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
1540415480
1540515481
return retcode;
1540615482
}
@@ -15410,62 +15486,62 @@
1541015486
{
1541115487
Jim_CallFrame *callFramePtr;
1541215488
int i, d, retcode, optargs;
1541315489
ScriptObj *script;
1541415490
15415
-
15491
+
1541615492
if (argc - 1 < cmd->u.proc.reqArity ||
1541715493
(cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
1541815494
JimSetProcWrongArgs(interp, argv[0], cmd);
1541915495
return JIM_ERR;
1542015496
}
1542115497
1542215498
if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15423
-
15499
+
1542415500
return JIM_OK;
1542515501
}
1542615502
15427
-
15503
+
1542815504
if (interp->framePtr->level == interp->maxCallFrameDepth) {
1542915505
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
1543015506
return JIM_ERR;
1543115507
}
1543215508
15433
-
15509
+
1543415510
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
1543515511
callFramePtr->argv = argv;
1543615512
callFramePtr->argc = argc;
1543715513
callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
1543815514
callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
1543915515
callFramePtr->staticVars = cmd->u.proc.staticVars;
1544015516
15441
-
15517
+
1544215518
script = JimGetScript(interp, interp->currentScriptObj);
1544315519
callFramePtr->fileNameObj = script->fileNameObj;
1544415520
callFramePtr->line = script->linenr;
1544515521
1544615522
Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
1544715523
Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
1544815524
interp->framePtr = callFramePtr;
1544915525
15450
-
15526
+
1545115527
optargs = (argc - 1 - cmd->u.proc.reqArity);
1545215528
15453
-
15529
+
1545415530
i = 1;
1545515531
for (d = 0; d < cmd->u.proc.argListLen; d++) {
1545615532
Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
1545715533
if (d == cmd->u.proc.argsPos) {
15458
-
15534
+
1545915535
Jim_Obj *listObjPtr;
1546015536
int argsLen = 0;
1546115537
if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
1546215538
argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
1546315539
}
1546415540
listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
1546515541
15466
-
15542
+
1546715543
if (cmd->u.proc.arglist[d].defaultObjPtr) {
1546815544
nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
1546915545
}
1547015546
retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
1547115547
if (retcode != JIM_OK) {
@@ -15474,33 +15550,33 @@
1547415550
1547515551
i += argsLen;
1547615552
continue;
1547715553
}
1547815554
15479
-
15555
+
1548015556
if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
1548115557
retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
1548215558
}
1548315559
else {
15484
-
15560
+
1548515561
retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
1548615562
}
1548715563
if (retcode != JIM_OK) {
1548815564
goto badargset;
1548915565
}
1549015566
}
1549115567
15492
-
15568
+
1549315569
retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
1549415570
1549515571
badargset:
1549615572
15497
-
15573
+
1549815574
interp->framePtr = interp->framePtr->parent;
1549915575
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
1550015576
15501
-
15577
+
1550215578
if (interp->framePtr->tailcallObj) {
1550315579
do {
1550415580
Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
1550515581
1550615582
interp->framePtr->tailcallObj = NULL;
@@ -15512,18 +15588,18 @@
1551215588
}
1551315589
}
1551415590
Jim_DecrRefCount(interp, tailcallObj);
1551515591
} while (interp->framePtr->tailcallObj);
1551615592
15517
-
15593
+
1551815594
if (interp->framePtr->tailcallCmd) {
1551915595
JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
1552015596
interp->framePtr->tailcallCmd = NULL;
1552115597
}
1552215598
}
1552315599
15524
-
15600
+
1552515601
if (retcode == JIM_RETURN) {
1552615602
if (--interp->returnLevel <= 0) {
1552715603
retcode = interp->returnCode;
1552815604
interp->returnCode = JIM_OK;
1552915605
interp->returnLevel = 0;
@@ -15635,20 +15711,20 @@
1563515711
prevScriptObj = interp->currentScriptObj;
1563615712
interp->currentScriptObj = scriptObjPtr;
1563715713
1563815714
retcode = Jim_EvalObj(interp, scriptObjPtr);
1563915715
15640
-
15716
+
1564115717
if (retcode == JIM_RETURN) {
1564215718
if (--interp->returnLevel <= 0) {
1564315719
retcode = interp->returnCode;
1564415720
interp->returnCode = JIM_OK;
1564515721
interp->returnLevel = 0;
1564615722
}
1564715723
}
1564815724
if (retcode == JIM_ERR) {
15649
-
15725
+
1565015726
interp->addStackTrace++;
1565115727
}
1565215728
1565315729
interp->currentScriptObj = prevScriptObj;
1565415730
@@ -15674,11 +15750,11 @@
1567415750
}
1567515751
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
1567615752
if (JimParseVar(pc) == JIM_OK) {
1567715753
return;
1567815754
}
15679
-
15755
+
1568015756
pc->tstart = pc->p;
1568115757
flags |= JIM_SUBST_NOVAR;
1568215758
}
1568315759
while (pc->len) {
1568415760
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15705,32 +15781,32 @@
1570515781
const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
1570615782
struct JimParserCtx parser;
1570715783
struct ScriptObj *script = Jim_Alloc(sizeof(*script));
1570815784
ParseTokenList tokenlist;
1570915785
15710
-
15786
+
1571115787
ScriptTokenListInit(&tokenlist);
1571215788
1571315789
JimParserInit(&parser, scriptText, scriptTextLen, 1);
1571415790
while (1) {
1571515791
JimParseSubst(&parser, flags);
1571615792
if (parser.eof) {
15717
-
15793
+
1571815794
break;
1571915795
}
1572015796
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
1572115797
parser.tline);
1572215798
}
1572315799
15724
-
15800
+
1572515801
script->inUse = 1;
1572615802
script->substFlags = flags;
1572715803
script->fileNameObj = interp->emptyObj;
1572815804
Jim_IncrRefCount(script->fileNameObj);
1572915805
SubstObjAddTokens(interp, script, &tokenlist);
1573015806
15731
-
15807
+
1573215808
ScriptTokenListFree(&tokenlist);
1573315809
1573415810
#ifdef DEBUG_SHOW_SUBST
1573515811
{
1573615812
int i;
@@ -15741,11 +15817,11 @@
1574115817
Jim_String(script->token[i].objPtr));
1574215818
}
1574315819
}
1574415820
#endif
1574515821
15746
-
15822
+
1574715823
Jim_FreeIntRep(interp, objPtr);
1574815824
Jim_SetIntRepPtr(objPtr, script);
1574915825
objPtr->typePtr = &scriptObjType;
1575015826
return JIM_OK;
1575115827
}
@@ -15759,11 +15835,11 @@
1575915835
1576015836
int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
1576115837
{
1576215838
ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
1576315839
15764
- Jim_IncrRefCount(substObjPtr);
15840
+ Jim_IncrRefCount(substObjPtr);
1576515841
script->inUse++;
1576615842
1576715843
*resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
1576815844
1576915845
script->inUse--;
@@ -15775,15 +15851,11 @@
1577515851
}
1577615852
1577715853
void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
1577815854
{
1577915855
Jim_Obj *objPtr;
15780
- Jim_Obj *listObjPtr;
15781
-
15782
- JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0"));
15783
-
15784
- listObjPtr = Jim_NewListObj(interp, argv, argc);
15856
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
1578515857
1578615858
if (*msg) {
1578715859
Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
1578815860
}
1578915861
Jim_IncrRefCount(listObjPtr);
@@ -15804,11 +15876,11 @@
1580415876
JimHashtableIteratorCallbackType *callback, int type)
1580515877
{
1580615878
Jim_HashEntry *he;
1580715879
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
1580815880
15809
-
15881
+
1581015882
if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
1581115883
he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
1581215884
if (he) {
1581315885
callback(interp, listObjPtr, he, type);
1581415886
}
@@ -15835,11 +15907,11 @@
1583515907
{
1583615908
Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
1583715909
Jim_Obj *objPtr;
1583815910
1583915911
if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
15840
-
15912
+
1584115913
return;
1584215914
}
1584315915
1584415916
objPtr = Jim_NewStringObj(interp, he->key, -1);
1584515917
Jim_IncrRefCount(objPtr);
@@ -15895,11 +15967,11 @@
1589515967
1589615968
targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
1589715969
if (targetCallFrame == NULL) {
1589815970
return JIM_ERR;
1589915971
}
15900
-
15972
+
1590115973
if (targetCallFrame == interp->topFramePtr) {
1590215974
Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
1590315975
return JIM_ERR;
1590415976
}
1590515977
if (info_level_cmd) {
@@ -16082,11 +16154,11 @@
1608216154
if (!objPtr)
1608316155
return JIM_ERR;
1608416156
Jim_SetResult(interp, objPtr);
1608516157
return JIM_OK;
1608616158
}
16087
-
16159
+
1608816160
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
1608916161
return JIM_ERR;
1609016162
Jim_SetResult(interp, argv[2]);
1609116163
return JIM_OK;
1609216164
}
@@ -16125,11 +16197,11 @@
1612516197
if (argc != 3) {
1612616198
Jim_WrongNumArgs(interp, 1, argv, "condition body");
1612716199
return JIM_ERR;
1612816200
}
1612916201
16130
-
16202
+
1613116203
while (1) {
1613216204
int boolean, retval;
1613316205
1613416206
if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
1613516207
return retval;
@@ -16165,11 +16237,11 @@
1616516237
if (argc != 5) {
1616616238
Jim_WrongNumArgs(interp, 1, argv, "start test next body");
1616716239
return JIM_ERR;
1616816240
}
1616916241
16170
-
16242
+
1617116243
if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
1617216244
return retval;
1617316245
}
1617416246
1617516247
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16181,19 +16253,19 @@
1618116253
ExprByteCode *expr;
1618216254
jim_wide stop, currentVal;
1618316255
Jim_Obj *objPtr;
1618416256
int cmpOffset;
1618516257
16186
-
16258
+
1618716259
expr = JimGetExpression(interp, argv[2]);
1618816260
incrScript = JimGetScript(interp, argv[3]);
1618916261
16190
-
16262
+
1619116263
if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
1619216264
goto evalstart;
1619316265
}
16194
-
16266
+
1619516267
if (incrScript->token[1].type != JIM_TT_ESC ||
1619616268
expr->token[0].type != JIM_TT_VAR ||
1619716269
(expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
1619816270
goto evalstart;
1619916271
}
@@ -16206,48 +16278,48 @@
1620616278
}
1620716279
else {
1620816280
goto evalstart;
1620916281
}
1621016282
16211
-
16283
+
1621216284
if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
1621316285
goto evalstart;
1621416286
}
1621516287
16216
-
16288
+
1621716289
if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
1621816290
goto evalstart;
1621916291
}
1622016292
16221
-
16293
+
1622216294
if (expr->token[1].type == JIM_TT_EXPR_INT) {
1622316295
if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
1622416296
goto evalstart;
1622516297
}
1622616298
}
1622716299
else {
1622816300
stopVarNamePtr = expr->token[1].objPtr;
1622916301
Jim_IncrRefCount(stopVarNamePtr);
16230
-
16302
+
1623116303
stop = 0;
1623216304
}
1623316305
16234
-
16306
+
1623516307
varNamePtr = expr->token[0].objPtr;
1623616308
Jim_IncrRefCount(varNamePtr);
1623716309
1623816310
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
1623916311
if (objPtr == NULL || Jim_GetWide(interp, objPtr, &currentVal) != JIM_OK) {
1624016312
goto testcond;
1624116313
}
1624216314
16243
-
16315
+
1624416316
while (retval == JIM_OK) {
16317
+
16318
+
1624516319
16246
-
16247
-
16248
-
16320
+
1624916321
if (stopVarNamePtr) {
1625016322
objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
1625116323
if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
1625216324
goto testcond;
1625316325
}
@@ -16255,18 +16327,18 @@
1625516327
1625616328
if (currentVal >= stop + cmpOffset) {
1625716329
break;
1625816330
}
1625916331
16260
-
16332
+
1626116333
retval = Jim_EvalObj(interp, argv[4]);
1626216334
if (retval == JIM_OK || retval == JIM_CONTINUE) {
1626316335
retval = JIM_OK;
1626416336
1626516337
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
1626616338
16267
-
16339
+
1626816340
if (objPtr == NULL) {
1626916341
retval = JIM_ERR;
1627016342
goto out;
1627116343
}
1627216344
if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16286,25 +16358,25 @@
1628616358
}
1628716359
evalstart:
1628816360
#endif
1628916361
1629016362
while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
16291
-
16363
+
1629216364
retval = Jim_EvalObj(interp, argv[4]);
1629316365
1629416366
if (retval == JIM_OK || retval == JIM_CONTINUE) {
16295
-
16296
-JIM_IF_OPTIM(evalnext:)
16367
+
16368
+ evalnext:
1629716369
retval = Jim_EvalObj(interp, argv[3]);
1629816370
if (retval == JIM_OK || retval == JIM_CONTINUE) {
16299
-
16300
-JIM_IF_OPTIM(testcond:)
16371
+
16372
+ testcond:
1630116373
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
1630216374
}
1630316375
}
1630416376
}
16305
-JIM_IF_OPTIM(out:)
16377
+ out:
1630616378
if (stopVarNamePtr) {
1630716379
Jim_DecrRefCount(interp, stopVarNamePtr);
1630816380
}
1630916381
if (varNamePtr) {
1631016382
Jim_DecrRefCount(interp, varNamePtr);
@@ -16346,11 +16418,11 @@
1634616418
if (retval == JIM_OK || retval == JIM_CONTINUE) {
1634716419
Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
1634816420
1634916421
retval = JIM_OK;
1635016422
16351
-
16423
+
1635216424
i += incr;
1635316425
1635416426
if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
1635516427
if (argv[1]->typePtr != &variableObjType) {
1635616428
if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16411,21 +16483,21 @@
1641116483
1641216484
static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
1641316485
{
1641416486
int result = JIM_OK;
1641516487
int i, numargs;
16416
- Jim_ListIter twoiters[2];
16488
+ Jim_ListIter twoiters[2];
1641716489
Jim_ListIter *iters;
1641816490
Jim_Obj *script;
1641916491
Jim_Obj *resultObj;
1642016492
1642116493
if (argc < 4 || argc % 2 != 0) {
1642216494
Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
1642316495
return JIM_ERR;
1642416496
}
16425
- script = argv[argc - 1];
16426
- numargs = (argc - 1 - 1);
16497
+ script = argv[argc - 1];
16498
+ numargs = (argc - 1 - 1);
1642716499
1642816500
if (numargs == 2) {
1642916501
iters = twoiters;
1643016502
}
1643116503
else {
@@ -16449,34 +16521,34 @@
1644916521
resultObj = interp->emptyObj;
1645016522
}
1645116523
Jim_IncrRefCount(resultObj);
1645216524
1645316525
while (1) {
16454
-
16526
+
1645516527
for (i = 0; i < numargs; i += 2) {
1645616528
if (!JimListIterDone(interp, &iters[i + 1])) {
1645716529
break;
1645816530
}
1645916531
}
1646016532
if (i == numargs) {
16461
-
16533
+
1646216534
break;
1646316535
}
1646416536
16465
-
16537
+
1646616538
for (i = 0; i < numargs; i += 2) {
1646716539
Jim_Obj *varName;
1646816540
16469
-
16541
+
1647016542
JimListIterInit(&iters[i], argv[i + 1]);
1647116543
while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
1647216544
Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
1647316545
if (!valObj) {
16474
-
16546
+
1647516547
valObj = interp->emptyObj;
1647616548
}
16477
-
16549
+
1647816550
Jim_IncrRefCount(valObj);
1647916551
result = Jim_SetVariable(interp, varName, valObj);
1648016552
Jim_DecrRefCount(interp, valObj);
1648116553
if (result != JIM_OK) {
1648216554
goto err;
@@ -16558,41 +16630,41 @@
1655816630
{
1655916631
int boolean, retval, current = 1, falsebody = 0;
1656016632
1656116633
if (argc >= 3) {
1656216634
while (1) {
16563
-
16635
+
1656416636
if (current >= argc)
1656516637
goto err;
1656616638
if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
1656716639
!= JIM_OK)
1656816640
return retval;
16569
-
16641
+
1657016642
if (current >= argc)
1657116643
goto err;
1657216644
if (Jim_CompareStringImmediate(interp, argv[current], "then"))
1657316645
current++;
16574
-
16646
+
1657516647
if (current >= argc)
1657616648
goto err;
1657716649
if (boolean)
1657816650
return Jim_EvalObj(interp, argv[current]);
16579
-
16651
+
1658016652
if (++current >= argc) {
1658116653
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
1658216654
return JIM_OK;
1658316655
}
1658416656
falsebody = current++;
1658516657
if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
16586
-
16658
+
1658716659
if (current != argc - 1)
1658816660
goto err;
1658916661
return Jim_EvalObj(interp, argv[current]);
1659016662
}
1659116663
else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
1659216664
continue;
16593
-
16665
+
1659416666
else if (falsebody != argc - 1)
1659516667
goto err;
1659616668
return Jim_EvalObj(interp, argv[falsebody]);
1659716669
}
1659816670
return JIM_OK;
@@ -16700,21 +16772,21 @@
1670016772
if (Jim_StringMatchObj(interp, patObj, strObj, 0))
1670116773
script = caseList[i + 1];
1670216774
break;
1670316775
case SWITCH_RE:
1670416776
command = Jim_NewStringObj(interp, "regexp", -1);
16705
-
16777
+
1670616778
case SWITCH_CMD:{
1670716779
int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
1670816780
1670916781
if (argc - opt == 1) {
1671016782
Jim_Obj **vector;
1671116783
1671216784
JimListGetElements(interp, argv[opt], &patCount, &vector);
1671316785
caseList = vector;
1671416786
}
16715
-
16787
+
1671616788
if (rc < 0) {
1671716789
return -rc;
1671816790
}
1671916791
if (rc)
1672016792
script = caseList[i + 1];
@@ -16848,11 +16920,11 @@
1684816920
case OPT_COMMAND:
1684916921
if (i >= argc - 2) {
1685016922
goto wrongargs;
1685116923
}
1685216924
commandObj = argv[++i];
16853
-
16925
+
1685416926
case OPT_EXACT:
1685516927
case OPT_GLOB:
1685616928
case OPT_REGEXP:
1685716929
opt_match = option;
1685816930
break;
@@ -16896,17 +16968,17 @@
1689616968
goto done;
1689716969
}
1689816970
break;
1689916971
}
1690016972
16901
-
16973
+
1690216974
if (!eq && opt_bool && opt_not && !opt_all) {
1690316975
continue;
1690416976
}
1690516977
1690616978
if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
16907
-
16979
+
1690816980
Jim_Obj *resultObj;
1690916981
1691016982
if (opt_bool) {
1691116983
resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
1691216984
}
@@ -16929,11 +17001,11 @@
1692917001
1693017002
if (opt_all) {
1693117003
Jim_SetResult(interp, listObjPtr);
1693217004
}
1693317005
else {
16934
-
17006
+
1693517007
if (opt_bool) {
1693617008
Jim_SetResultBool(interp, opt_not);
1693717009
}
1693817010
else if (!opt_inline) {
1693917011
Jim_SetResultInt(interp, -1);
@@ -16958,11 +17030,11 @@
1695817030
Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
1695917031
return JIM_ERR;
1696017032
}
1696117033
listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1696217034
if (!listObjPtr) {
16963
-
17035
+
1696417036
listObjPtr = Jim_NewListObj(interp, NULL, 0);
1696517037
new_obj = 1;
1696617038
}
1696717039
else if (Jim_IsShared(listObjPtr)) {
1696817040
listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
@@ -17031,31 +17103,31 @@
1703117103
first = JimRelToAbsIndex(len, first);
1703217104
last = JimRelToAbsIndex(len, last);
1703317105
JimRelToAbsRange(len, &first, &last, &rangeLen);
1703417106
1703517107
17036
-
17108
+
1703717109
if (first < len) {
17038
-
17110
+
1703917111
}
1704017112
else if (len == 0) {
17041
-
17113
+
1704217114
first = 0;
1704317115
}
1704417116
else {
1704517117
Jim_SetResultString(interp, "list doesn't contain element ", -1);
1704617118
Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
1704717119
return JIM_ERR;
1704817120
}
1704917121
17050
-
17122
+
1705117123
newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
1705217124
17053
-
17125
+
1705417126
ListInsertElements(newListObj, -1, argc - 4, argv + 4);
1705517127
17056
-
17128
+
1705717129
ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
1705817130
1705917131
Jim_SetResult(interp, newListObj);
1706017132
return JIM_OK;
1706117133
}
@@ -17066,11 +17138,11 @@
1706617138
if (argc < 3) {
1706717139
Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
1706817140
return JIM_ERR;
1706917141
}
1707017142
else if (argc == 3) {
17071
-
17143
+
1707217144
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
1707317145
return JIM_ERR;
1707417146
Jim_SetResult(interp, argv[2]);
1707517147
return JIM_OK;
1707617148
}
@@ -17181,11 +17253,11 @@
1718117253
}
1718217254
else {
1718317255
int new_obj = 0;
1718417256
stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1718517257
if (!stringObjPtr) {
17186
-
17258
+
1718717259
stringObjPtr = Jim_NewEmptyStringObj(interp);
1718817260
new_obj = 1;
1718917261
}
1719017262
else if (Jim_IsShared(stringObjPtr)) {
1719117263
new_obj = 1;
@@ -17230,11 +17302,11 @@
1723017302
else {
1723117303
rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
1723217304
}
1723317305
1723417306
if (rc == JIM_ERR) {
17235
-
17307
+
1723617308
interp->addStackTrace++;
1723717309
}
1723817310
return rc;
1723917311
}
1724017312
@@ -17244,14 +17316,14 @@
1724417316
if (argc >= 2) {
1724517317
int retcode;
1724617318
Jim_CallFrame *savedCallFrame, *targetCallFrame;
1724717319
const char *str;
1724817320
17249
-
17321
+
1725017322
savedCallFrame = interp->framePtr;
1725117323
17252
-
17324
+
1725317325
str = Jim_String(argv[1]);
1725417326
if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
1725517327
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
1725617328
argc--;
1725717329
argv++;
@@ -17264,11 +17336,11 @@
1726417336
}
1726517337
if (argc < 2) {
1726617338
Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
1726717339
return JIM_ERR;
1726817340
}
17269
-
17341
+
1727017342
interp->framePtr = targetCallFrame;
1727117343
if (argc == 2) {
1727217344
retcode = Jim_EvalObj(interp, argv[1]);
1727317345
}
1727417346
else {
@@ -17366,15 +17438,15 @@
1736617438
if (i != argc - 1 && i != argc) {
1736717439
Jim_WrongNumArgs(interp, 1, argv,
1736817440
"?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
1736917441
}
1737017442
17371
-
17443
+
1737217444
if (stackTraceObj && returnCode == JIM_ERR) {
1737317445
JimSetStackTrace(interp, stackTraceObj);
1737417446
}
17375
-
17447
+
1737617448
if (errorCodeObj && returnCode == JIM_ERR) {
1737717449
Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
1737817450
}
1737917451
interp->returnCode = returnCode;
1738017452
interp->returnLevel = level;
@@ -17391,31 +17463,31 @@
1739117463
if (interp->framePtr->level == 0) {
1739217464
Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
1739317465
return JIM_ERR;
1739417466
}
1739517467
else if (argc >= 2) {
17396
-
17468
+
1739717469
Jim_CallFrame *cf = interp->framePtr->parent;
1739817470
1739917471
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
1740017472
if (cmdPtr == NULL) {
1740117473
return JIM_ERR;
1740217474
}
1740317475
1740417476
JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
1740517477
17406
-
17478
+
1740717479
JimIncrCmdRefCount(cmdPtr);
1740817480
cf->tailcallCmd = cmdPtr;
1740917481
17410
-
17482
+
1741117483
JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
1741217484
1741317485
cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
1741417486
Jim_IncrRefCount(cf->tailcallObj);
1741517487
17416
-
17488
+
1741717489
return JIM_EVAL;
1741817490
}
1741917491
return JIM_OK;
1742017492
}
1742117493
@@ -17422,11 +17494,11 @@
1742217494
static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1742317495
{
1742417496
Jim_Obj *cmdList;
1742517497
Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
1742617498
17427
-
17499
+
1742817500
cmdList = Jim_DuplicateObj(interp, prefixListObj);
1742917501
Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
1743017502
1743117503
return JimEvalObjList(interp, cmdList);
1743217504
}
@@ -17480,22 +17552,22 @@
1748017552
else {
1748117553
cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
1748217554
}
1748317555
1748417556
if (cmd) {
17485
-
17557
+
1748617558
Jim_Obj *qualifiedCmdNameObj;
1748717559
const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
1748817560
1748917561
JimCreateCommand(interp, cmdname, cmd);
1749017562
17491
-
17563
+
1749217564
JimUpdateProcNamespace(interp, cmd, cmdname);
1749317565
1749417566
JimFreeQualifiedName(interp, qualifiedCmdNameObj);
1749517567
17496
-
17568
+
1749717569
Jim_SetResult(interp, argv[1]);
1749817570
return JIM_OK;
1749917571
}
1750017572
return JIM_ERR;
1750117573
}
@@ -17508,17 +17580,17 @@
1750817580
if (argc < 2) {
1750917581
Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
1751017582
return JIM_ERR;
1751117583
}
1751217584
17513
-
17585
+
1751417586
interp->local++;
1751517587
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
1751617588
interp->local--;
1751717589
1751817590
17519
-
17591
+
1752017592
if (retcode == 0) {
1752117593
Jim_Obj *cmdNameObj = Jim_GetResult(interp);
1752217594
1752317595
if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
1752417596
return JIM_ERR;
@@ -17547,18 +17619,18 @@
1754717619
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
1754817620
if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
1754917621
Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
1755017622
return JIM_ERR;
1755117623
}
17552
-
17624
+
1755317625
cmdPtr->u.proc.upcall++;
1755417626
JimIncrCmdRefCount(cmdPtr);
1755517627
17556
-
17628
+
1755717629
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
1755817630
17559
-
17631
+
1756017632
cmdPtr->u.proc.upcall--;
1756117633
JimDecrCmdRefCount(interp, cmdPtr);
1756217634
1756317635
return retcode;
1756417636
}
@@ -17585,11 +17657,11 @@
1758517657
return JIM_ERR;
1758617658
}
1758717659
1758817660
if (len == 3) {
1758917661
#ifdef jim_ext_namespace
17590
-
17662
+
1759117663
nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
1759217664
#else
1759317665
Jim_SetResultString(interp, "namespaces not enabled", -1);
1759417666
return JIM_ERR;
1759517667
#endif
@@ -17598,11 +17670,11 @@
1759817670
bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
1759917671
1760017672
cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
1760117673
1760217674
if (cmd) {
17603
-
17675
+
1760417676
nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
1760517677
nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
1760617678
Jim_IncrRefCount(nargv[0]);
1760717679
memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
1760817680
ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17628,11 +17700,11 @@
1762817700
static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1762917701
{
1763017702
int i;
1763117703
Jim_CallFrame *targetCallFrame;
1763217704
17633
-
17705
+
1763417706
if (argc > 3 && (argc % 2 == 0)) {
1763517707
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
1763617708
argc--;
1763717709
argv++;
1763817710
}
@@ -17641,17 +17713,17 @@
1764117713
}
1764217714
if (targetCallFrame == NULL) {
1764317715
return JIM_ERR;
1764417716
}
1764517717
17646
-
17718
+
1764717719
if (argc < 3) {
1764817720
Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
1764917721
return JIM_ERR;
1765017722
}
1765117723
17652
-
17724
+
1765317725
for (i = 1; i < argc; i += 2) {
1765417726
if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
1765517727
return JIM_ERR;
1765617728
}
1765717729
return JIM_OK;
@@ -17664,15 +17736,15 @@
1766417736
1766517737
if (argc < 2) {
1766617738
Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
1766717739
return JIM_ERR;
1766817740
}
17669
-
17741
+
1767017742
if (interp->framePtr->level == 0)
17671
- return JIM_OK;
17743
+ return JIM_OK;
1767217744
for (i = 1; i < argc; i++) {
17673
-
17745
+
1767417746
const char *name = Jim_String(argv[i]);
1767517747
if (name[0] != ':' || name[1] != ':') {
1767617748
if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
1767717749
return JIM_ERR;
1767817750
}
@@ -17695,21 +17767,21 @@
1769517767
}
1769617768
1769717769
str = Jim_String(objPtr);
1769817770
strLen = Jim_Utf8Length(interp, objPtr);
1769917771
17700
-
17772
+
1770117773
resultObjPtr = Jim_NewStringObj(interp, "", 0);
1770217774
while (strLen) {
1770317775
for (i = 0; i < numMaps; i += 2) {
17704
- Jim_Obj *eachObjPtr;
17776
+ Jim_Obj *objPtr;
1770517777
const char *k;
1770617778
int kl;
1770717779
17708
- eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17709
- k = Jim_String(eachObjPtr);
17710
- kl = Jim_Utf8Length(interp, eachObjPtr);
17780
+ objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17781
+ k = Jim_String(objPtr);
17782
+ kl = Jim_Utf8Length(interp, objPtr);
1771117783
1771217784
if (strLen >= kl && kl) {
1771317785
int rc;
1771417786
rc = JimStringCompareLen(str, k, kl, nocase);
1771517787
if (rc == 0) {
@@ -17722,11 +17794,11 @@
1772217794
strLen -= kl;
1772317795
break;
1772417796
}
1772517797
}
1772617798
}
17727
- if (i == numMaps) {
17799
+ if (i == numMaps) {
1772817800
int c;
1772917801
if (noMatchStart == NULL)
1773017802
noMatchStart = str;
1773117803
str += utf8_tounicode(str, &c);
1773217804
strLen--;
@@ -17787,11 +17859,11 @@
1778717859
return JIM_OK;
1778817860
1778917861
case OPT_CAT:{
1779017862
Jim_Obj *objPtr;
1779117863
if (argc == 3) {
17792
-
17864
+
1779317865
objPtr = argv[2];
1779417866
}
1779517867
else {
1779617868
int i;
1779717869
@@ -17806,11 +17878,11 @@
1780617878
}
1780717879
1780817880
case OPT_COMPARE:
1780917881
case OPT_EQUAL:
1781017882
{
17811
-
17883
+
1781217884
long opt_length = -1;
1781317885
int n = argc - 4;
1781417886
int i = 2;
1781517887
while (n > 0) {
1781617888
int subopt;
@@ -17819,16 +17891,16 @@
1781917891
badcompareargs:
1782017892
Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
1782117893
return JIM_ERR;
1782217894
}
1782317895
if (subopt == 0) {
17824
-
17896
+
1782517897
opt_case = 0;
1782617898
n--;
1782717899
}
1782817900
else {
17829
-
17901
+
1783017902
if (n < 2) {
1783117903
goto badcompareargs;
1783217904
}
1783317905
if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
1783417906
return JIM_ERR;
@@ -17839,11 +17911,11 @@
1783917911
if (n) {
1784017912
goto badcompareargs;
1784117913
}
1784217914
argv += argc - 2;
1784317915
if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17844
-
17916
+
1784517917
Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
1784617918
}
1784717919
else {
1784817920
if (opt_length >= 0) {
1784917921
n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -17953,10 +18025,11 @@
1795318025
}
1795418026
1795518027
case OPT_REVERSE:{
1795618028
char *buf, *p;
1795718029
const char *str;
18030
+ int len;
1795818031
int i;
1795918032
1796018033
if (argc != 3) {
1796118034
Jim_WrongNumArgs(interp, 2, argv, "string");
1796218035
return JIM_ERR;
@@ -17996,11 +18069,11 @@
1799618069
}
1799718070
if (idx < 0 || idx >= len || str == NULL) {
1799818071
Jim_SetResultString(interp, "", 0);
1799918072
}
1800018073
else if (len == Jim_Length(argv[2])) {
18001
-
18074
+
1800218075
Jim_SetResultString(interp, str + idx, 1);
1800318076
}
1800418077
else {
1800518078
int c;
1800618079
int i = utf8_index(str, idx);
@@ -18150,11 +18223,11 @@
1815018223
{
1815118224
int exitCode = 0;
1815218225
int i;
1815318226
int sig = 0;
1815418227
18155
-
18228
+
1815618229
jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
1815718230
static const int max_ignore_code = sizeof(ignore_mask) * 8;
1815818231
1815918232
Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
1816018233
@@ -18161,11 +18234,11 @@
1816118234
for (i = 1; i < argc - 1; i++) {
1816218235
const char *arg = Jim_String(argv[i]);
1816318236
jim_wide option;
1816418237
int ignore;
1816518238
18166
-
18239
+
1816718240
if (strcmp(arg, "--") == 0) {
1816818241
i++;
1816918242
break;
1817018243
}
1817118244
if (*arg != '-') {
@@ -18212,28 +18285,28 @@
1821218285
sig++;
1821318286
}
1821418287
1821518288
interp->signal_level += sig;
1821618289
if (Jim_CheckSignal(interp)) {
18217
-
18290
+
1821818291
exitCode = JIM_SIGNAL;
1821918292
}
1822018293
else {
1822118294
exitCode = Jim_EvalObj(interp, argv[0]);
18222
-
18295
+
1822318296
interp->errorFlag = 0;
1822418297
}
1822518298
interp->signal_level -= sig;
1822618299
18227
-
18300
+
1822818301
if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
18229
-
18302
+
1823018303
return exitCode;
1823118304
}
1823218305
1823318306
if (sig && exitCode == JIM_SIGNAL) {
18234
-
18307
+
1823518308
if (interp->signal_set_result) {
1823618309
interp->signal_set_result(interp, interp->sigmask);
1823718310
}
1823818311
else {
1823918312
Jim_SetResultInt(interp, interp->sigmask);
@@ -18272,10 +18345,125 @@
1827218345
}
1827318346
Jim_SetResultInt(interp, exitCode);
1827418347
return JIM_OK;
1827518348
}
1827618349
18350
+#ifdef JIM_REFERENCES
18351
+
18352
+
18353
+static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18354
+{
18355
+ if (argc != 3 && argc != 4) {
18356
+ Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?");
18357
+ return JIM_ERR;
18358
+ }
18359
+ if (argc == 3) {
18360
+ Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL));
18361
+ }
18362
+ else {
18363
+ Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3]));
18364
+ }
18365
+ return JIM_OK;
18366
+}
18367
+
18368
+
18369
+static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18370
+{
18371
+ Jim_Reference *refPtr;
18372
+
18373
+ if (argc != 2) {
18374
+ Jim_WrongNumArgs(interp, 1, argv, "reference");
18375
+ return JIM_ERR;
18376
+ }
18377
+ if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18378
+ return JIM_ERR;
18379
+ Jim_SetResult(interp, refPtr->objPtr);
18380
+ return JIM_OK;
18381
+}
18382
+
18383
+
18384
+static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18385
+{
18386
+ Jim_Reference *refPtr;
18387
+
18388
+ if (argc != 3) {
18389
+ Jim_WrongNumArgs(interp, 1, argv, "reference newValue");
18390
+ return JIM_ERR;
18391
+ }
18392
+ if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18393
+ return JIM_ERR;
18394
+ Jim_IncrRefCount(argv[2]);
18395
+ Jim_DecrRefCount(interp, refPtr->objPtr);
18396
+ refPtr->objPtr = argv[2];
18397
+ Jim_SetResult(interp, argv[2]);
18398
+ return JIM_OK;
18399
+}
18400
+
18401
+
18402
+static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18403
+{
18404
+ if (argc != 1) {
18405
+ Jim_WrongNumArgs(interp, 1, argv, "");
18406
+ return JIM_ERR;
18407
+ }
18408
+ Jim_SetResultInt(interp, Jim_Collect(interp));
18409
+
18410
+
18411
+ while (interp->freeList) {
18412
+ Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr;
18413
+ Jim_Free(interp->freeList);
18414
+ interp->freeList = nextObjPtr;
18415
+ }
18416
+
18417
+ return JIM_OK;
18418
+}
18419
+
18420
+
18421
+static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18422
+{
18423
+ if (argc != 2 && argc != 3) {
18424
+ Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?");
18425
+ return JIM_ERR;
18426
+ }
18427
+ if (argc == 2) {
18428
+ Jim_Obj *cmdNamePtr;
18429
+
18430
+ if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK)
18431
+ return JIM_ERR;
18432
+ if (cmdNamePtr != NULL)
18433
+ Jim_SetResult(interp, cmdNamePtr);
18434
+ }
18435
+ else {
18436
+ if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK)
18437
+ return JIM_ERR;
18438
+ Jim_SetResult(interp, argv[2]);
18439
+ }
18440
+ return JIM_OK;
18441
+}
18442
+
18443
+
18444
+static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18445
+{
18446
+ Jim_Obj *listObjPtr;
18447
+ Jim_HashTableIterator htiter;
18448
+ Jim_HashEntry *he;
18449
+
18450
+ listObjPtr = Jim_NewListObj(interp, NULL, 0);
18451
+
18452
+ JimInitHashTableIterator(&interp->references, &htiter);
18453
+ while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18454
+ char buf[JIM_REFERENCE_SPACE + 1];
18455
+ Jim_Reference *refPtr = Jim_GetHashEntryVal(he);
18456
+ const unsigned long *refId = he->key;
18457
+
18458
+ JimFormatReference(buf, refPtr, *refId);
18459
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
18460
+ }
18461
+ Jim_SetResult(interp, listObjPtr);
18462
+ return JIM_OK;
18463
+}
18464
+#endif
1827718465
1827818466
1827918467
static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1828018468
{
1828118469
if (argc != 3) {
@@ -18306,11 +18494,11 @@
1830618494
JimDictMatchCallbackType *callback, int type)
1830718495
{
1830818496
Jim_HashEntry *he;
1830918497
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
1831018498
18311
-
18499
+
1831218500
Jim_HashTableIterator htiter;
1831318501
JimInitHashTableIterator(ht, &htiter);
1831418502
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1831518503
if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
1831618504
callback(interp, listObjPtr, he, type);
@@ -18356,11 +18544,11 @@
1835618544
return JIM_ERR;
1835718545
}
1835818546
1835918547
ht = (Jim_HashTable *)objPtr->internalRep.ptr;
1836018548
18361
-
18549
+
1836218550
printf("%d entries in table, %d buckets\n", ht->used, ht->size);
1836318551
1836418552
for (i = 0; i < ht->size; i++) {
1836518553
Jim_HashEntry *he = ht->table[i];
1836618554
@@ -18480,16 +18668,16 @@
1848018668
return JIM_OK;
1848118669
}
1848218670
if (Jim_DictSize(interp, argv[2]) < 0) {
1848318671
return JIM_ERR;
1848418672
}
18485
-
18673
+
1848618674
break;
1848718675
1848818676
case OPT_UPDATE:
1848918677
if (argc < 6 || argc % 2) {
18490
-
18678
+
1849118679
argc = 2;
1849218680
}
1849318681
break;
1849418682
1849518683
case OPT_CREATE:
@@ -18506,11 +18694,11 @@
1850618694
Jim_WrongNumArgs(interp, 2, argv, "dictionary");
1850718695
return JIM_ERR;
1850818696
}
1850918697
return Jim_DictInfo(interp, argv[2]);
1851018698
}
18511
-
18699
+
1851218700
return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
1851318701
}
1851418702
1851518703
1851618704
static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18576,11 +18764,11 @@
1857618764
1857718765
#ifdef jim_ext_namespace
1857818766
int nons = 0;
1857918767
1858018768
if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18581
-
18769
+
1858218770
argc--;
1858318771
argv++;
1858418772
nons = 1;
1858518773
}
1858618774
#endif
@@ -18592,11 +18780,11 @@
1859218780
if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
1859318781
!= JIM_OK) {
1859418782
return JIM_ERR;
1859518783
}
1859618784
18597
-
18785
+
1859818786
switch (cmd) {
1859918787
case INFO_EXISTS:
1860018788
if (argc != 3) {
1860118789
Jim_WrongNumArgs(interp, 2, argv, "varName");
1860218790
return JIM_ERR;
@@ -18621,21 +18809,21 @@
1862118809
Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
1862218810
return JIM_OK;
1862318811
}
1862418812
1862518813
case INFO_CHANNELS:
18626
- mode++;
18814
+ mode++;
1862718815
#ifndef jim_ext_aio
1862818816
Jim_SetResultString(interp, "aio not enabled", -1);
1862918817
return JIM_ERR;
1863018818
#endif
18631
-
18819
+
1863218820
case INFO_PROCS:
18633
- mode++;
18634
-
18821
+ mode++;
18822
+
1863518823
case INFO_COMMANDS:
18636
-
18824
+
1863718825
if (argc != 2 && argc != 3) {
1863818826
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
1863918827
return JIM_ERR;
1864018828
}
1864118829
#ifdef jim_ext_namespace
@@ -18647,17 +18835,17 @@
1864718835
#endif
1864818836
Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
1864918837
break;
1865018838
1865118839
case INFO_VARS:
18652
- mode++;
18653
-
18840
+ mode++;
18841
+
1865418842
case INFO_LOCALS:
18655
- mode++;
18656
-
18843
+ mode++;
18844
+
1865718845
case INFO_GLOBALS:
18658
-
18846
+
1865918847
if (argc != 2 && argc != 3) {
1866018848
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
1866118849
return JIM_ERR;
1866218850
}
1866318851
#ifdef jim_ext_namespace
@@ -18763,12 +18951,13 @@
1876318951
case INFO_ARGS:
1876418952
Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
1876518953
break;
1876618954
case INFO_STATICS:
1876718955
if (cmdPtr->u.proc.staticVars) {
18956
+ int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
1876818957
Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
18769
- NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES));
18958
+ NULL, JimVariablesMatch, mode));
1877018959
}
1877118960
break;
1877218961
}
1877318962
break;
1877418963
}
@@ -18796,15 +18985,15 @@
1879618985
}
1879718986
}
1879818987
break;
1879918988
1880018989
case INFO_HOSTNAME:
18801
-
18990
+
1880218991
return Jim_Eval(interp, "os.gethostname");
1880318992
1880418993
case INFO_NAMEOFEXECUTABLE:
18805
-
18994
+
1880618995
return Jim_Eval(interp, "{info nameofexecutable}");
1880718996
1880818997
case INFO_RETURNCODES:
1880918998
if (argc == 2) {
1881018999
int i;
@@ -18881,11 +19070,11 @@
1888119070
1888219071
if (option == OPT_VAR) {
1888319072
result = Jim_GetVariable(interp, objPtr, 0) != NULL;
1888419073
}
1888519074
else {
18886
-
19075
+
1888719076
Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
1888819077
1888919078
if (cmd) {
1889019079
switch (option) {
1889119080
case OPT_COMMAND:
@@ -18924,11 +19113,11 @@
1892419113
if (len == 0) {
1892519114
return JIM_OK;
1892619115
}
1892719116
strLen = Jim_Utf8Length(interp, argv[1]);
1892819117
18929
-
19118
+
1893019119
if (argc == 2) {
1893119120
splitChars = " \n\t\r";
1893219121
splitLen = 4;
1893319122
}
1893419123
else {
@@ -18937,11 +19126,11 @@
1893719126
}
1893819127
1893919128
noMatchStart = str;
1894019129
resObjPtr = Jim_NewListObj(interp, NULL, 0);
1894119130
18942
-
19131
+
1894319132
if (splitLen) {
1894419133
Jim_Obj *objPtr;
1894519134
while (strLen--) {
1894619135
const char *sc = splitChars;
1894719136
int scLen = splitLen;
@@ -18966,11 +19155,11 @@
1896619155
#define NUM_COMMON (128 - 9)
1896719156
while (strLen--) {
1896819157
int n = utf8_tounicode(str, &c);
1896919158
#ifdef JIM_OPTIMIZATION
1897019159
if (c >= 9 && c < 128) {
18971
-
19160
+
1897219161
c -= 9;
1897319162
if (!commonObj) {
1897419163
commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
1897519164
memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
1897619165
}
@@ -19000,11 +19189,11 @@
1900019189
1900119190
if (argc != 2 && argc != 3) {
1900219191
Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
1900319192
return JIM_ERR;
1900419193
}
19005
-
19194
+
1900619195
if (argc == 2) {
1900719196
joinStr = " ";
1900819197
joinStrLen = 1;
1900919198
}
1901019199
else {
@@ -19279,13 +19468,13 @@
1927919468
return -1;
1928019469
else if (step < 0 && end > start)
1928119470
return -1;
1928219471
len = end - start;
1928319472
if (len < 0)
19284
- len = -len;
19473
+ len = -len;
1928519474
if (step < 0)
19286
- step = -step;
19475
+ step = -step;
1928719476
len = 1 + ((len - 1) / step);
1928819477
if (len > INT_MAX)
1928919478
len = INT_MAX;
1929019479
return (int)((len < 0) ? -1 : len);
1929119480
}
@@ -19499,11 +19688,11 @@
1949919688
1950019689
*indexPtr = -1;
1950119690
1950219691
for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
1950319692
if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
19504
-
19693
+
1950519694
*indexPtr = i;
1950619695
return JIM_OK;
1950719696
}
1950819697
if (flags & JIM_ENUM_ABBREV) {
1950919698
if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19517,11 +19706,11 @@
1951719706
match = i;
1951819707
}
1951919708
}
1952019709
}
1952119710
19522
-
19711
+
1952319712
if (match >= 0) {
1952419713
*indexPtr = match;
1952519714
return JIM_OK;
1952619715
}
1952719716
@@ -19554,11 +19743,11 @@
1955419743
return objPtr->typePtr == &listObjType;
1955519744
}
1955619745
1955719746
void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
1955819747
{
19559
-
19748
+
1956019749
int len = strlen(format);
1956119750
int extra = 0;
1956219751
int n = 0;
1956319752
const char *params[5];
1956419753
char *buf;
@@ -19619,11 +19808,11 @@
1961919808
#include <string.h>
1962019809
1962119810
1962219811
static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1962319812
{
19624
-
19813
+
1962519814
return JIM_OK;
1962619815
}
1962719816
1962819817
static const jim_subcmd_type dummy_subcmd = {
1962919818
"dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19698,43 +19887,43 @@
1969819887
return 0;
1969919888
}
1970019889
1970119890
cmd = argv[1];
1970219891
19703
-
19892
+
1970419893
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
1970519894
if (argc == 2) {
19706
-
19895
+
1970719896
show_cmd_usage(interp, command_table, argc, argv);
1970819897
return &dummy_subcmd;
1970919898
}
1971019899
help = 1;
1971119900
19712
-
19901
+
1971319902
cmd = argv[2];
1971419903
}
1971519904
19716
-
19905
+
1971719906
if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
19718
-
19907
+
1971919908
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
1972019909
add_commands(interp, command_table, " ");
1972119910
return &dummy_subcmd;
1972219911
}
1972319912
1972419913
cmdstr = Jim_GetString(cmd, &cmdlen);
1972519914
1972619915
for (ct = command_table; ct->cmd; ct++) {
1972719916
if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
19728
-
19917
+
1972919918
break;
1973019919
}
1973119920
if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
1973219921
if (partial) {
19733
-
19922
+
1973419923
if (help) {
19735
-
19924
+
1973619925
show_cmd_usage(interp, command_table, argc, argv);
1973719926
return &dummy_subcmd;
1973819927
}
1973919928
bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
1974019929
return 0;
@@ -19742,44 +19931,44 @@
1974219931
partial = ct;
1974319932
}
1974419933
continue;
1974519934
}
1974619935
19747
-
19936
+
1974819937
if (partial && !ct->cmd) {
1974919938
ct = partial;
1975019939
}
1975119940
1975219941
if (!ct->cmd) {
19753
-
19942
+
1975419943
if (help) {
19755
-
19944
+
1975619945
show_cmd_usage(interp, command_table, argc, argv);
1975719946
return &dummy_subcmd;
1975819947
}
1975919948
bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
1976019949
return 0;
1976119950
}
1976219951
1976319952
if (help) {
1976419953
Jim_SetResultString(interp, "Usage: ", -1);
19765
-
19954
+
1976619955
add_cmd_usage(interp, ct, argv[0]);
1976719956
return &dummy_subcmd;
1976819957
}
1976919958
19770
-
19959
+
1977119960
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
1977219961
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
19773
-
19962
+
1977419963
add_cmd_usage(interp, ct, argv[0]);
1977519964
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
1977619965
1977719966
return 0;
1977819967
}
1977919968
19780
-
19969
+
1978119970
return ct;
1978219971
}
1978319972
1978419973
int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
1978519974
{
@@ -19830,11 +20019,11 @@
1983020019
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
1983120020
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
1983220021
*p = 0x80 | (uc & 0x3f);
1983320022
return 3;
1983420023
}
19835
-
20024
+
1983620025
else {
1983720026
*p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
1983820027
*p++ = 0x80 | ((uc & 0x3f000) >> 12);
1983920028
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
1984020029
*p = 0x80 | (uc & 0x3f);
@@ -20021,11 +20210,11 @@
2002120210
if (ch == 'h') {
2002220211
useShort = 1;
2002320212
format += step;
2002420213
step = utf8_tounicode(format, &ch);
2002520214
} else if (ch == 'l') {
20026
-
20215
+
2002720216
format += step;
2002820217
step = utf8_tounicode(format, &ch);
2002920218
if (ch == 'l') {
2003020219
format += step;
2003120220
step = utf8_tounicode(format, &ch);
@@ -20048,11 +20237,11 @@
2004820237
goto errorMsg;
2004920238
case 's': {
2005020239
formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
2005120240
formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
2005220241
if (gotPrecision && (precision < formatted_chars)) {
20053
-
20242
+
2005420243
formatted_chars = precision;
2005520244
formatted_bytes = utf8_index(formatted_buf, precision);
2005620245
}
2005720246
break;
2005820247
}
@@ -20060,11 +20249,11 @@
2006020249
jim_wide code;
2006120250
2006220251
if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
2006320252
goto error;
2006420253
}
20065
-
20254
+
2006620255
formatted_bytes = utf8_getchars(spec, code);
2006720256
formatted_buf = spec;
2006820257
formatted_chars = 1;
2006920258
break;
2007020259
}
@@ -20078,11 +20267,11 @@
2007820267
goto error;
2007920268
}
2008020269
length = sizeof(w) * 8;
2008120270
2008220271
20083
-
20272
+
2008420273
if (num_buffer_size < length + 1) {
2008520274
num_buffer_size = length + 1;
2008620275
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
2008720276
}
2008820277
@@ -20106,29 +20295,29 @@
2010620295
case 'E':
2010720296
case 'f':
2010820297
case 'g':
2010920298
case 'G':
2011020299
doubleType = 1;
20111
-
20300
+
2011220301
case 'd':
2011320302
case 'u':
2011420303
case 'o':
2011520304
case 'x':
2011620305
case 'X': {
2011720306
jim_wide w;
2011820307
double d;
2011920308
int length;
2012020309
20121
-
20310
+
2012220311
if (width) {
2012320312
p += sprintf(p, "%ld", width);
2012420313
}
2012520314
if (gotPrecision) {
2012620315
p += sprintf(p, ".%ld", precision);
2012720316
}
2012820317
20129
-
20318
+
2013020319
if (doubleType) {
2013120320
if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
2013220321
goto error;
2013320322
}
2013420323
length = MAX_FLOAT_WIDTH;
@@ -20155,19 +20344,19 @@
2015520344
}
2015620345
2015720346
*p++ = (char) ch;
2015820347
*p = '\0';
2015920348
20160
-
20349
+
2016120350
if (width > length) {
2016220351
length = width;
2016320352
}
2016420353
if (gotPrecision) {
2016520354
length += precision;
2016620355
}
2016720356
20168
-
20357
+
2016920358
if (num_buffer_size < length + 1) {
2017020359
num_buffer_size = length + 1;
2017120360
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
2017220361
}
2017320362
@@ -20181,11 +20370,11 @@
2018120370
formatted_buf = num_buffer;
2018220371
break;
2018320372
}
2018420373
2018520374
default: {
20186
-
20375
+
2018720376
spec[0] = ch;
2018820377
spec[1] = '\0';
2018920378
Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
2019020379
goto error;
2019120380
}
@@ -20233,37 +20422,37 @@
2023320422
2023420423
#define REG_MAX_PAREN 100
2023520424
2023620425
2023720426
20238
-#define END 0
20239
-#define BOL 1
20240
-#define EOL 2
20241
-#define ANY 3
20242
-#define ANYOF 4
20243
-#define ANYBUT 5
20244
-#define BRANCH 6
20245
-#define BACK 7
20246
-#define EXACTLY 8
20247
-#define NOTHING 9
20248
-#define REP 10
20249
-#define REPMIN 11
20250
-#define REPX 12
20251
-#define REPXMIN 13
20252
-#define BOLX 14
20253
-#define EOLX 15
20254
-#define WORDA 16
20255
-#define WORDZ 17
20256
-
20257
-#define OPENNC 1000
20258
-#define OPEN 1001
20259
-
20260
-
20261
-
20262
-
20263
-#define CLOSENC 2000
20264
-#define CLOSE 2001
20427
+#define END 0
20428
+#define BOL 1
20429
+#define EOL 2
20430
+#define ANY 3
20431
+#define ANYOF 4
20432
+#define ANYBUT 5
20433
+#define BRANCH 6
20434
+#define BACK 7
20435
+#define EXACTLY 8
20436
+#define NOTHING 9
20437
+#define REP 10
20438
+#define REPMIN 11
20439
+#define REPX 12
20440
+#define REPXMIN 13
20441
+#define BOLX 14
20442
+#define EOLX 15
20443
+#define WORDA 16
20444
+#define WORDZ 17
20445
+
20446
+#define OPENNC 1000
20447
+#define OPEN 1001
20448
+
20449
+
20450
+
20451
+
20452
+#define CLOSENC 2000
20453
+#define CLOSE 2001
2026520454
#define CLOSE_END (CLOSE+REG_MAX_PAREN)
2026620455
2026720456
#define REG_MAGIC 0xFADED00D
2026820457
2026920458
@@ -20276,18 +20465,18 @@
2027620465
2027720466
#define FAIL(R,M) { (R)->err = (M); return (M); }
2027820467
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
2027920468
#define META "^$.[()|?{+*"
2028020469
20281
-#define HASWIDTH 1
20282
-#define SIMPLE 2
20283
-#define SPSTART 4
20284
-#define WORST 0
20470
+#define HASWIDTH 1
20471
+#define SIMPLE 2
20472
+#define SPSTART 4
20473
+#define WORST 0
2028520474
2028620475
#define MAX_REP_COUNT 1000000
2028720476
20288
-static int reg(regex_t *preg, int paren, int *flagp );
20477
+static int reg(regex_t *preg, int paren , int *flagp );
2028920478
static int regpiece(regex_t *preg, int *flagp );
2029020479
static int regbranch(regex_t *preg, int *flagp );
2029120480
static int regatom(regex_t *preg, int *flagp );
2029220481
static int regnode(regex_t *preg, int op );
2029320482
static int regnext(regex_t *preg, int p );
@@ -20331,15 +20520,15 @@
2033120520
memset(preg, 0, sizeof(*preg));
2033220521
2033320522
if (exp == NULL)
2033420523
FAIL(preg, REG_ERR_NULL_ARGUMENT);
2033520524
20336
-
20525
+
2033720526
preg->cflags = cflags;
2033820527
preg->regparse = exp;
2033920528
20340
-
20529
+
2034120530
preg->proglen = (strlen(exp) + 1) * 5;
2034220531
preg->program = malloc(preg->proglen * sizeof(int));
2034320532
if (preg->program == NULL)
2034420533
FAIL(preg, REG_ERR_NOMEM);
2034520534
@@ -20346,24 +20535,24 @@
2034620535
regc(preg, REG_MAGIC);
2034720536
if (reg(preg, 0, &flags) == 0) {
2034820537
return preg->err;
2034920538
}
2035020539
20351
-
20352
- if (preg->re_nsub >= REG_MAX_PAREN)
20540
+
20541
+ if (preg->re_nsub >= REG_MAX_PAREN)
2035320542
FAIL(preg,REG_ERR_TOO_BIG);
2035420543
20355
-
20356
- preg->regstart = 0;
20544
+
20545
+ preg->regstart = 0;
2035720546
preg->reganch = 0;
2035820547
preg->regmust = 0;
2035920548
preg->regmlen = 0;
20360
- scan = 1;
20361
- if (OP(preg, regnext(preg, scan)) == END) {
20549
+ scan = 1;
20550
+ if (OP(preg, regnext(preg, scan)) == END) {
2036220551
scan = OPERAND(scan);
2036320552
20364
-
20553
+
2036520554
if (OP(preg, scan) == EXACTLY) {
2036620555
preg->regstart = preg->program[OPERAND(scan)];
2036720556
}
2036820557
else if (OP(preg, scan) == BOL)
2036920558
preg->reganch++;
@@ -20390,24 +20579,24 @@
2039020579
#endif
2039120580
2039220581
return 0;
2039320582
}
2039420583
20395
-static int reg(regex_t *preg, int paren, int *flagp )
20584
+static int reg(regex_t *preg, int paren , int *flagp )
2039620585
{
2039720586
int ret;
2039820587
int br;
2039920588
int ender;
2040020589
int parno = 0;
2040120590
int flags;
2040220591
20403
- *flagp = HASWIDTH;
20592
+ *flagp = HASWIDTH;
2040420593
20405
-
20594
+
2040620595
if (paren) {
2040720596
if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
20408
-
20597
+
2040920598
preg->regparse += 2;
2041020599
parno = -1;
2041120600
}
2041220601
else {
2041320602
parno = ++preg->re_nsub;
@@ -20414,16 +20603,16 @@
2041420603
}
2041520604
ret = regnode(preg, OPEN+parno);
2041620605
} else
2041720606
ret = 0;
2041820607
20419
-
20608
+
2042020609
br = regbranch(preg, &flags);
2042120610
if (br == 0)
2042220611
return 0;
2042320612
if (ret != 0)
20424
- regtail(preg, ret, br);
20613
+ regtail(preg, ret, br);
2042520614
else
2042620615
ret = br;
2042720616
if (!(flags&HASWIDTH))
2042820617
*flagp &= ~HASWIDTH;
2042920618
*flagp |= flags&SPSTART;
@@ -20430,25 +20619,25 @@
2043020619
while (*preg->regparse == '|') {
2043120620
preg->regparse++;
2043220621
br = regbranch(preg, &flags);
2043320622
if (br == 0)
2043420623
return 0;
20435
- regtail(preg, ret, br);
20624
+ regtail(preg, ret, br);
2043620625
if (!(flags&HASWIDTH))
2043720626
*flagp &= ~HASWIDTH;
2043820627
*flagp |= flags&SPSTART;
2043920628
}
2044020629
20441
-
20630
+
2044220631
ender = regnode(preg, (paren) ? CLOSE+parno : END);
2044320632
regtail(preg, ret, ender);
2044420633
20445
-
20634
+
2044620635
for (br = ret; br != 0; br = regnext(preg, br))
2044720636
regoptail(preg, br, ender);
2044820637
20449
-
20638
+
2045020639
if (paren && *preg->regparse++ != ')') {
2045120640
preg->err = REG_ERR_UNMATCHED_PAREN;
2045220641
return 0;
2045320642
} else if (!paren && *preg->regparse != '\0') {
2045420643
if (*preg->regparse == ')') {
@@ -20468,11 +20657,11 @@
2046820657
int ret;
2046920658
int chain;
2047020659
int latest;
2047120660
int flags;
2047220661
20473
- *flagp = WORST;
20662
+ *flagp = WORST;
2047420663
2047520664
ret = regnode(preg, BRANCH);
2047620665
chain = 0;
2047720666
while (*preg->regparse != '\0' && *preg->regparse != ')' &&
2047820667
*preg->regparse != '|') {
@@ -20486,11 +20675,11 @@
2048620675
else {
2048720676
regtail(preg, chain, latest);
2048820677
}
2048920678
chain = latest;
2049020679
}
20491
- if (chain == 0)
20680
+ if (chain == 0)
2049220681
(void) regnode(preg, NOTHING);
2049320682
2049420683
return(ret);
2049520684
}
2049620685
@@ -20516,11 +20705,11 @@
2051620705
if (!(flags&HASWIDTH) && op != '?') {
2051720706
preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
2051820707
return 0;
2051920708
}
2052020709
20521
-
20710
+
2052220711
if (op == '{') {
2052320712
char *end;
2052420713
2052520714
min = strtoul(preg->regparse + 1, &end, 10);
2052620715
if (end == preg->regparse + 1) {
@@ -20588,11 +20777,11 @@
2058820777
static void reg_addrange(regex_t *preg, int lower, int upper)
2058920778
{
2059020779
if (lower > upper) {
2059120780
reg_addrange(preg, upper, lower);
2059220781
}
20593
-
20782
+
2059420783
regc(preg, upper - lower + 1);
2059520784
regc(preg, lower);
2059620785
}
2059720786
2059820787
static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20656,17 +20845,17 @@
2065620845
case 'r': *ch = '\r'; break;
2065720846
case 't': *ch = '\t'; break;
2065820847
case 'v': *ch = '\v'; break;
2065920848
case 'u':
2066020849
if (*s == '{') {
20661
-
20850
+
2066220851
n = parse_hex(s + 1, 6, ch);
2066320852
if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
2066420853
s += n + 2;
2066520854
}
2066620855
else {
20667
-
20856
+
2066820857
*ch = 'u';
2066920858
}
2067020859
}
2067120860
else if ((n = parse_hex(s, 4, ch)) > 0) {
2067220861
s += n;
@@ -20697,15 +20886,15 @@
2069720886
int nocase = (preg->cflags & REG_ICASE);
2069820887
2069920888
int ch;
2070020889
int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
2070120890
20702
- *flagp = WORST;
20891
+ *flagp = WORST;
2070320892
2070420893
preg->regparse += n;
2070520894
switch (ch) {
20706
-
20895
+
2070720896
case '^':
2070820897
ret = regnode(preg, BOL);
2070920898
break;
2071020899
case '$':
2071120900
ret = regnode(preg, EOL);
@@ -20715,24 +20904,24 @@
2071520904
*flagp |= HASWIDTH|SIMPLE;
2071620905
break;
2071720906
case '[': {
2071820907
const char *pattern = preg->regparse;
2071920908
20720
- if (*pattern == '^') {
20909
+ if (*pattern == '^') {
2072120910
ret = regnode(preg, ANYBUT);
2072220911
pattern++;
2072320912
} else
2072420913
ret = regnode(preg, ANYOF);
2072520914
20726
-
20915
+
2072720916
if (*pattern == ']' || *pattern == '-') {
2072820917
reg_addrange(preg, *pattern, *pattern);
2072920918
pattern++;
2073020919
}
2073120920
2073220921
while (*pattern && *pattern != ']') {
20733
-
20922
+
2073420923
int start;
2073520924
int end;
2073620925
2073720926
pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
2073820927
if (start == '\\') {
@@ -20741,11 +20930,11 @@
2074120930
preg->err = REG_ERR_NULL_CHAR;
2074220931
return 0;
2074320932
}
2074420933
}
2074520934
if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
20746
-
20935
+
2074720936
pattern += utf8_tounicode(pattern, &end);
2074820937
pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
2074920938
if (end == '\\') {
2075020939
pattern += reg_decode_escape(pattern, &end);
2075120940
if (end == 0) {
@@ -20768,22 +20957,22 @@
2076820957
CC_NUM
2076920958
};
2077020959
int i;
2077120960
2077220961
for (i = 0; i < CC_NUM; i++) {
20773
- n = strlen(character_class[i]);
20962
+ int n = strlen(character_class[i]);
2077420963
if (strncmp(pattern, character_class[i], n) == 0) {
20775
-
20964
+
2077620965
pattern += n + 1;
2077720966
break;
2077820967
}
2077920968
}
2078020969
if (i != CC_NUM) {
2078120970
switch (i) {
2078220971
case CC_ALNUM:
2078320972
reg_addrange(preg, '0', '9');
20784
-
20973
+
2078520974
case CC_ALPHA:
2078620975
if ((preg->cflags & REG_ICASE) == 0) {
2078720976
reg_addrange(preg, 'a', 'z');
2078820977
}
2078920978
reg_addrange(preg, 'A', 'Z');
@@ -20801,11 +20990,11 @@
2080120990
reg_addrange(preg, 'a', 'z');
2080220991
break;
2080320992
case CC_XDIGIT:
2080420993
reg_addrange(preg, 'a', 'f');
2080520994
reg_addrange(preg, 'A', 'F');
20806
-
20995
+
2080720996
case CC_DIGIT:
2080820997
reg_addrange(preg, '0', '9');
2080920998
break;
2081020999
case CC_CNTRL:
2081121000
reg_addrange(preg, 0, 31);
@@ -20825,11 +21014,11 @@
2082521014
break;
2082621015
}
2082721016
continue;
2082821017
}
2082921018
}
20830
-
21019
+
2083121020
reg_addrange(preg, start, start);
2083221021
}
2083321022
regc(preg, '\0');
2083421023
2083521024
if (*pattern) {
@@ -20848,11 +21037,11 @@
2084821037
break;
2084921038
case '\0':
2085021039
case '|':
2085121040
case ')':
2085221041
preg->err = REG_ERR_INTERNAL;
20853
- return 0;
21042
+ return 0;
2085421043
case '?':
2085521044
case '+':
2085621045
case '*':
2085721046
case '{':
2085821047
preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
@@ -20901,34 +21090,34 @@
2090121090
ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT);
2090221091
reg_addrange_str(preg," \t\r\n\f\v");
2090321092
regc(preg, '\0');
2090421093
*flagp |= HASWIDTH|SIMPLE;
2090521094
break;
20906
-
21095
+
2090721096
default:
20908
-
20909
-
21097
+
21098
+
2091021099
preg->regparse--;
2091121100
goto de_fault;
2091221101
}
2091321102
break;
2091421103
de_fault:
2091521104
default: {
2091621105
int added = 0;
2091721106
20918
-
21107
+
2091921108
preg->regparse -= n;
2092021109
2092121110
ret = regnode(preg, EXACTLY);
2092221111
2092321112
20924
-
21113
+
2092521114
while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
2092621115
n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
2092721116
if (ch == '\\' && preg->regparse[n]) {
2092821117
if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) {
20929
-
21118
+
2093021119
break;
2093121120
}
2093221121
n += reg_decode_escape(preg->regparse + n, &ch);
2093321122
if (ch == 0) {
2093421123
preg->err = REG_ERR_NULL_CHAR;
@@ -20936,23 +21125,23 @@
2093621125
}
2093721126
}
2093821127
2093921128
2094021129
if (ISMULT(preg->regparse[n])) {
20941
-
21130
+
2094221131
if (added) {
20943
-
21132
+
2094421133
break;
2094521134
}
20946
-
21135
+
2094721136
regc(preg, ch);
2094821137
added++;
2094921138
preg->regparse += n;
2095021139
break;
2095121140
}
2095221141
20953
-
21142
+
2095421143
regc(preg, ch);
2095521144
added++;
2095621145
preg->regparse += n;
2095721146
}
2095821147
regc(preg, '\0');
@@ -20979,15 +21168,15 @@
2097921168
2098021169
static int regnode(regex_t *preg, int op)
2098121170
{
2098221171
reg_grow(preg, 2);
2098321172
20984
-
21173
+
2098521174
preg->program[preg->p++] = op;
2098621175
preg->program[preg->p++] = 0;
2098721176
20988
-
21177
+
2098921178
return preg->p - 2;
2099021179
}
2099121180
2099221181
static void regc(regex_t *preg, int b )
2099321182
{
@@ -20997,13 +21186,13 @@
2099721186
2099821187
static int reginsert(regex_t *preg, int op, int size, int opnd )
2099921188
{
2100021189
reg_grow(preg, size);
2100121190
21002
-
21191
+
2100321192
memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
21004
-
21193
+
2100521194
memset(preg->program + opnd, 0, sizeof(int) * size);
2100621195
2100721196
preg->program[opnd] = op;
2100821197
2100921198
preg->p += size;
@@ -21015,11 +21204,11 @@
2101521204
{
2101621205
int scan;
2101721206
int temp;
2101821207
int offset;
2101921208
21020
-
21209
+
2102121210
scan = p;
2102221211
for (;;) {
2102321212
temp = regnext(preg, scan);
2102421213
if (temp == 0)
2102521214
break;
@@ -21035,11 +21224,11 @@
2103521224
}
2103621225
2103721226
2103821227
static void regoptail(regex_t *preg, int p, int val )
2103921228
{
21040
-
21229
+
2104121230
if (p != 0 && OP(preg, p) == BRANCH) {
2104221231
regtail(preg, OPERAND(p), val);
2104321232
}
2104421233
}
2104521234
@@ -21051,16 +21240,16 @@
2105121240
int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
2105221241
{
2105321242
const char *s;
2105421243
int scan;
2105521244
21056
-
21245
+
2105721246
if (preg == NULL || preg->program == NULL || string == NULL) {
2105821247
return REG_ERR_NULL_ARGUMENT;
2105921248
}
2106021249
21061
-
21250
+
2106221251
if (*preg->program != REG_MAGIC) {
2106321252
return REG_ERR_CORRUPTED;
2106421253
}
2106521254
2106621255
#ifdef DEBUG
@@ -21069,51 +21258,51 @@
2106921258
#endif
2107021259
2107121260
preg->eflags = eflags;
2107221261
preg->pmatch = pmatch;
2107321262
preg->nmatch = nmatch;
21074
- preg->start = string;
21263
+ preg->start = string;
2107521264
21076
-
21265
+
2107721266
for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
2107821267
int op = OP(preg, scan);
2107921268
if (op == END)
2108021269
break;
2108121270
if (op == REPX || op == REPXMIN)
2108221271
preg->program[scan + 4] = 0;
2108321272
}
2108421273
21085
-
21274
+
2108621275
if (preg->regmust != 0) {
2108721276
s = string;
2108821277
while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
2108921278
if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
2109021279
break;
2109121280
}
2109221281
s++;
2109321282
}
21094
- if (s == NULL)
21283
+ if (s == NULL)
2109521284
return REG_NOMATCH;
2109621285
}
2109721286
21098
-
21287
+
2109921288
preg->regbol = string;
2110021289
21101
-
21290
+
2110221291
if (preg->reganch) {
2110321292
if (eflags & REG_NOTBOL) {
21104
-
21293
+
2110521294
goto nextline;
2110621295
}
2110721296
while (1) {
2110821297
if (regtry(preg, string)) {
2110921298
return REG_NOERROR;
2111021299
}
2111121300
if (*string) {
2111221301
nextline:
2111321302
if (preg->cflags & REG_NEWLINE) {
21114
-
21303
+
2111521304
string = strchr(string, '\n');
2111621305
if (string) {
2111721306
preg->regbol = ++string;
2111821307
continue;
2111921308
}
@@ -21121,22 +21310,22 @@
2112121310
}
2112221311
return REG_NOMATCH;
2112321312
}
2112421313
}
2112521314
21126
-
21315
+
2112721316
s = string;
2112821317
if (preg->regstart != '\0') {
21129
-
21318
+
2113021319
while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
2113121320
if (regtry(preg, s))
2113221321
return REG_NOERROR;
2113321322
s++;
2113421323
}
2113521324
}
2113621325
else
21137
-
21326
+
2113821327
while (1) {
2113921328
if (regtry(preg, s))
2114021329
return REG_NOERROR;
2114121330
if (*s == '\0') {
2114221331
break;
@@ -21145,15 +21334,15 @@
2114521334
int c;
2114621335
s += utf8_tounicode(s, &c);
2114721336
}
2114821337
}
2114921338
21150
-
21339
+
2115121340
return REG_NOMATCH;
2115221341
}
2115321342
21154
-
21343
+
2115521344
static int regtry( regex_t *preg, const char *string )
2115621345
{
2115721346
int i;
2115821347
2115921348
preg->reginput = string;
@@ -21190,11 +21379,11 @@
2119021379
}
2119121380
2119221381
static int reg_range_find(const int *range, int c)
2119321382
{
2119421383
while (*range) {
21195
-
21384
+
2119621385
if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
2119721386
return 1;
2119821387
}
2119921388
range += 2;
2120021389
}
@@ -21202,11 +21391,11 @@
2120221391
}
2120321392
2120421393
static const char *str_find(const char *string, int c, int nocase)
2120521394
{
2120621395
if (nocase) {
21207
-
21396
+
2120821397
c = utf8_upper(c);
2120921398
}
2121021399
while (*string) {
2121121400
int ch;
2121221401
int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21246,15 +21435,15 @@
2124621435
no = regrepeat(preg, scan + 5, max);
2124721436
if (no < min) {
2124821437
return 0;
2124921438
}
2125021439
if (matchmin) {
21251
-
21440
+
2125221441
max = no;
2125321442
no = min;
2125421443
}
21255
-
21444
+
2125621445
while (1) {
2125721446
if (matchmin) {
2125821447
if (no > max) {
2125921448
break;
2126021449
}
@@ -21264,22 +21453,22 @@
2126421453
break;
2126521454
}
2126621455
}
2126721456
preg->reginput = save + utf8_index(save, no);
2126821457
reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21269
-
21458
+
2127021459
if (reg_iseol(preg, nextch) || c == nextch) {
2127121460
if (regmatch(preg, next)) {
2127221461
return(1);
2127321462
}
2127421463
}
2127521464
if (matchmin) {
21276
-
21465
+
2127721466
no++;
2127821467
}
2127921468
else {
21280
-
21469
+
2128121470
no--;
2128221471
}
2128321472
}
2128421473
return(0);
2128521474
}
@@ -21289,13 +21478,13 @@
2128921478
int *scanpt = preg->program + scan;
2129021479
2129121480
int max = scanpt[2];
2129221481
int min = scanpt[3];
2129321482
21294
-
21483
+
2129521484
if (scanpt[4] < min) {
21296
-
21485
+
2129721486
scanpt[4]++;
2129821487
if (regmatch(preg, scan + 5)) {
2129921488
return 1;
2130021489
}
2130121490
scanpt[4]--;
@@ -21304,39 +21493,39 @@
2130421493
if (scanpt[4] > max) {
2130521494
return 0;
2130621495
}
2130721496
2130821497
if (matchmin) {
21309
-
21498
+
2131021499
if (regmatch(preg, regnext(preg, scan))) {
2131121500
return 1;
2131221501
}
21313
-
21502
+
2131421503
scanpt[4]++;
2131521504
if (regmatch(preg, scan + 5)) {
2131621505
return 1;
2131721506
}
2131821507
scanpt[4]--;
2131921508
return 0;
2132021509
}
21321
-
21510
+
2132221511
if (scanpt[4] < max) {
2132321512
scanpt[4]++;
2132421513
if (regmatch(preg, scan + 5)) {
2132521514
return 1;
2132621515
}
2132721516
scanpt[4]--;
2132821517
}
21329
-
21518
+
2133021519
return regmatch(preg, regnext(preg, scan));
2133121520
}
2133221521
2133321522
2133421523
static int regmatch(regex_t *preg, int prog)
2133521524
{
21336
- int scan;
21337
- int next;
21525
+ int scan;
21526
+ int next;
2133821527
const char *save;
2133921528
2134021529
scan = prog;
2134121530
2134221531
#ifdef DEBUG
@@ -21346,11 +21535,11 @@
2134621535
while (scan != 0) {
2134721536
int n;
2134821537
int c;
2134921538
#ifdef DEBUG
2135021539
if (regnarrate) {
21351
- fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
21540
+ fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
2135221541
}
2135321542
#endif
2135421543
next = regnext(preg, scan);
2135521544
n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
2135621545
@@ -21357,49 +21546,49 @@
2135721546
switch (OP(preg, scan)) {
2135821547
case BOLX:
2135921548
if ((preg->eflags & REG_NOTBOL)) {
2136021549
return(0);
2136121550
}
21362
-
21551
+
2136321552
case BOL:
2136421553
if (preg->reginput != preg->regbol) {
2136521554
return(0);
2136621555
}
2136721556
break;
2136821557
case EOLX:
2136921558
if (c != 0) {
21370
-
21559
+
2137121560
return 0;
2137221561
}
2137321562
break;
2137421563
case EOL:
2137521564
if (!reg_iseol(preg, c)) {
2137621565
return(0);
2137721566
}
2137821567
break;
2137921568
case WORDA:
21380
-
21569
+
2138121570
if ((!isalnum(UCHAR(c))) && c != '_')
2138221571
return(0);
21383
-
21572
+
2138421573
if (preg->reginput > preg->regbol &&
2138521574
(isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
2138621575
return(0);
2138721576
break;
2138821577
case WORDZ:
21389
-
21578
+
2139021579
if (preg->reginput > preg->regbol) {
21391
-
21580
+
2139221581
if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
2139321582
c = preg->reginput[-1];
21394
-
21583
+
2139521584
if (isalnum(UCHAR(c)) || c == '_') {
2139621585
break;
2139721586
}
2139821587
}
2139921588
}
21400
-
21589
+
2140121590
return(0);
2140221591
2140321592
case ANY:
2140421593
if (reg_iseol(preg, c))
2140521594
return 0;
@@ -21435,12 +21624,12 @@
2143521624
case NOTHING:
2143621625
break;
2143721626
case BACK:
2143821627
break;
2143921628
case BRANCH:
21440
- if (OP(preg, next) != BRANCH)
21441
- next = OPERAND(scan);
21629
+ if (OP(preg, next) != BRANCH)
21630
+ next = OPERAND(scan);
2144221631
else {
2144321632
do {
2144421633
save = preg->reginput;
2144521634
if (regmatch(preg, OPERAND(scan))) {
2144621635
return(1);
@@ -21447,11 +21636,11 @@
2144721636
}
2144821637
preg->reginput = save;
2144921638
scan = regnext(preg, scan);
2145021639
} while (scan != 0 && OP(preg, scan) == BRANCH);
2145121640
return(0);
21452
-
21641
+
2145321642
}
2145421643
break;
2145521644
case REP:
2145621645
case REPMIN:
2145721646
return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21459,11 +21648,11 @@
2145921648
case REPX:
2146021649
case REPXMIN:
2146121650
return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
2146221651
2146321652
case END:
21464
- return 1;
21653
+ return 1;
2146521654
2146621655
case OPENNC:
2146721656
case CLOSENC:
2146821657
return regmatch(preg, next);
2146921658
@@ -21506,11 +21695,11 @@
2150621695
2150721696
scan = preg->reginput;
2150821697
opnd = OPERAND(p);
2150921698
switch (OP(preg, p)) {
2151021699
case ANY:
21511
-
21700
+
2151221701
while (!reg_iseol(preg, *scan) && count < max) {
2151321702
count++;
2151421703
scan++;
2151521704
}
2151621705
break;
@@ -21542,13 +21731,13 @@
2154221731
}
2154321732
count++;
2154421733
scan += n;
2154521734
}
2154621735
break;
21547
- default:
21736
+ default:
2154821737
preg->err = REG_ERR_INTERNAL;
21549
- count = 0;
21738
+ count = 0;
2155021739
break;
2155121740
}
2155221741
preg->reginput = scan;
2155321742
2155421743
return(count);
@@ -21569,11 +21758,11 @@
2156921758
return(p+offset);
2157021759
}
2157121760
2157221761
static int regopsize(regex_t *preg, int p )
2157321762
{
21574
-
21763
+
2157521764
switch (OP(preg, p)) {
2157621765
case REP:
2157721766
case REPMIN:
2157821767
case REPX:
2157921768
case REPXMIN:
@@ -21690,26 +21879,26 @@
2169021879
{
2169121880
DIR *dir = 0;
2169221881
2169321882
if (name && name[0]) {
2169421883
size_t base_length = strlen(name);
21695
- const char *all =
21884
+ const char *all =
2169621885
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
2169721886
2169821887
if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
2169921888
(dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
2170021889
strcat(strcpy(dir->name, name), all);
2170121890
2170221891
if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
2170321892
dir->result.d_name = 0;
21704
- else {
21893
+ else {
2170521894
Jim_Free(dir->name);
2170621895
Jim_Free(dir);
2170721896
dir = 0;
2170821897
}
2170921898
}
21710
- else {
21899
+ else {
2171121900
Jim_Free(dir);
2171221901
dir = 0;
2171321902
errno = ENOMEM;
2171421903
}
2171521904
}
@@ -21727,11 +21916,11 @@
2172721916
if (dir->handle != -1)
2172821917
result = _findclose(dir->handle);
2172921918
Jim_Free(dir->name);
2173021919
Jim_Free(dir);
2173121920
}
21732
- if (result == -1)
21921
+ if (result == -1)
2173321922
errno = EBADF;
2173421923
return result;
2173521924
}
2173621925
2173721926
struct dirent *readdir(DIR * dir)
@@ -21810,11 +21999,11 @@
2181021999
}
2181122000
2181222001
void Jim_HistoryShow(void)
2181322002
{
2181422003
#ifdef USE_LINENOISE
21815
-
22004
+
2181622005
int i;
2181722006
int len;
2181822007
char **history = linenoiseHistory(&len);
2181922008
for (i = 0; i < len; i++) {
2182022009
printf("%4d %s\n", i + 1, history[i]);
@@ -21876,11 +22065,11 @@
2187622065
Jim_DecrRefCount(interp, scriptObjPtr);
2187722066
retcode = JIM_OK;
2187822067
goto out;
2187922068
}
2188022069
if (Jim_Length(scriptObjPtr) != 0) {
21881
-
22070
+
2188222071
Jim_AppendString(interp, scriptObjPtr, "\n", 1);
2188322072
}
2188422073
Jim_AppendString(interp, scriptObjPtr, line, -1);
2188522074
free(line);
2188622075
if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
@@ -21888,11 +22077,11 @@
2188822077
2188922078
snprintf(prompt, sizeof(prompt), "%c> ", state);
2189022079
}
2189122080
#ifdef USE_LINENOISE
2189222081
if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
21893
-
22082
+
2189422083
Jim_HistoryShow();
2189522084
Jim_DecrRefCount(interp, scriptObjPtr);
2189622085
continue;
2189722086
}
2189822087
@@ -21931,11 +22120,11 @@
2193122120
static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
2193222121
{
2193322122
int n;
2193422123
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
2193522124
21936
-
22125
+
2193722126
for (n = 0; n < argc; n++) {
2193822127
Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
2193922128
2194022129
Jim_ListAppendElement(interp, listObj, obj);
2194122130
}
@@ -21971,47 +22160,47 @@
2197122160
{
2197222161
int retcode;
2197322162
Jim_Interp *interp;
2197422163
char *const orig_argv0 = argv[0];
2197522164
21976
-
22165
+
2197722166
if (argc > 1 && strcmp(argv[1], "--version") == 0) {
2197822167
printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
2197922168
return 0;
2198022169
}
2198122170
else if (argc > 1 && strcmp(argv[1], "--help") == 0) {
2198222171
usage(argv[0]);
2198322172
return 0;
2198422173
}
2198522174
21986
-
22175
+
2198722176
interp = Jim_CreateInterp();
2198822177
Jim_RegisterCoreCommands(interp);
2198922178
21990
-
22179
+
2199122180
if (Jim_InitStaticExtensions(interp) != JIM_OK) {
2199222181
JimPrintErrorMessage(interp);
2199322182
}
2199422183
2199522184
Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0);
2199622185
Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
2199722186
retcode = Jim_initjimshInit(interp);
2199822187
2199922188
if (argc == 1) {
22000
-
22189
+
2200122190
if (retcode == JIM_ERR) {
2200222191
JimPrintErrorMessage(interp);
2200322192
}
2200422193
if (retcode != JIM_EXIT) {
2200522194
JimSetArgv(interp, 0, NULL);
2200622195
retcode = Jim_InteractivePrompt(interp);
2200722196
}
2200822197
}
2200922198
else {
22010
-
22199
+
2201122200
if (argc > 2 && strcmp(argv[1], "-e") == 0) {
22012
-
22201
+
2201322202
JimSetArgv(interp, argc - 3, argv + 3);
2201422203
retcode = Jim_Eval(interp, argv[2]);
2201522204
if (retcode != JIM_ERR) {
2201622205
printf("%s\n", Jim_String(Jim_GetResult(interp)));
2201722206
}
2201822207
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,7 +1,9 @@
1 /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */
 
2 #define JIM_TCL_COMPAT
 
3 #define JIM_ANSIC
4 #define JIM_REGEXP
5 #define HAVE_NO_AUTOCONF
6 #define _JIMAUTOCONF_H
7 #define TCL_LIBRARY "."
@@ -33,26 +35,20 @@
33 #define HAVE_UNISTD_H
34 #else
35 #define TCL_PLATFORM_OS "unknown"
36 #define TCL_PLATFORM_PLATFORM "unix"
37 #define TCL_PLATFORM_PATH_SEPARATOR ":"
38 #ifdef _MINIX
39 #define vfork fork
40 #define _POSIX_SOURCE
41 #else
42 #define _GNU_SOURCE
43 #endif
44 #define HAVE_VFORK
45 #define HAVE_WAITPID
46 #define HAVE_ISATTY
47 #define HAVE_MKSTEMP
48 #define HAVE_LINK
49 #define HAVE_SYS_TIME_H
50 #define HAVE_DIRENT_H
51 #define HAVE_UNISTD_H
52 #endif
53 #define JIM_VERSION 77
54 #ifndef JIM_WIN32COMPAT_H
55 #define JIM_WIN32COMPAT_H
56
57
58
@@ -109,14 +105,14 @@
109 struct dirent {
110 char *d_name;
111 };
112
113 typedef struct DIR {
114 long handle;
115 struct _finddata_t info;
116 struct dirent result;
117 char *name;
118 } DIR;
119
120 DIR *opendir(const char *name);
121 int closedir(DIR *dir);
122 struct dirent *readdir(DIR *dir);
@@ -126,11 +122,11 @@
126 #include <stdlib.h>
127 #define strtod __strtod
128
129 #endif
130
131 #endif
132
133 #ifdef __cplusplus
134 }
135 #endif
136
@@ -179,13 +175,13 @@
179 extern "C" {
180 #endif
181
182 #include <time.h>
183 #include <limits.h>
184 #include <stdio.h>
185 #include <stdlib.h>
186 #include <stdarg.h>
187
188
189 #ifndef HAVE_NO_AUTOCONF
190 #endif
191
@@ -228,31 +224,31 @@
228 #define JIM_SIGNAL 5
229 #define JIM_EXIT 6
230
231 #define JIM_EVAL 7
232
233 #define JIM_MAX_CALLFRAME_DEPTH 1000
234 #define JIM_MAX_EVAL_DEPTH 2000
235
236
237 #define JIM_PRIV_FLAG_SHIFT 20
238
239 #define JIM_NONE 0
240 #define JIM_ERRMSG 1
241 #define JIM_ENUM_ABBREV 2
242 #define JIM_UNSHARED 4
243 #define JIM_MUSTEXIST 8
244
245
246 #define JIM_SUBST_NOVAR 1
247 #define JIM_SUBST_NOCMD 2
248 #define JIM_SUBST_NOESC 4
249 #define JIM_SUBST_FLAG 128
250
251
252 #define JIM_CASESENS 0
253 #define JIM_NOCASE 1
254
255
256 #define JIM_PATH_LEN 1024
257
258
@@ -343,79 +339,79 @@
343 #define Jim_GetHashTableSize(ht) ((ht)->size)
344 #define Jim_GetHashTableUsed(ht) ((ht)->used)
345
346
347 typedef struct Jim_Obj {
348 char *bytes;
349 const struct Jim_ObjType *typePtr;
350 int refCount;
351 int length;
352
353 union {
354
355 jim_wide wideValue;
356
357 int intValue;
358
359 double doubleValue;
360
361 void *ptr;
362
363 struct {
364 void *ptr1;
365 void *ptr2;
366 } twoPtrValue;
367
368 struct {
369 struct Jim_Var *varPtr;
370 unsigned long callFrameId;
371 int global;
372 } varValue;
373
374 struct {
375 struct Jim_Obj *nsObj;
376 struct Jim_Cmd *cmdPtr;
377 unsigned long procEpoch;
378 } cmdValue;
379
380 struct {
381 struct Jim_Obj **ele;
382 int len;
383 int maxLen;
384 } listValue;
385
386 struct {
387 int maxLength;
388 int charLength;
389 } strValue;
390
391 struct {
392 unsigned long id;
393 struct Jim_Reference *refPtr;
394 } refValue;
395
396 struct {
397 struct Jim_Obj *fileNameObj;
398 int lineNumber;
399 } sourceValue;
400
401 struct {
402 struct Jim_Obj *varNameObjPtr;
403 struct Jim_Obj *indexObjPtr;
404 } dictSubstValue;
405
406 struct {
407 void *compre;
408 unsigned flags;
409 } regexpValue;
410 struct {
411 int line;
412 int argc;
413 } scriptLineValue;
414 } internalRep;
415 struct Jim_Obj *prevObjPtr;
416 struct Jim_Obj *nextObjPtr;
417 } Jim_Obj;
418
419
420 #define Jim_IncrRefCount(objPtr) \
421 ++(objPtr)->refCount
@@ -446,40 +442,40 @@
446 typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
447 struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
448 typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
449
450 typedef struct Jim_ObjType {
451 const char *name;
452 Jim_FreeInternalRepProc *freeIntRepProc;
453 Jim_DupInternalRepProc *dupIntRepProc;
454 Jim_UpdateStringProc *updateStringProc;
455 int flags;
456 } Jim_ObjType;
457
458
459 #define JIM_TYPE_NONE 0
460 #define JIM_TYPE_REFERENCES 1
461
462
463
464 typedef struct Jim_CallFrame {
465 unsigned long id;
466 int level;
467 struct Jim_HashTable vars;
468 struct Jim_HashTable *staticVars;
469 struct Jim_CallFrame *parent;
470 Jim_Obj *const *argv;
471 int argc;
472 Jim_Obj *procArgsObjPtr;
473 Jim_Obj *procBodyObjPtr;
474 struct Jim_CallFrame *next;
475 Jim_Obj *nsObj;
476 Jim_Obj *fileNameObj;
477 int line;
478 Jim_Stack *localCommands;
479 struct Jim_Obj *tailcallObj;
480 struct Jim_Cmd *tailcallCmd;
481 } Jim_CallFrame;
482
483 typedef struct Jim_Var {
484 Jim_Obj *objPtr;
485 struct Jim_CallFrame *linkFramePtr;
@@ -491,35 +487,35 @@
491 typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
492
493
494
495 typedef struct Jim_Cmd {
496 int inUse;
497 int isproc;
498 struct Jim_Cmd *prevCmd;
499 union {
500 struct {
501
502 Jim_CmdProc *cmdProc;
503 Jim_DelCmdProc *delProc;
504 void *privData;
505 } native;
506 struct {
507
508 Jim_Obj *argListObjPtr;
509 Jim_Obj *bodyObjPtr;
510 Jim_HashTable *staticVars;
511 int argListLen;
512 int reqArity;
513 int optArity;
514 int argsPos;
515 int upcall;
516 struct Jim_ProcArg {
517 Jim_Obj *nameObjPtr;
518 Jim_Obj *defaultObjPtr;
519 } *arglist;
520 Jim_Obj *nsObj;
521 } proc;
522 } u;
523 } Jim_Cmd;
524
525
@@ -527,64 +523,64 @@
527 unsigned char sbox[256];
528 unsigned int i, j;
529 } Jim_PrngState;
530
531 typedef struct Jim_Interp {
532 Jim_Obj *result;
533 int errorLine;
534 Jim_Obj *errorFileNameObj;
535 int addStackTrace;
536 int maxCallFrameDepth;
537 int maxEvalDepth;
538 int evalDepth;
539 int returnCode;
540 int returnLevel;
541 int exitCode;
542 long id;
543 int signal_level;
544 jim_wide sigmask;
545 int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
546 Jim_CallFrame *framePtr;
547 Jim_CallFrame *topFramePtr;
548 struct Jim_HashTable commands;
549 unsigned long procEpoch; /* Incremented every time the result
550 of procedures names lookup caching
551 may no longer be valid. */
552 unsigned long callFrameEpoch; /* Incremented every time a new
553 callframe is created. This id is used for the
554 'ID' field contained in the Jim_CallFrame
555 structure. */
556 int local;
557 Jim_Obj *liveList;
558 Jim_Obj *freeList;
559 Jim_Obj *currentScriptObj;
560 Jim_Obj *nullScriptObj;
561 Jim_Obj *emptyObj;
562 Jim_Obj *trueObj;
563 Jim_Obj *falseObj;
564 unsigned long referenceNextId;
565 struct Jim_HashTable references;
566 unsigned long lastCollectId; /* reference max Id of the last GC
567 execution. It's set to -1 while the collection
568 is running as sentinel to avoid to recursive
569 calls via the [collect] command inside
570 finalizers. */
571 time_t lastCollectTime;
572 Jim_Obj *stackTrace;
573 Jim_Obj *errorProc;
574 Jim_Obj *unknown;
575 int unknown_called;
576 int errorFlag;
577 void *cmdPrivData; /* Used to pass the private data pointer to
578 a command. It is set to what the user specified
579 via Jim_CreateCommand(). */
580
581 struct Jim_CallFrame *freeFramesList;
582 struct Jim_HashTable assocData;
583 Jim_PrngState *prngState;
584 struct Jim_HashTable packages;
585 Jim_Stack *loadHandles;
586 } Jim_Interp;
587
588 #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
589 #define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
590 #define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -835,14 +831,10 @@
835 JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
836 Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
837 JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
838 Jim_Obj *exprObjPtr, int *boolPtr);
839
840
841 JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr,
842 int *booleanPtr);
843
844
845 JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
846 jim_wide *widePtr);
847 JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
848 long *longPtr);
@@ -912,11 +904,11 @@
912
913 #ifdef __cplusplus
914 }
915 #endif
916
917 #endif
918
919 #ifndef JIM_SUBCMD_H
920 #define JIM_SUBCMD_H
921
922
@@ -923,24 +915,24 @@
923 #ifdef __cplusplus
924 extern "C" {
925 #endif
926
927
928 #define JIM_MODFLAG_HIDDEN 0x0001
929 #define JIM_MODFLAG_FULLARGV 0x0002
930
931
932
933 typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
934
935 typedef struct {
936 const char *cmd;
937 const char *args;
938 jim_subcmd_function *function;
939 short minargs;
940 short maxargs;
941 unsigned short flags;
942 } jim_subcmd_type;
943
944 const jim_subcmd_type *
945 Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv);
946
@@ -968,36 +960,36 @@
968 int rm_eo;
969 } regmatch_t;
970
971
972 typedef struct regexp {
973
974 int re_nsub;
975
976
977 int cflags;
978 int err;
979 int regstart;
980 int reganch;
981 int regmust;
982 int regmlen;
983 int *program;
984
985
986 const char *regparse;
987 int p;
988 int proglen;
989
990
991 int eflags;
992 const char *start;
993 const char *reginput;
994 const char *regbol;
995
996
997 regmatch_t *pmatch;
998 int nmatch;
999 } regexp;
1000
1001 typedef regexp regex_t;
1002
1003 #define REG_EXTENDED 0
@@ -1005,13 +997,13 @@
1005 #define REG_ICASE 2
1006
1007 #define REG_NOTBOL 16
1008
1009 enum {
1010 REG_NOERROR,
1011 REG_NOMATCH,
1012 REG_BADPAT,
1013 REG_ERR_NULL_ARGUMENT,
1014 REG_ERR_UNKNOWN,
1015 REG_ERR_TOO_BIG,
1016 REG_ERR_NOMEM,
1017 REG_ERR_TOO_MANY_PAREN,
@@ -1788,11 +1780,10 @@
1788 "}\n"
1789 );
1790 }
1791
1792
1793 #define _GNU_SOURCE
1794 #include <stdio.h>
1795 #include <string.h>
1796 #include <errno.h>
1797 #include <fcntl.h>
1798 #ifdef HAVE_UNISTD_H
@@ -1817,12 +1808,12 @@
1817 #include <openssl/ssl.h>
1818 #include <openssl/err.h>
1819 #endif
1820
1821
1822 #define AIO_CMD_LEN 32
1823 #define AIO_BUF_LEN 256
1824
1825 #ifndef HAVE_FTELLO
1826 #define ftello ftell
1827 #endif
1828 #ifndef HAVE_FSEEKO
@@ -1857,11 +1848,11 @@
1857 typedef struct AioFile
1858 {
1859 FILE *fp;
1860 Jim_Obj *filename;
1861 int type;
1862 int openFlags;
1863 int fd;
1864 Jim_Obj *rEvent;
1865 Jim_Obj *wEvent;
1866 Jim_Obj *eEvent;
1867 int addr_family;
@@ -1888,11 +1879,11 @@
1888 {
1889 if (!ferror(af->fp)) {
1890 return JIM_OK;
1891 }
1892 clearerr(af->fp);
1893
1894 if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
1895 return JIM_OK;
1896 }
1897 #ifdef ECONNRESET
1898 if (errno == ECONNRESET) {
@@ -1954,12 +1945,12 @@
1954 JIM_NOTUSED(interp);
1955
1956 Jim_DecrRefCount(interp, af->filename);
1957
1958 #ifdef jim_ext_eventloop
1959
1960 Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
1961 #endif
1962
1963 #if defined(JIM_SSL)
1964 if (af->ssl != NULL) {
1965 SSL_free(af->ssl);
@@ -1977,11 +1968,11 @@
1977 {
1978 AioFile *af = Jim_CmdPrivData(interp);
1979 char buf[AIO_BUF_LEN];
1980 Jim_Obj *objPtr;
1981 int nonewline = 0;
1982 jim_wide neededLen = -1;
1983
1984 if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
1985 nonewline = 1;
1986 argv++;
1987 argc--;
@@ -2016,11 +2007,11 @@
2016 }
2017 }
2018 if (retval != readlen)
2019 break;
2020 }
2021
2022 if (JimCheckStreamError(interp, af)) {
2023 Jim_FreeNewObj(interp, objPtr);
2024 return JIM_ERR;
2025 }
2026 if (nonewline) {
@@ -2038,11 +2029,11 @@
2038
2039 AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command)
2040 {
2041 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
2042
2043
2044 if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
2045 return (AioFile *) cmdPtr->u.native.privData;
2046 }
2047 Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
2048 return NULL;
@@ -2119,21 +2110,21 @@
2119 }
2120 else {
2121 len = strlen(buf);
2122
2123 if (len && (buf[len - 1] == '\n')) {
2124
2125 len--;
2126 }
2127
2128 Jim_AppendString(interp, objPtr, buf, len);
2129 break;
2130 }
2131 }
2132
2133 if (JimCheckStreamError(interp, af)) {
2134
2135 Jim_FreeNewObj(interp, objPtr);
2136 return JIM_ERR;
2137 }
2138
2139 if (argc) {
@@ -2143,11 +2134,11 @@
2143 }
2144
2145 len = Jim_Length(objPtr);
2146
2147 if (len == 0 && feof(af->fp)) {
2148
2149 len = -1;
2150 }
2151 Jim_SetResultInt(interp, len);
2152 }
2153 else {
@@ -2373,33 +2364,33 @@
2373
2374 static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
2375 int argc, Jim_Obj * const *argv)
2376 {
2377 if (argc == 0) {
2378
2379 if (*scriptHandlerObj) {
2380 Jim_SetResult(interp, *scriptHandlerObj);
2381 }
2382 return JIM_OK;
2383 }
2384
2385 if (*scriptHandlerObj) {
2386
2387 Jim_DeleteFileHandler(interp, af->fd, mask);
2388 }
2389
2390
2391 if (Jim_Length(argv[0]) == 0) {
2392
2393 return JIM_OK;
2394 }
2395
2396
2397 Jim_IncrRefCount(argv[0]);
2398 *scriptHandlerObj = argv[0];
2399
2400 Jim_CreateFileHandler(interp, af->fd, mask,
2401 JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
2402
2403 return JIM_OK;
2404 }
2405
@@ -2424,136 +2415,135 @@
2424 return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
2425 }
2426 #endif
2427
2428
2429
2430 static const jim_subcmd_type aio_command_table[] = {
2431 { "read",
2432 "?-nonewline? ?len?",
2433 aio_cmd_read,
2434 0,
2435 2,
2436
2437 },
2438 { "copyto",
2439 "handle ?size?",
2440 aio_cmd_copy,
2441 1,
2442 2,
2443
2444 },
2445 { "gets",
2446 "?var?",
2447 aio_cmd_gets,
2448 0,
2449 1,
2450
2451 },
2452 { "puts",
2453 "?-nonewline? str",
2454 aio_cmd_puts,
2455 1,
2456 2,
2457
2458 },
2459 { "isatty",
2460 NULL,
2461 aio_cmd_isatty,
2462 0,
2463 0,
2464
2465 },
2466 { "flush",
2467 NULL,
2468 aio_cmd_flush,
2469 0,
2470 0,
2471
2472 },
2473 { "eof",
2474 NULL,
2475 aio_cmd_eof,
2476 0,
2477 0,
2478
2479 },
2480 { "close",
2481 "?r(ead)|w(rite)?",
2482 aio_cmd_close,
2483 0,
2484 1,
2485 JIM_MODFLAG_FULLARGV,
2486
2487 },
2488 { "seek",
2489 "offset ?start|current|end",
2490 aio_cmd_seek,
2491 1,
2492 2,
2493
2494 },
2495 { "tell",
2496 NULL,
2497 aio_cmd_tell,
2498 0,
2499 0,
2500
2501 },
2502 { "filename",
2503 NULL,
2504 aio_cmd_filename,
2505 0,
2506 0,
2507
2508 },
2509 #ifdef O_NDELAY
2510 { "ndelay",
2511 "?0|1?",
2512 aio_cmd_ndelay,
2513 0,
2514 1,
2515
2516 },
2517 #endif
2518 #ifdef HAVE_FSYNC
2519 { "sync",
2520 NULL,
2521 aio_cmd_sync,
2522 0,
2523 0,
2524
2525 },
2526 #endif
2527 { "buffering",
2528 "none|line|full",
2529 aio_cmd_buffering,
2530 1,
2531 1,
2532
2533 },
2534 #ifdef jim_ext_eventloop
2535 { "readable",
2536 "?readable-script?",
2537 aio_cmd_readable,
2538 0,
2539 1,
2540
2541 },
2542 { "writable",
2543 "?writable-script?",
2544 aio_cmd_writable,
2545 0,
2546 1,
2547
2548 },
2549 { "onexception",
2550 "?exception-script?",
2551 aio_cmd_onexception,
2552 0,
2553 1,
2554
2555 },
2556 #endif
2557 { NULL }
2558 };
2559
@@ -2576,11 +2566,11 @@
2576
2577 #ifdef jim_ext_tclcompat
2578 {
2579 const char *filename = Jim_String(argv[1]);
2580
2581
2582 if (*filename == '|') {
2583 Jim_Obj *evalObj[3];
2584
2585 evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
2586 evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2633,11 +2623,11 @@
2633 Jim_DecrRefCount(interp, filename);
2634 return NULL;
2635 }
2636 }
2637
2638
2639 af = Jim_Alloc(sizeof(*af));
2640 memset(af, 0, sizeof(*af));
2641 af->fp = fh;
2642 af->fd = fileno(fh);
2643 af->filename = filename;
@@ -2671,11 +2661,11 @@
2671 Jim_SetResult(interp, objPtr);
2672 return JIM_OK;
2673 }
2674 }
2675
2676
2677 close(p[0]);
2678 close(p[1]);
2679 JimAioSetError(interp, NULL);
2680 return JIM_ERR;
2681 }
@@ -2705,15 +2695,15 @@
2705 }
2706
2707 #if defined(S_IRWXG) && defined(S_IRWXO)
2708 mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
2709 #else
2710
2711 mask = umask(S_IXUSR);
2712 #endif
2713
2714
2715 fd = mkstemp(filenameObj->bytes);
2716 umask(mask);
2717 if (fd < 0) {
2718 JimAioSetError(interp, filenameObj);
2719 Jim_FreeNewObj(interp, filenameObj);
@@ -2741,11 +2731,11 @@
2741 Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
2742 #ifndef JIM_ANSIC
2743 Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
2744 #endif
2745
2746
2747 JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
2748 JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
2749 JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
2750
2751 return JIM_OK;
@@ -2841,20 +2831,20 @@
2841 {
2842 regex_t *compre;
2843 const char *pattern;
2844 int ret;
2845
2846
2847 if (objPtr->typePtr == &regexpObjType &&
2848 objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
2849
2850 return objPtr->internalRep.regexpValue.compre;
2851 }
2852
 
2853
2854
2855
2856 pattern = Jim_String(objPtr);
2857 compre = Jim_Alloc(sizeof(regex_t));
2858
2859 if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
2860 char buf[100];
@@ -3011,11 +3001,11 @@
3011 }
3012
3013 num_matches++;
3014
3015 if (opt_all && !opt_inline) {
3016
3017 goto try_next_match;
3018 }
3019
3020
3021 j = 0;
@@ -3051,11 +3041,11 @@
3051
3052 if (opt_inline) {
3053 Jim_ListAppendElement(interp, resultListObj, resultObj);
3054 }
3055 else {
3056
3057 result = Jim_SetVariable(interp, argv[i], resultObj);
3058
3059 if (result != JIM_OK) {
3060 Jim_FreeObj(interp, resultObj);
3061 break;
@@ -3178,11 +3168,11 @@
3178
3179 source_str = Jim_GetString(argv[i + 1], &source_len);
3180 replace_str = Jim_GetString(argv[i + 2], &replace_len);
3181 varname = argv[i + 3];
3182
3183
3184 resultObj = Jim_NewStringObj(interp, "", 0);
3185
3186 if (offset) {
3187 if (offset < 0) {
3188 offset += source_len + 1;
@@ -3193,11 +3183,11 @@
3193 else if (offset < 0) {
3194 offset = 0;
3195 }
3196 }
3197
3198
3199 Jim_AppendString(interp, resultObj, source_str, offset);
3200
3201
3202 n = source_len - offset;
3203 p = source_str + offset;
@@ -3252,23 +3242,23 @@
3252 }
3253
3254 p += pmatch[0].rm_eo;
3255 n -= pmatch[0].rm_eo;
3256
3257
3258 if (!opt_all || n == 0) {
3259 break;
3260 }
3261
3262
3263 if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
3264 break;
3265 }
3266
3267
3268 if (pattern[0] == '\0' && n) {
3269
3270 Jim_AppendString(interp, resultObj, p, 1);
3271 p++;
3272 n--;
3273 }
3274
@@ -3275,11 +3265,11 @@
3275 regexec_flags |= REG_NOTBOL;
3276 } while (n);
3277
3278 Jim_AppendString(interp, resultObj, p, -1);
3279
3280
3281 if (argc - i == 4) {
3282 result = Jim_SetVariable(interp, varname, resultObj);
3283
3284 if (result == JIM_OK) {
3285 Jim_SetResultInt(interp, num_matches);
@@ -3381,11 +3371,11 @@
3381 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
3382 }
3383
3384 static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
3385 {
3386
3387 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
3388
3389 AppendStatElement(interp, listObj, "dev", sb->st_dev);
3390 AppendStatElement(interp, listObj, "ino", sb->st_ino);
3391 AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3397,25 +3387,25 @@
3397 AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
3398 AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
3399 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
3400 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
3401
3402
3403 if (varName) {
3404 Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
3405 if (objPtr) {
3406 if (Jim_DictSize(interp, objPtr) < 0) {
3407
3408 Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
3409 Jim_FreeNewObj(interp, listObj);
3410 return JIM_ERR;
3411 }
3412
3413 if (Jim_IsShared(objPtr))
3414 objPtr = Jim_DuplicateObj(interp, objPtr);
3415
3416
3417 Jim_ListAppendList(interp, objPtr, listObj);
3418 Jim_DictSize(interp, objPtr);
3419 Jim_InvalidateStringRep(objPtr);
3420
3421 Jim_FreeNewObj(interp, listObj);
@@ -3422,11 +3412,11 @@
3422 listObj = objPtr;
3423 }
3424 Jim_SetVariable(interp, varName, listObj);
3425 }
3426
3427
3428 Jim_SetResult(interp, listObj);
3429
3430 return JIM_OK;
3431 }
3432
@@ -3442,11 +3432,11 @@
3442 }
3443 else if (p == path) {
3444 Jim_SetResultString(interp, "/", -1);
3445 }
3446 else if (ISWINDOWS && p[-1] == ':') {
3447
3448 Jim_SetResultString(interp, path, p - path + 1);
3449 }
3450 else {
3451 Jim_SetResultString(interp, path, p - path);
3452 }
@@ -3522,35 +3512,35 @@
3522 char *newname = Jim_Alloc(MAXPATHLEN + 1);
3523 char *last = newname;
3524
3525 *newname = 0;
3526
3527
3528 for (i = 0; i < argc; i++) {
3529 int len;
3530 const char *part = Jim_GetString(argv[i], &len);
3531
3532 if (*part == '/') {
3533
3534 last = newname;
3535 }
3536 else if (ISWINDOWS && strchr(part, ':')) {
3537
3538 last = newname;
3539 }
3540 else if (part[0] == '.') {
3541 if (part[1] == '/') {
3542 part += 2;
3543 len -= 2;
3544 }
3545 else if (part[1] == 0 && last != newname) {
3546
3547 continue;
3548 }
3549 }
3550
3551
3552 if (last != newname && last[-1] != '/') {
3553 *last++ = '/';
3554 }
3555
3556 if (len) {
@@ -3561,22 +3551,22 @@
3561 }
3562 memcpy(last, part, len);
3563 last += len;
3564 }
3565
3566
3567 if (last > newname + 1 && last[-1] == '/') {
3568
3569 if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
3570 *--last = 0;
3571 }
3572 }
3573 }
3574
3575 *last = 0;
3576
3577
3578
3579 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
3580
3581 return JIM_OK;
3582 }
@@ -3601,11 +3591,11 @@
3601 static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3602 {
3603 #ifdef X_OK
3604 return file_access(interp, argv[0], X_OK);
3605 #else
3606
3607 Jim_SetResultBool(interp, 1);
3608 return JIM_OK;
3609 #endif
3610 }
3611
@@ -3626,11 +3616,11 @@
3626 while (argc--) {
3627 const char *path = Jim_String(argv[0]);
3628
3629 if (unlink(path) == -1 && errno != ENOENT) {
3630 if (rmdir(path) == -1) {
3631
3632 if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
3633 Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
3634 strerror(errno));
3635 return JIM_ERR;
3636 }
@@ -3649,15 +3639,15 @@
3649
3650 static int mkdir_all(char *path)
3651 {
3652 int ok = 1;
3653
3654
3655 goto first;
3656
3657 while (ok--) {
3658
3659 {
3660 char *slash = strrchr(path, '/');
3661
3662 if (slash && slash != path) {
3663 *slash = 0;
@@ -3670,24 +3660,24 @@
3670 first:
3671 if (MKDIR_DEFAULT(path) == 0) {
3672 return 0;
3673 }
3674 if (errno == ENOENT) {
3675
3676 continue;
3677 }
3678
3679 if (errno == EEXIST) {
3680 struct stat sb;
3681
3682 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
3683 return 0;
3684 }
3685
3686 errno = EEXIST;
3687 }
3688
3689 break;
3690 }
3691 return -1;
3692 }
3693
@@ -3972,192 +3962,192 @@
3972 { "atime",
3973 "name",
3974 file_cmd_atime,
3975 1,
3976 1,
3977
3978 },
3979 { "mtime",
3980 "name ?time?",
3981 file_cmd_mtime,
3982 1,
3983 2,
3984
3985 },
3986 { "copy",
3987 "?-force? source dest",
3988 file_cmd_copy,
3989 2,
3990 3,
3991
3992 },
3993 { "dirname",
3994 "name",
3995 file_cmd_dirname,
3996 1,
3997 1,
3998
3999 },
4000 { "rootname",
4001 "name",
4002 file_cmd_rootname,
4003 1,
4004 1,
4005
4006 },
4007 { "extension",
4008 "name",
4009 file_cmd_extension,
4010 1,
4011 1,
4012
4013 },
4014 { "tail",
4015 "name",
4016 file_cmd_tail,
4017 1,
4018 1,
4019
4020 },
4021 { "normalize",
4022 "name",
4023 file_cmd_normalize,
4024 1,
4025 1,
4026
4027 },
4028 { "join",
4029 "name ?name ...?",
4030 file_cmd_join,
4031 1,
4032 -1,
4033
4034 },
4035 { "readable",
4036 "name",
4037 file_cmd_readable,
4038 1,
4039 1,
4040
4041 },
4042 { "writable",
4043 "name",
4044 file_cmd_writable,
4045 1,
4046 1,
4047
4048 },
4049 { "executable",
4050 "name",
4051 file_cmd_executable,
4052 1,
4053 1,
4054
4055 },
4056 { "exists",
4057 "name",
4058 file_cmd_exists,
4059 1,
4060 1,
4061
4062 },
4063 { "delete",
4064 "?-force|--? name ...",
4065 file_cmd_delete,
4066 1,
4067 -1,
4068
4069 },
4070 { "mkdir",
4071 "dir ...",
4072 file_cmd_mkdir,
4073 1,
4074 -1,
4075
4076 },
4077 { "tempfile",
4078 "?template?",
4079 file_cmd_tempfile,
4080 0,
4081 1,
4082
4083 },
4084 { "rename",
4085 "?-force? source dest",
4086 file_cmd_rename,
4087 2,
4088 3,
4089
4090 },
4091 #if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
4092 { "link",
4093 "?-symbolic|-hard? newname target",
4094 file_cmd_link,
4095 2,
4096 3,
4097
4098 },
4099 #endif
4100 #if defined(HAVE_READLINK)
4101 { "readlink",
4102 "name",
4103 file_cmd_readlink,
4104 1,
4105 1,
4106
4107 },
4108 #endif
4109 { "size",
4110 "name",
4111 file_cmd_size,
4112 1,
4113 1,
4114
4115 },
4116 { "stat",
4117 "name ?var?",
4118 file_cmd_stat,
4119 1,
4120 2,
4121
4122 },
4123 { "lstat",
4124 "name ?var?",
4125 file_cmd_lstat,
4126 1,
4127 2,
4128
4129 },
4130 { "type",
4131 "name",
4132 file_cmd_type,
4133 1,
4134 1,
4135
4136 },
4137 #ifdef HAVE_GETEUID
4138 { "owned",
4139 "name",
4140 file_cmd_owned,
4141 1,
4142 1,
4143
4144 },
4145 #endif
4146 { "isdirectory",
4147 "name",
4148 file_cmd_isdirectory,
4149 1,
4150 1,
4151
4152 },
4153 { "isfile",
4154 "name",
4155 file_cmd_isfile,
4156 1,
4157 1,
4158
4159 },
4160 {
4161 NULL
4162 }
4163 };
@@ -4189,11 +4179,11 @@
4189 Jim_SetResultString(interp, "Failed to get pwd", -1);
4190 Jim_Free(cwd);
4191 return JIM_ERR;
4192 }
4193 else if (ISWINDOWS) {
4194
4195 char *p = cwd;
4196 while ((p = strchr(p, '\\')) != NULL) {
4197 *p++ = '/';
4198 }
4199 }
@@ -4213,11 +4203,10 @@
4213 Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
4214 Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
4215 return JIM_OK;
4216 }
4217
4218 #define _GNU_SOURCE
4219 #include <string.h>
4220 #include <ctype.h>
4221
4222
4223 #if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4225,20 +4214,20 @@
4225 {
4226 Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
4227 int i, j;
4228 int rc;
4229
4230
4231 for (i = 1; i < argc; i++) {
4232 int len;
4233 const char *arg = Jim_GetString(argv[i], &len);
4234
4235 if (i > 1) {
4236 Jim_AppendString(interp, cmdlineObj, " ", 1);
4237 }
4238 if (strpbrk(arg, "\\\" ") == NULL) {
4239
4240 Jim_AppendString(interp, cmdlineObj, arg, len);
4241 continue;
4242 }
4243
4244 Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4279,11 +4268,11 @@
4279
4280 #include <errno.h>
4281 #include <signal.h>
4282
4283 #if defined(__MINGW32__)
4284
4285 #ifndef STRICT
4286 #define STRICT
4287 #endif
4288 #define WIN32_LEAN_AND_MEAN
4289 #include <windows.h>
@@ -4405,14 +4394,14 @@
4405 if (!objPtr) {
4406 return Jim_GetEnviron();
4407 }
4408
4409
4410
4411 num = Jim_ListLength(interp, objPtr);
4412 if (num % 2) {
4413
4414 num--;
4415 }
4416 size = Jim_Length(objPtr) + 2;
4417
4418 envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4504,19 +4493,19 @@
4504 }
4505
4506
4507 struct WaitInfo
4508 {
4509 pidtype pid;
4510 int status;
4511 int flags;
4512 };
4513
4514 struct WaitInfoTable {
4515 struct WaitInfo *info;
4516 int size;
4517 int used;
4518 };
4519
4520
4521 #define WI_DETACHED 2
4522
@@ -4539,12 +4528,12 @@
4539 return table;
4540 }
4541
4542 static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
4543 {
4544 fdtype outputId;
4545 fdtype errorId;
4546 pidtype *pidPtr;
4547 int numPids, result;
4548 int child_siginfo = 1;
4549 Jim_Obj *childErrObj;
4550 Jim_Obj *errStrObj;
@@ -4556,11 +4545,11 @@
4556 argc--;
4557 numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
4558 if (numPids < 0) {
4559 return JIM_ERR;
4560 }
4561
4562 listObj = Jim_NewListObj(interp, NULL, 0);
4563 for (i = 0; i < numPids; i++) {
4564 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
4565 }
4566 Jim_SetResult(interp, listObj);
@@ -4578,19 +4567,19 @@
4578
4579 result = JIM_OK;
4580
4581 errStrObj = Jim_NewStringObj(interp, "", 0);
4582
4583
4584 if (outputId != JIM_BAD_FD) {
4585 if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
4586 result = JIM_ERR;
4587 Jim_SetResultErrno(interp, "error reading from output pipe");
4588 }
4589 }
4590
4591
4592 childErrObj = Jim_NewStringObj(interp, "", 0);
4593 Jim_IncrRefCount(childErrObj);
4594
4595 if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
4596 result = JIM_ERR;
@@ -4603,25 +4592,25 @@
4603 if (ret < 0) {
4604 Jim_SetResultErrno(interp, "error reading from error pipe");
4605 result = JIM_ERR;
4606 }
4607 else if (ret > 0) {
4608
4609 child_siginfo = 0;
4610 }
4611 }
4612
4613 if (child_siginfo) {
4614
4615 Jim_AppendObj(interp, errStrObj, childErrObj);
4616 }
4617 Jim_DecrRefCount(interp, childErrObj);
4618
4619
4620 Jim_RemoveTrailingNewline(errStrObj);
4621
4622
4623 Jim_SetResult(interp, errStrObj);
4624
4625 return result;
4626 }
4627
@@ -4640,11 +4629,11 @@
4640 for (count = table->used; count > 0; waitPtr++, count--) {
4641 if (waitPtr->flags & WI_DETACHED) {
4642 int status;
4643 pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
4644 if (pid == waitPtr->pid) {
4645
4646 table->used--;
4647 continue;
4648 }
4649 }
4650 if (waitPtr != &table->info[dest]) {
@@ -4656,36 +4645,36 @@
4656
4657 static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
4658 {
4659 int i;
4660
4661
4662 for (i = 0; i < table->used; i++) {
4663 if (pid == table->info[i].pid) {
4664
4665 JimWaitPid(pid, statusPtr, 0);
4666
4667
4668 if (i != table->used - 1) {
4669 table->info[i] = table->info[table->used - 1];
4670 }
4671 table->used--;
4672 return pid;
4673 }
4674 }
4675
4676
4677 return JIM_BAD_PID;
4678 }
4679
4680 static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
4681 {
4682 int j;
4683 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4684
4685 for (j = 0; j < numPids; j++) {
4686
4687 int i;
4688 for (i = 0; i < table->used; i++) {
4689 if (pidPtr[j] == table->info[i].pid) {
4690 table->info[i].flags |= WI_DETACHED;
4691 break;
@@ -4718,16 +4707,16 @@
4718 int cmdCount; /* Count of number of distinct commands
4719 * found in argc/argv. */
4720 const char *input = NULL; /* Describes input for pipeline, depending
4721 * on "inputFile". NULL means take input
4722 * from stdin/pipe. */
4723 int input_len = 0;
4724
4725 #define FILE_NAME 0
4726 #define FILE_APPEND 1
4727 #define FILE_HANDLE 2
4728 #define FILE_TEXT 3
4729
4730 int inputFile = FILE_NAME; /* 1 means input is name of input file.
4731 * 2 means input is filehandle name.
4732 * 0 means input holds actual
4733 * text to be input to command. */
@@ -4748,20 +4737,20 @@
4748 * or NULL if stderr goes to stderr/pipe. */
4749 fdtype inputId = JIM_BAD_FD;
4750 fdtype outputId = JIM_BAD_FD;
4751 fdtype errorId = JIM_BAD_FD;
4752 fdtype lastOutputId = JIM_BAD_FD;
4753 fdtype pipeIds[2];
4754 int firstArg, lastArg; /* Indexes of first and last arguments in
4755 * current command. */
4756 int lastBar;
4757 int i;
4758 pidtype pid;
4759 char **save_environ;
4760 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4761
4762
4763 char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
4764 int arg_count = 0;
4765
4766 JimReapDetachedPids(table);
4767
@@ -4807,11 +4796,11 @@
4807 if (*output == '>') {
4808 outputFile = FILE_APPEND;
4809 output++;
4810 }
4811 if (*output == '&') {
4812
4813 output++;
4814 dup_error = 1;
4815 }
4816 if (*output == '@') {
4817 outputFile = FILE_HANDLE;
@@ -4848,11 +4837,11 @@
4848 goto badargs;
4849 }
4850 lastBar = i;
4851 cmdCount++;
4852 }
4853
4854 arg_array[arg_count++] = (char *)arg;
4855 continue;
4856 }
4857
4858 if (i >= argc) {
@@ -4866,11 +4855,11 @@
4866 badargs:
4867 Jim_Free(arg_array);
4868 return -1;
4869 }
4870
4871
4872 save_environ = JimSaveEnv(JimBuildEnv(interp));
4873
4874 if (input != NULL) {
4875 if (inputFile == FILE_TEXT) {
4876 inputId = JimCreateTemp(interp, input, input_len);
@@ -4877,11 +4866,11 @@
4877 if (inputId == JIM_BAD_FD) {
4878 goto error;
4879 }
4880 }
4881 else if (inputFile == FILE_HANDLE) {
4882
4883 FILE *fh = JimGetAioFilehandle(interp, input);
4884
4885 if (fh == NULL) {
4886 goto error;
4887 }
@@ -4929,20 +4918,20 @@
4929 }
4930 lastOutputId = pipeIds[1];
4931 *outPipePtr = pipeIds[0];
4932 pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
4933 }
4934
4935 if (error != NULL) {
4936 if (errorFile == FILE_HANDLE) {
4937 if (strcmp(error, "1") == 0) {
4938
4939 if (lastOutputId != JIM_BAD_FD) {
4940 errorId = JimDupFd(lastOutputId);
4941 }
4942 else {
4943
4944 error = "stdout";
4945 }
4946 }
4947 if (errorId == JIM_BAD_FD) {
4948 FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4984,11 +4973,11 @@
4984 pipe_dup_err = 1;
4985 }
4986 break;
4987 }
4988 }
4989
4990 arg_array[lastArg] = NULL;
4991 if (lastArg == arg_count) {
4992 outputId = lastOutputId;
4993 }
4994 else {
@@ -4997,16 +4986,16 @@
4997 goto error;
4998 }
4999 outputId = pipeIds[1];
5000 }
5001
5002
5003 if (pipe_dup_err) {
5004 errorId = outputId;
5005 }
5006
5007
5008
5009 #ifdef __MINGW32__
5010 pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
5011 if (pid == JIM_BAD_PID) {
5012 Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -5017,32 +5006,32 @@
5017 if (pid < 0) {
5018 Jim_SetResultErrno(interp, "couldn't fork child process");
5019 goto error;
5020 }
5021 if (pid == 0) {
5022
5023
5024 if (inputId != -1) dup2(inputId, 0);
5025 if (outputId != -1) dup2(outputId, 1);
5026 if (errorId != -1) dup2(errorId, 2);
5027
5028 for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
5029 close(i);
5030 }
5031
5032
5033 (void)signal(SIGPIPE, SIG_DFL);
5034
5035 execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
5036
5037
5038 fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
5039 _exit(127);
5040 }
5041 #endif
5042
5043
5044
5045 if (table->used == table->size) {
5046 table->size += WAIT_TABLE_GROW_BY;
5047 table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
5048 }
@@ -5051,11 +5040,11 @@
5051 table->info[table->used].flags = 0;
5052 table->used++;
5053
5054 pidPtr[numPids] = pid;
5055
5056
5057 errorId = origErrorId;
5058
5059
5060 if (inputId != JIM_BAD_FD) {
5061 JimCloseFd(inputId);
@@ -5122,11 +5111,11 @@
5122 {
5123 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
5124 int result = JIM_OK;
5125 int i;
5126
5127
5128 for (i = 0; i < numPids; i++) {
5129 int waitStatus = 0;
5130 if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
5131 if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) {
5132 result = JIM_ERR;
@@ -5295,21 +5284,17 @@
5295 }
5296
5297 static fdtype JimOpenForRead(const char *filename)
5298 {
5299 return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
5300 JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
5301 }
5302
5303 static fdtype JimOpenForWrite(const char *filename, int append)
5304 {
5305 fdtype fd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5306 JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
5307 if (append && fd != JIM_BAD_FD) {
5308 SetFilePointer(fd, 0, NULL, FILE_END);
5309 }
5310 return fd;
5311 }
5312
5313 static FILE *JimFdOpenForWrite(fdtype fd)
5314 {
5315 return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5317,11 +5302,11 @@
5317
5318 static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
5319 {
5320 DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
5321 if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
5322
5323 return JIM_BAD_PID;
5324 }
5325 GetExitCodeProcess(pid, &ret);
5326 *status = ret;
5327 CloseHandle(pid);
@@ -5344,11 +5329,11 @@
5344 if (handle == INVALID_HANDLE_VALUE) {
5345 goto error;
5346 }
5347
5348 if (contents != NULL) {
5349
5350 FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
5351 if (fh == NULL) {
5352 goto error;
5353 }
5354
@@ -5616,11 +5601,11 @@
5616 #include <sys/time.h>
5617 #endif
5618
5619 static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5620 {
5621
5622 char buf[100];
5623 time_t t;
5624 long seconds;
5625
5626 const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5657,20 +5642,20 @@
5657
5658 if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
5659 return -1;
5660 }
5661
5662
5663 localtime_r(&now, &tm);
5664
5665 pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
5666 if (pt == 0 || *pt != 0) {
5667 Jim_SetResultString(interp, "Failed to parse time according to format", -1);
5668 return JIM_ERR;
5669 }
5670
5671
5672 Jim_SetResultInt(interp, mktime(&tm));
5673
5674 return JIM_OK;
5675 }
5676 #endif
@@ -5708,47 +5693,47 @@
5708 { "seconds",
5709 NULL,
5710 clock_cmd_seconds,
5711 0,
5712 0,
5713
5714 },
5715 { "clicks",
5716 NULL,
5717 clock_cmd_micros,
5718 0,
5719 0,
5720
5721 },
5722 { "microseconds",
5723 NULL,
5724 clock_cmd_micros,
5725 0,
5726 0,
5727
5728 },
5729 { "milliseconds",
5730 NULL,
5731 clock_cmd_millis,
5732 0,
5733 0,
5734
5735 },
5736 { "format",
5737 "seconds ?-format format?",
5738 clock_cmd_format,
5739 1,
5740 3,
5741
5742 },
5743 #ifdef HAVE_STRPTIME
5744 { "scan",
5745 "str -format format",
5746 clock_cmd_scan,
5747 3,
5748 3,
5749
5750 },
5751 #endif
5752 { NULL }
5753 };
5754
@@ -5768,11 +5753,11 @@
5768 #include <errno.h>
5769
5770
5771 static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5772 {
5773
5774 Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
5775 return JIM_OK;
5776 }
5777
5778 static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5784,20 +5769,20 @@
5784 return JIM_OK;
5785 }
5786
5787 patternObj = (argc == 1) ? NULL : argv[1];
5788
5789
5790 if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
5791 if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
5792
5793 Jim_SetResult(interp, objPtr);
5794 return JIM_OK;
5795 }
5796 }
5797
5798
5799 return Jim_DictValues(interp, objPtr, patternObj);
5800 }
5801
5802 static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5803 {
@@ -5817,27 +5802,27 @@
5817 Jim_Obj *resultObj;
5818 Jim_Obj *objPtr;
5819 Jim_Obj **dictValuesObj;
5820
5821 if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
5822
5823 Jim_UnsetVariable(interp, argv[0], JIM_NONE);
5824 return JIM_OK;
5825 }
5826
5827 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5828
5829 if (objPtr == NULL) {
5830
5831 return JIM_OK;
5832 }
5833
5834 if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
5835 return JIM_ERR;
5836 }
5837
5838
5839 resultObj = Jim_NewDictObj(interp, NULL, 0);
5840
5841 for (i = 0; i < len; i += 2) {
5842 if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
5843 Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5852,11 +5837,11 @@
5852 static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5853 {
5854 Jim_Obj *objPtr;
5855 int len = 0;
5856
5857
5858 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5859 if (objPtr) {
5860 len = Jim_DictSize(interp, objPtr);
5861 if (len < 0) {
5862 return JIM_ERR;
@@ -5891,11 +5876,11 @@
5891 return JIM_ERR;
5892 }
5893
5894 dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
5895 if (!dictObj) {
5896
5897 return Jim_SetVariable(interp, argv[0], listObj);
5898 }
5899 else if (Jim_DictSize(interp, dictObj) < 0) {
5900 return JIM_ERR;
5901 }
@@ -5920,53 +5905,53 @@
5920 { "exists",
5921 "arrayName",
5922 array_cmd_exists,
5923 1,
5924 1,
5925
5926 },
5927 { "get",
5928 "arrayName ?pattern?",
5929 array_cmd_get,
5930 1,
5931 2,
5932
5933 },
5934 { "names",
5935 "arrayName ?pattern?",
5936 array_cmd_names,
5937 1,
5938 2,
5939
5940 },
5941 { "set",
5942 "arrayName list",
5943 array_cmd_set,
5944 2,
5945 2,
5946
5947 },
5948 { "size",
5949 "arrayName",
5950 array_cmd_size,
5951 1,
5952 1,
5953
5954 },
5955 { "stat",
5956 "arrayName",
5957 array_cmd_stat,
5958 1,
5959 1,
5960
5961 },
5962 { "unset",
5963 "arrayName ?pattern?",
5964 array_cmd_unset,
5965 1,
5966 2,
5967
5968 },
5969 { NULL
5970 }
5971 };
5972
@@ -6002,12 +5987,11 @@
6002 Jim_arrayInit(interp);
6003 Jim_stdlibInit(interp);
6004 Jim_tclcompatInit(interp);
6005 return JIM_OK;
6006 }
6007 #define JIM_OPTIMIZATION
6008 #define _GNU_SOURCE
6009
6010 #include <stdio.h>
6011 #include <stdlib.h>
6012
6013 #include <string.h>
@@ -6072,16 +6056,10 @@
6072 #define JimPanic(X) JimPanicDump X
6073 #else
6074 #define JimPanic(X)
6075 #endif
6076
6077 #ifdef JIM_OPTIMIZATION
6078 #define JIM_IF_OPTIM(X) X
6079 #else
6080 #define JIM_IF_OPTIM(X)
6081 #endif
6082
6083
6084 static char JimEmptyStringRep[] = "";
6085
6086 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
6087 static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -6134,34 +6112,34 @@
6134 if (*pattern == '^') {
6135 not++;
6136 pattern++;
6137 }
6138
6139
6140 if (*pattern == ']') {
6141 goto first;
6142 }
6143 }
6144
6145 while (*pattern && *pattern != ']') {
6146
6147 if (pattern[0] == '\\') {
6148 first:
6149 pattern += utf8_tounicode_case(pattern, &pchar, nocase);
6150 }
6151 else {
6152
6153 int start;
6154 int end;
6155
6156 pattern += utf8_tounicode_case(pattern, &start, nocase);
6157 if (pattern[0] == '-' && pattern[1]) {
6158
6159 pattern += utf8_tounicode(pattern, &pchar);
6160 pattern += utf8_tounicode_case(pattern, &end, nocase);
6161
6162
6163 if ((c >= start && c <= end) || (c >= end && c <= start)) {
6164 match = 1;
6165 }
6166 continue;
6167 }
@@ -6191,19 +6169,19 @@
6191 while (pattern[1] == '*') {
6192 pattern++;
6193 }
6194 pattern++;
6195 if (!pattern[0]) {
6196 return 1;
6197 }
6198 while (*string) {
6199
6200 if (JimGlobMatch(pattern, string, nocase))
6201 return 1;
6202 string += utf8_tounicode(string, &c);
6203 }
6204 return 0;
6205
6206 case '?':
6207 string += utf8_tounicode(string, &c);
6208 break;
6209
@@ -6212,20 +6190,20 @@
6212 pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
6213 if (!pattern) {
6214 return 0;
6215 }
6216 if (!*pattern) {
6217
6218 continue;
6219 }
6220 break;
6221 }
6222 case '\\':
6223 if (pattern[1]) {
6224 pattern++;
6225 }
6226
6227 default:
6228 string += utf8_tounicode_case(string, &c, nocase);
6229 utf8_tounicode_case(pattern, &pchar, nocase);
6230 if (pchar != c) {
6231 return 0;
@@ -6271,11 +6249,11 @@
6271 maxchars--;
6272 }
6273 if (!maxchars) {
6274 return 0;
6275 }
6276
6277 if (*s1) {
6278 return 1;
6279 }
6280 if (*s2) {
6281 return -1;
@@ -6312,11 +6290,11 @@
6312 const char *p;
6313
6314 if (!l1 || !l2 || l1 > l2)
6315 return -1;
6316
6317
6318 for (p = s2 + l2 - 1; p != s2 - 1; p--) {
6319 if (*p == *s1 && memcmp(s1, p, l1) == 0) {
6320 return p - s2;
6321 }
6322 }
@@ -6371,28 +6349,28 @@
6371 }
6372 *sign = 1;
6373 }
6374
6375 if (str[i] != '0') {
6376
6377 return 0;
6378 }
6379
6380
6381 switch (str[i + 1]) {
6382 case 'x': case 'X': *base = 16; break;
6383 case 'o': case 'O': *base = 8; break;
6384 case 'b': case 'B': *base = 2; break;
6385 default: return 0;
6386 }
6387 i += 2;
6388
6389 if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
6390
6391 return i;
6392 }
6393
6394 *base = 10;
6395 return 0;
6396 }
6397
6398 static long jim_strtol(const char *str, char **endptr)
@@ -6406,11 +6384,11 @@
6406 if (endptr == NULL || *endptr != str + i) {
6407 return value * sign;
6408 }
6409 }
6410
6411
6412 return strtol(str, endptr, 10);
6413 }
6414
6415
6416 static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6425,11 +6403,11 @@
6425 if (endptr == NULL || *endptr != str + i) {
6426 return value * sign;
6427 }
6428 }
6429
6430
6431 return strtoull(str, endptr, 10);
6432 #else
6433 return (unsigned long)jim_strtol(str, endptr);
6434 #endif
6435 }
@@ -6450,40 +6428,26 @@
6450
6451 int Jim_StringToDouble(const char *str, double *doublePtr)
6452 {
6453 char *endptr;
6454
6455
6456 errno = 0;
6457
6458 *doublePtr = strtod(str, &endptr);
6459
6460 return JimCheckConversion(str, endptr);
6461 }
6462
6463 static jim_wide JimPowWide(jim_wide b, jim_wide e)
6464 {
6465 jim_wide res = 1;
6466
6467
6468 if (b == 1) {
6469
6470 return 1;
6471 }
6472 if (e < 0) {
6473 if (b != -1) {
6474 return 0;
6475 }
6476 e = -e;
6477 }
6478 while (e)
6479 {
6480 if (e & 1) {
6481 res *= b;
6482 }
6483 e >>= 1;
6484 b *= b;
6485 }
6486 return res;
6487 }
6488
6489 #ifdef JIM_DEBUG_PANIC
@@ -6545,11 +6509,11 @@
6545 char *Jim_StrDupLen(const char *s, int l)
6546 {
6547 char *copy = Jim_Alloc(l + 1);
6548
6549 memcpy(copy, s, l + 1);
6550 copy[l] = 0;
6551 return copy;
6552 }
6553
6554
6555
@@ -6634,52 +6598,52 @@
6634 }
6635
6636
6637 void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
6638 {
6639 Jim_HashTable n;
6640 unsigned int realsize = JimHashTableNextPower(size), i;
6641
6642 if (size <= ht->used)
6643 return;
6644
6645 Jim_InitHashTable(&n, ht->type, ht->privdata);
6646 n.size = realsize;
6647 n.sizemask = realsize - 1;
6648 n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
6649
6650 n.uniq = ht->uniq;
6651
6652
6653 memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
6654
6655 n.used = ht->used;
6656 for (i = 0; ht->used > 0; i++) {
6657 Jim_HashEntry *he, *nextHe;
6658
6659 if (ht->table[i] == NULL)
6660 continue;
6661
6662
6663 he = ht->table[i];
6664 while (he) {
6665 unsigned int h;
6666
6667 nextHe = he->next;
6668
6669 h = Jim_HashKey(ht, he->key) & n.sizemask;
6670 he->next = n.table[h];
6671 n.table[h] = he;
6672 ht->used--;
6673
6674 he = nextHe;
6675 }
6676 }
6677 assert(ht->used == 0);
6678 Jim_Free(ht->table);
6679
6680
6681 *ht = n;
6682 }
6683
6684
6685 int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6688,11 +6652,11 @@
6688
6689 entry = JimInsertHashEntry(ht, key, 0);
6690 if (entry == NULL)
6691 return JIM_ERR;
6692
6693
6694 Jim_SetHashKey(ht, entry, key);
6695 Jim_SetHashVal(ht, entry, val);
6696 return JIM_OK;
6697 }
6698
@@ -6714,11 +6678,11 @@
6714 Jim_SetHashVal(ht, entry, val);
6715 }
6716 existed = 1;
6717 }
6718 else {
6719
6720 Jim_SetHashKey(ht, entry, key);
6721 Jim_SetHashVal(ht, entry, val);
6722 existed = 0;
6723 }
6724
@@ -6737,11 +6701,11 @@
6737 he = ht->table[h];
6738
6739 prevHe = NULL;
6740 while (he) {
6741 if (Jim_CompareHashKeys(ht, key, he->key)) {
6742
6743 if (prevHe)
6744 prevHe->next = he->next;
6745 else
6746 ht->table[h] = he->next;
6747 Jim_FreeEntryKey(ht, he);
@@ -6751,19 +6715,19 @@
6751 return JIM_OK;
6752 }
6753 prevHe = he;
6754 he = he->next;
6755 }
6756 return JIM_ERR;
6757 }
6758
6759
6760 int Jim_FreeHashTable(Jim_HashTable *ht)
6761 {
6762 unsigned int i;
6763
6764
6765 for (i = 0; ht->used > 0; i++) {
6766 Jim_HashEntry *he, *nextHe;
6767
6768 if ((he = ht->table[i]) == NULL)
6769 continue;
@@ -6774,15 +6738,15 @@
6774 Jim_Free(he);
6775 ht->used--;
6776 he = nextHe;
6777 }
6778 }
6779
6780 Jim_Free(ht->table);
6781
6782 JimResetHashTable(ht);
6783 return JIM_OK;
6784 }
6785
6786 Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
6787 {
6788 Jim_HashEntry *he;
@@ -6855,24 +6819,24 @@
6855 static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
6856 {
6857 unsigned int h;
6858 Jim_HashEntry *he;
6859
6860
6861 JimExpandHashTableIfNeeded(ht);
6862
6863
6864 h = Jim_HashKey(ht, key) & ht->sizemask;
6865
6866 he = ht->table[h];
6867 while (he) {
6868 if (Jim_CompareHashKeys(ht, key, he->key))
6869 return replace ? he : NULL;
6870 he = he->next;
6871 }
6872
6873
6874 he = Jim_Alloc(sizeof(*he));
6875 he->next = ht->table[h];
6876 ht->table[h] = he;
6877 ht->used++;
6878 he->key = NULL;
@@ -6901,16 +6865,16 @@
6901 {
6902 Jim_Free(key);
6903 }
6904
6905 static const Jim_HashTableType JimPackageHashTableType = {
6906 JimStringCopyHTHashFunction,
6907 JimStringCopyHTDup,
6908 NULL,
6909 JimStringCopyHTKeyCompare,
6910 JimStringCopyHTKeyDestructor,
6911 NULL
6912 };
6913
6914 typedef struct AssocDataValue
6915 {
6916 Jim_InterpDeleteProc *delProc;
@@ -6925,16 +6889,16 @@
6925 assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
6926 Jim_Free(data);
6927 }
6928
6929 static const Jim_HashTableType JimAssocDataHashTableType = {
6930 JimStringCopyHTHashFunction,
6931 JimStringCopyHTDup,
6932 NULL,
6933 JimStringCopyHTKeyCompare,
6934 JimStringCopyHTKeyDestructor,
6935 JimAssocDataHashTableValueDestructor
6936 };
6937
6938 void Jim_InitStack(Jim_Stack *stack)
6939 {
6940 stack->len = 0;
@@ -6987,61 +6951,56 @@
6987 freeFunc(stack->vector[i]);
6988 }
6989
6990
6991
6992 #define JIM_TT_NONE 0
6993 #define JIM_TT_STR 1
6994 #define JIM_TT_ESC 2
6995 #define JIM_TT_VAR 3
6996 #define JIM_TT_DICTSUGAR 4
6997 #define JIM_TT_CMD 5
6998
6999 #define JIM_TT_SEP 6
7000 #define JIM_TT_EOL 7
7001 #define JIM_TT_EOF 8
7002
7003 #define JIM_TT_LINE 9
7004 #define JIM_TT_WORD 10
7005
7006
7007 #define JIM_TT_SUBEXPR_START 11
7008 #define JIM_TT_SUBEXPR_END 12
7009 #define JIM_TT_SUBEXPR_COMMA 13
7010 #define JIM_TT_EXPR_INT 14
7011 #define JIM_TT_EXPR_DOUBLE 15
7012 #define JIM_TT_EXPR_BOOLEAN 16
7013
7014 #define JIM_TT_EXPRSUGAR 17
7015
7016
7017 #define JIM_TT_EXPR_OP 20
7018
7019 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
7020
7021 #define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA)
7022
7023 #define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP)
7024
7025 struct JimParseMissing {
7026 int ch;
7027 int line;
7028 };
7029
7030 struct JimParserCtx
7031 {
7032 const char *p;
7033 int len;
7034 int linenr;
7035 const char *tstart;
7036 const char *tend;
7037 int tline;
7038 int tt;
7039 int eof;
7040 int inquote;
7041 int comment;
7042 struct JimParseMissing missing;
7043 };
7044
7045 static int JimParseScript(struct JimParserCtx *pc);
7046 static int JimParseSep(struct JimParserCtx *pc);
7047 static int JimParseEol(struct JimParserCtx *pc);
@@ -7071,11 +7030,11 @@
7071 pc->missing.line = linenr;
7072 }
7073
7074 static int JimParseScript(struct JimParserCtx *pc)
7075 {
7076 while (1) {
7077 if (!pc->len) {
7078 pc->tstart = pc->p;
7079 pc->tend = pc->p - 1;
7080 pc->tline = pc->linenr;
7081 pc->tt = JIM_TT_EOL;
@@ -7107,11 +7066,11 @@
7107 pc->comment = 0;
7108 return JimParseCmd(pc);
7109 case '$':
7110 pc->comment = 0;
7111 if (JimParseVar(pc) == JIM_ERR) {
7112
7113 pc->tstart = pc->tend = pc->p++;
7114 pc->len--;
7115 pc->tt = JIM_TT_ESC;
7116 }
7117 return JIM_OK;
@@ -7168,11 +7127,11 @@
7168
7169 static void JimParseSubBrace(struct JimParserCtx *pc)
7170 {
7171 int level = 1;
7172
7173
7174 pc->p++;
7175 pc->len--;
7176 while (pc->len) {
7177 switch (*pc->p) {
7178 case '\\':
@@ -7212,11 +7171,11 @@
7212 static int JimParseSubQuote(struct JimParserCtx *pc)
7213 {
7214 int tt = JIM_TT_STR;
7215 int line = pc->tline;
7216
7217
7218 pc->p++;
7219 pc->len--;
7220 while (pc->len) {
7221 switch (*pc->p) {
7222 case '\\':
@@ -7261,11 +7220,11 @@
7261 {
7262 int level = 1;
7263 int startofword = 1;
7264 int line = pc->tline;
7265
7266
7267 pc->p++;
7268 pc->len--;
7269 while (pc->len) {
7270 switch (*pc->p) {
7271 case '\\':
@@ -7341,17 +7300,17 @@
7341 return JIM_OK;
7342 }
7343
7344 static int JimParseVar(struct JimParserCtx *pc)
7345 {
7346
7347 pc->p++;
7348 pc->len--;
7349
7350 #ifdef EXPRSUGAR_BRACKET
7351 if (*pc->p == '[') {
7352
7353 JimParseCmd(pc);
7354 pc->tt = JIM_TT_EXPRSUGAR;
7355 return JIM_OK;
7356 }
7357 #endif
@@ -7377,11 +7336,11 @@
7377 pc->len--;
7378 }
7379 }
7380 else {
7381 while (1) {
7382
7383 if (pc->p[0] == ':' && pc->p[1] == ':') {
7384 while (*pc->p == ':') {
7385 pc->p++;
7386 pc->len--;
7387 }
@@ -7392,11 +7351,11 @@
7392 pc->len--;
7393 continue;
7394 }
7395 break;
7396 }
7397
7398 if (*pc->p == '(') {
7399 int count = 1;
7400 const char *paren = NULL;
7401
7402 pc->tt = JIM_TT_DICTSUGAR;
@@ -7419,11 +7378,11 @@
7419 if (count == 0) {
7420 pc->p++;
7421 pc->len--;
7422 }
7423 else if (paren) {
7424
7425 paren++;
7426 pc->len += (pc->p - paren);
7427 pc->p = paren;
7428 }
7429 #ifndef EXPRSUGAR_BRACKET
@@ -7444,19 +7403,19 @@
7444
7445 static int JimParseStr(struct JimParserCtx *pc)
7446 {
7447 if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
7448 pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
7449
7450 if (*pc->p == '{') {
7451 return JimParseBrace(pc);
7452 }
7453 if (*pc->p == '"') {
7454 pc->inquote = 1;
7455 pc->p++;
7456 pc->len--;
7457
7458 pc->missing.line = pc->tline;
7459 }
7460 }
7461 pc->tstart = pc->p;
7462 pc->tline = pc->linenr;
@@ -7482,25 +7441,25 @@
7482 }
7483 pc->p++;
7484 pc->len--;
7485 }
7486 else if (pc->len == 1) {
7487
7488 pc->missing.ch = '\\';
7489 }
7490 break;
7491 case '(':
7492
7493 if (pc->len > 1 && pc->p[1] != '$') {
7494 break;
7495 }
7496
7497 case ')':
7498
7499 if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
7500 if (pc->p == pc->tstart) {
7501
7502 pc->p++;
7503 pc->len--;
7504 }
7505 pc->tend = pc->p - 1;
7506 pc->tt = JIM_TT_ESC;
@@ -7540,11 +7499,11 @@
7540 break;
7541 }
7542 pc->p++;
7543 pc->len--;
7544 }
7545 return JIM_OK;
7546 }
7547
7548 static int JimParseComment(struct JimParserCtx *pc)
7549 {
7550 while (*pc->p) {
@@ -7651,34 +7610,34 @@
7651 if (c == -1) {
7652 break;
7653 }
7654 val = (val << 4) | c;
7655 }
7656
7657 if (s[i] == '{') {
7658 if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
7659
7660 i--;
7661 k = 0;
7662 }
7663 else {
7664
7665 k++;
7666 }
7667 }
7668 if (k) {
7669
7670 if (s[i] == 'x') {
7671 *p++ = val;
7672 }
7673 else {
7674 p += utf8_fromunicode(p, val);
7675 }
7676 i += k;
7677 break;
7678 }
7679
7680 *p++ = s[i];
7681 }
7682 break;
7683 case 'v':
7684 *p++ = 0xb;
@@ -7687,11 +7646,11 @@
7687 case '\0':
7688 *p++ = '\\';
7689 i++;
7690 break;
7691 case '\n':
7692
7693 *p++ = ' ';
7694 do {
7695 i++;
7696 } while (s[i + 1] == ' ' || s[i + 1] == '\t');
7697 break;
@@ -7701,11 +7660,11 @@
7701 case '3':
7702 case '4':
7703 case '5':
7704 case '6':
7705 case '7':
7706
7707 {
7708 int val = 0;
7709 int c = odigitval(s[i + 1]);
7710
7711 val = c;
@@ -7758,16 +7717,16 @@
7758 }
7759 else {
7760 len = (end - start) + 1;
7761 token = Jim_Alloc(len + 1);
7762 if (pc->tt != JIM_TT_ESC) {
7763
7764 memcpy(token, start, len);
7765 token[len] = '\0';
7766 }
7767 else {
7768
7769 len = JimEscape(token, start, len);
7770 }
7771 }
7772
7773 return Jim_NewStringObjNoAlloc(interp, token, len);
@@ -7831,11 +7790,11 @@
7831 while (pc->len) {
7832 switch (*pc->p) {
7833 case '\\':
7834 pc->tt = JIM_TT_ESC;
7835 if (--pc->len == 0) {
7836
7837 pc->tend = pc->p;
7838 return JIM_OK;
7839 }
7840 pc->p++;
7841 break;
@@ -7867,11 +7826,11 @@
7867 pc->tend = pc->p - 1;
7868 return JIM_OK;
7869 }
7870 if (*pc->p == '\\') {
7871 if (--pc->len == 0) {
7872
7873 pc->tend = pc->p;
7874 return JIM_OK;
7875 }
7876 pc->tt = JIM_TT_ESC;
7877 pc->p++;
@@ -7887,24 +7846,24 @@
7887
7888 Jim_Obj *Jim_NewObj(Jim_Interp *interp)
7889 {
7890 Jim_Obj *objPtr;
7891
7892
7893 if (interp->freeList != NULL) {
7894
7895 objPtr = interp->freeList;
7896 interp->freeList = objPtr->nextObjPtr;
7897 }
7898 else {
7899
7900 objPtr = Jim_Alloc(sizeof(*objPtr));
7901 }
7902
7903 objPtr->refCount = 0;
7904
7905
7906 objPtr->prevObjPtr = NULL;
7907 objPtr->nextObjPtr = interp->liveList;
7908 if (interp->liveList)
7909 interp->liveList->prevObjPtr = objPtr;
7910 interp->liveList = objPtr;
@@ -7912,32 +7871,32 @@
7912 return objPtr;
7913 }
7914
7915 void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
7916 {
7917
7918 JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
7919 objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>"));
7920
7921
7922 Jim_FreeIntRep(interp, objPtr);
7923
7924 if (objPtr->bytes != NULL) {
7925 if (objPtr->bytes != JimEmptyStringRep)
7926 Jim_Free(objPtr->bytes);
7927 }
7928
7929 if (objPtr->prevObjPtr)
7930 objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
7931 if (objPtr->nextObjPtr)
7932 objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
7933 if (interp->liveList == objPtr)
7934 interp->liveList = objPtr->nextObjPtr;
7935 #ifdef JIM_DISABLE_OBJECT_POOL
7936 Jim_Free(objPtr);
7937 #else
7938
7939 objPtr->prevObjPtr = NULL;
7940 objPtr->nextObjPtr = interp->freeList;
7941 if (interp->freeList)
7942 interp->freeList->prevObjPtr = objPtr;
7943 interp->freeList = objPtr;
@@ -7960,45 +7919,45 @@
7960 {
7961 Jim_Obj *dupPtr;
7962
7963 dupPtr = Jim_NewObj(interp);
7964 if (objPtr->bytes == NULL) {
7965
7966 dupPtr->bytes = NULL;
7967 }
7968 else if (objPtr->length == 0) {
7969
7970 dupPtr->bytes = JimEmptyStringRep;
7971 dupPtr->length = 0;
7972 dupPtr->typePtr = NULL;
7973 return dupPtr;
7974 }
7975 else {
7976 dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
7977 dupPtr->length = objPtr->length;
7978
7979 memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
7980 }
7981
7982
7983 dupPtr->typePtr = objPtr->typePtr;
7984 if (objPtr->typePtr != NULL) {
7985 if (objPtr->typePtr->dupIntRepProc == NULL) {
7986 dupPtr->internalRep = objPtr->internalRep;
7987 }
7988 else {
7989
7990 objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
7991 }
7992 }
7993 return dupPtr;
7994 }
7995
7996 const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
7997 {
7998 if (objPtr->bytes == NULL) {
7999
8000 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
8001 objPtr->typePtr->updateStringProc(objPtr);
8002 }
8003 if (lenPtr)
8004 *lenPtr = objPtr->length;
@@ -8007,11 +7966,11 @@
8007
8008
8009 int Jim_Length(Jim_Obj *objPtr)
8010 {
8011 if (objPtr->bytes == NULL) {
8012
8013 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
8014 objPtr->typePtr->updateStringProc(objPtr);
8015 }
8016 return objPtr->length;
8017 }
@@ -8018,11 +7977,11 @@
8018
8019
8020 const char *Jim_String(Jim_Obj *objPtr)
8021 {
8022 if (objPtr->bytes == NULL) {
8023
8024 JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
8025 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
8026 objPtr->typePtr->updateStringProc(objPtr);
8027 }
8028 return objPtr->bytes;
@@ -8078,22 +8037,22 @@
8078 }
8079
8080 static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
8081 {
8082 if (objPtr->typePtr != &stringObjType) {
8083
8084 if (objPtr->bytes == NULL) {
8085
8086 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
8087 objPtr->typePtr->updateStringProc(objPtr);
8088 }
8089
8090 Jim_FreeIntRep(interp, objPtr);
8091
8092 objPtr->typePtr = &stringObjType;
8093 objPtr->internalRep.strValue.maxLength = objPtr->length;
8094
8095 objPtr->internalRep.strValue.charLength = -1;
8096 }
8097 return JIM_OK;
8098 }
8099
@@ -8114,14 +8073,14 @@
8114
8115 Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
8116 {
8117 Jim_Obj *objPtr = Jim_NewObj(interp);
8118
8119
8120 if (len == -1)
8121 len = strlen(s);
8122
8123 if (len == 0) {
8124 objPtr->bytes = JimEmptyStringRep;
8125 }
8126 else {
8127 objPtr->bytes = Jim_Alloc(len + 1);
@@ -8128,25 +8087,25 @@
8128 memcpy(objPtr->bytes, s, len);
8129 objPtr->bytes[len] = '\0';
8130 }
8131 objPtr->length = len;
8132
8133
8134 objPtr->typePtr = NULL;
8135 return objPtr;
8136 }
8137
8138
8139 Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
8140 {
8141 #ifdef JIM_UTF8
8142
8143 int bytelen = utf8_index(s, charlen);
8144
8145 Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
8146
8147
8148 objPtr->typePtr = &stringObjType;
8149 objPtr->internalRep.strValue.maxLength = bytelen;
8150 objPtr->internalRep.strValue.charLength = charlen;
8151
8152 return objPtr;
@@ -8173,11 +8132,11 @@
8173 len = strlen(str);
8174 needlen = objPtr->length + len;
8175 if (objPtr->internalRep.strValue.maxLength < needlen ||
8176 objPtr->internalRep.strValue.maxLength == 0) {
8177 needlen *= 2;
8178
8179 if (needlen < 7) {
8180 needlen = 7;
8181 }
8182 if (objPtr->bytes == JimEmptyStringRep) {
8183 objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8189,11 +8148,11 @@
8189 }
8190 memcpy(objPtr->bytes + objPtr->length, str, len);
8191 objPtr->bytes[objPtr->length + len] = '\0';
8192
8193 if (objPtr->internalRep.strValue.charLength >= 0) {
8194
8195 objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
8196 }
8197 objPtr->length += len;
8198 }
8199
@@ -8251,11 +8210,11 @@
8251 int l1, l2;
8252 const char *s1 = Jim_GetString(firstObjPtr, &l1);
8253 const char *s2 = Jim_GetString(secondObjPtr, &l2);
8254
8255 if (nocase) {
8256
8257 return JimStringCompareLen(s1, s2, -1, nocase);
8258 }
8259 return JimStringCompare(s1, l1, s2, l2);
8260 }
8261
@@ -8353,11 +8312,11 @@
8353
8354 if (first == 0 && rangeLen == len) {
8355 return strObjPtr;
8356 }
8357 if (len == bytelen) {
8358
8359 return Jim_NewStringObj(interp, str + first, rangeLen);
8360 }
8361 return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
8362 #else
8363 return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8382,19 +8341,19 @@
8382 return strObjPtr;
8383 }
8384
8385 str = Jim_String(strObjPtr);
8386
8387
8388 objPtr = Jim_NewStringObjUtf8(interp, str, first);
8389
8390
8391 if (newStrObj) {
8392 Jim_AppendObj(interp, objPtr, newStrObj);
8393 }
8394
8395
8396 Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
8397
8398 return objPtr;
8399 }
8400
@@ -8493,11 +8452,11 @@
8493 while (len) {
8494 int c;
8495 int n = utf8_tounicode(str, &c);
8496
8497 if (utf8_memchr(trimchars, trimlen, c) == NULL) {
8498
8499 break;
8500 }
8501 str += n;
8502 len -= n;
8503 }
@@ -8564,41 +8523,41 @@
8564
8565 len = Jim_Length(strObjPtr);
8566 nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
8567
8568 if (nontrim == NULL) {
8569
8570 return Jim_NewEmptyStringObj(interp);
8571 }
8572 if (nontrim == strObjPtr->bytes + len) {
8573
8574 return strObjPtr;
8575 }
8576
8577 if (Jim_IsShared(strObjPtr)) {
8578 strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
8579 }
8580 else {
8581
8582 strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
8583 strObjPtr->length = (nontrim - strObjPtr->bytes);
8584 }
8585
8586 return strObjPtr;
8587 }
8588
8589 static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
8590 {
8591
8592 Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
8593
8594
8595 strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
8596
8597
8598 if (objPtr != strObjPtr && objPtr->refCount == 0) {
8599
8600 Jim_FreeNewObj(interp, objPtr);
8601 }
8602
8603 return strObjPtr;
8604 }
@@ -8616,17 +8575,17 @@
8616 static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
8617 {
8618 static const char * const strclassnames[] = {
8619 "integer", "alpha", "alnum", "ascii", "digit",
8620 "double", "lower", "upper", "space", "xdigit",
8621 "control", "print", "graph", "punct", "boolean",
8622 NULL
8623 };
8624 enum {
8625 STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
8626 STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
8627 STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN,
8628 };
8629 int strclass;
8630 int len;
8631 int i;
8632 const char *str;
@@ -8655,17 +8614,10 @@
8655 double d;
8656 Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
8657 return JIM_OK;
8658 }
8659
8660 case STR_IS_BOOLEAN:
8661 {
8662 int b;
8663 Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK);
8664 return JIM_OK;
8665 }
8666
8667 case STR_IS_ALPHA: isclassfunc = isalpha; break;
8668 case STR_IS_ALNUM: isclassfunc = isalnum; break;
8669 case STR_IS_ASCII: isclassfunc = jim_isascii; break;
8670 case STR_IS_DIGIT: isclassfunc = isdigit; break;
8671 case STR_IS_LOWER: isclassfunc = islower; break;
@@ -8713,11 +8665,11 @@
8713
8714 if (objPtr->typePtr != &comparedStringObjType) {
8715 Jim_FreeIntRep(interp, objPtr);
8716 objPtr->typePtr = &comparedStringObjType;
8717 }
8718 objPtr->internalRep.ptr = (char *)str;
8719 return 1;
8720 }
8721 }
8722
8723 static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8806,20 +8758,20 @@
8806 int type;
8807 } ScriptToken;
8808
8809 typedef struct ScriptObj
8810 {
8811 ScriptToken *token;
8812 Jim_Obj *fileNameObj;
8813 int len;
8814 int substFlags;
8815 int inUse; /* Used to share a ScriptObj. Currently
8816 only used by Jim_EvalObj() as protection against
8817 shimmering of the currently evaluated object. */
8818 int firstline;
8819 int linenr;
8820 int missing;
8821 } ScriptObj;
8822
8823 static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
8824 static int JimParseCheckMissing(Jim_Interp *interp, int ch);
8825 static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -8847,23 +8799,23 @@
8847 dupPtr->typePtr = NULL;
8848 }
8849
8850 typedef struct
8851 {
8852 const char *token;
8853 int len;
8854 int type;
8855 int line;
8856 } ParseToken;
8857
8858 typedef struct
8859 {
8860
8861 ParseToken *list;
8862 int size;
8863 int count;
8864 ParseToken static_list[20];
8865 } ParseTokenList;
8866
8867 static void ScriptTokenListInit(ParseTokenList *tokenlist)
8868 {
8869 tokenlist->list = tokenlist->static_list;
@@ -8882,18 +8834,18 @@
8882 int line)
8883 {
8884 ParseToken *t;
8885
8886 if (tokenlist->count == tokenlist->size) {
8887
8888 tokenlist->size *= 2;
8889 if (tokenlist->list != tokenlist->static_list) {
8890 tokenlist->list =
8891 Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
8892 }
8893 else {
8894
8895 tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
8896 memcpy(tokenlist->list, tokenlist->static_list,
8897 tokenlist->count * sizeof(*tokenlist->list));
8898 }
8899 }
@@ -8907,20 +8859,20 @@
8907 static int JimCountWordTokens(ParseToken *t)
8908 {
8909 int expand = 1;
8910 int count = 0;
8911
8912
8913 if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
8914 if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
8915
8916 expand = -1;
8917 t++;
8918 }
8919 }
8920
8921
8922 while (!TOKEN_IS_SEP(t->type)) {
8923 t++;
8924 count++;
8925 }
8926
@@ -8930,11 +8882,11 @@
8930 static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
8931 {
8932 Jim_Obj *objPtr;
8933
8934 if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
8935
8936 int len = t->len;
8937 char *str = Jim_Alloc(len + 1);
8938 len = JimEscape(str, t->token, len);
8939 objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
8940 }
@@ -8947,13 +8899,13 @@
8947 static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
8948 ParseTokenList *tokenlist)
8949 {
8950 int i;
8951 struct ScriptToken *token;
8952
8953 int lineargs = 0;
8954
8955 ScriptToken *linefirst;
8956 int count;
8957 int linenr;
8958
8959 #ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8962,11 +8914,11 @@
8962 printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
8963 tokenlist->list[i].len, tokenlist->list[i].token);
8964 }
8965 #endif
8966
8967
8968 count = tokenlist->count;
8969 for (i = 0; i < tokenlist->count; i++) {
8970 if (tokenlist->list[i].type == JIM_TT_EOL) {
8971 count++;
8972 }
@@ -8973,59 +8925,59 @@
8973 }
8974 linenr = script->firstline = tokenlist->list[0].line;
8975
8976 token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
8977
8978
8979 linefirst = token++;
8980
8981 for (i = 0; i < tokenlist->count; ) {
8982
8983 int wordtokens;
8984
8985
8986 while (tokenlist->list[i].type == JIM_TT_SEP) {
8987 i++;
8988 }
8989
8990 wordtokens = JimCountWordTokens(tokenlist->list + i);
8991
8992 if (wordtokens == 0) {
8993
8994 if (lineargs) {
8995 linefirst->type = JIM_TT_LINE;
8996 linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
8997 Jim_IncrRefCount(linefirst->objPtr);
8998
8999
9000 lineargs = 0;
9001 linefirst = token++;
9002 }
9003 i++;
9004 continue;
9005 }
9006 else if (wordtokens != 1) {
9007
9008 token->type = JIM_TT_WORD;
9009 token->objPtr = Jim_NewIntObj(interp, wordtokens);
9010 Jim_IncrRefCount(token->objPtr);
9011 token++;
9012 if (wordtokens < 0) {
9013
9014 i++;
9015 wordtokens = -wordtokens - 1;
9016 lineargs--;
9017 }
9018 }
9019
9020 if (lineargs == 0) {
9021
9022 linenr = tokenlist->list[i].line;
9023 }
9024 lineargs++;
9025
9026
9027 while (wordtokens--) {
9028 const ParseToken *t = &tokenlist->list[i++];
9029
9030 token->type = t->type;
9031 token->objPtr = JimMakeScriptObj(interp, t);
@@ -9097,11 +9049,11 @@
9097 token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
9098
9099 for (i = 0; i < tokenlist->count; i++) {
9100 const ParseToken *t = &tokenlist->list[i];
9101
9102
9103 token->type = t->type;
9104 token->objPtr = JimMakeScriptObj(interp, t);
9105 Jim_IncrRefCount(token->objPtr);
9106 token++;
9107 }
@@ -9116,29 +9068,29 @@
9116 struct JimParserCtx parser;
9117 struct ScriptObj *script;
9118 ParseTokenList tokenlist;
9119 int line = 1;
9120
9121
9122 if (objPtr->typePtr == &sourceObjType) {
9123 line = objPtr->internalRep.sourceValue.lineNumber;
9124 }
9125
9126
9127 ScriptTokenListInit(&tokenlist);
9128
9129 JimParserInit(&parser, scriptText, scriptTextLen, line);
9130 while (!parser.eof) {
9131 JimParseScript(&parser);
9132 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
9133 parser.tline);
9134 }
9135
9136
9137 ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
9138
9139
9140 script = Jim_Alloc(sizeof(*script));
9141 memset(script, 0, sizeof(*script));
9142 script->inUse = 1;
9143 if (objPtr->typePtr == &sourceObjType) {
9144 script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -9150,14 +9102,14 @@
9150 script->missing = parser.missing.ch;
9151 script->linenr = parser.missing.line;
9152
9153 ScriptObjAddTokens(interp, script, &tokenlist);
9154
9155
9156 ScriptTokenListFree(&tokenlist);
9157
9158
9159 Jim_FreeIntRep(interp, objPtr);
9160 Jim_SetIntRepPtr(objPtr, script);
9161 objPtr->typePtr = &scriptObjType;
9162 }
9163
@@ -9164,11 +9116,11 @@
9164 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
9165
9166 static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
9167 {
9168 if (objPtr == interp->emptyObj) {
9169
9170 objPtr = interp->nullScriptObj;
9171 }
9172
9173 if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
9174 JimSetScriptFromAny(interp, objPtr);
@@ -9203,17 +9155,17 @@
9203 Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
9204 Jim_Free(cmdPtr->u.proc.staticVars);
9205 }
9206 }
9207 else {
9208
9209 if (cmdPtr->u.native.delProc) {
9210 cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
9211 }
9212 }
9213 if (cmdPtr->prevCmd) {
9214
9215 JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
9216 }
9217 Jim_Free(cmdPtr);
9218 }
9219 }
@@ -9224,46 +9176,46 @@
9224 Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
9225 Jim_Free(val);
9226 }
9227
9228 static const Jim_HashTableType JimVariablesHashTableType = {
9229 JimStringCopyHTHashFunction,
9230 JimStringCopyHTDup,
9231 NULL,
9232 JimStringCopyHTKeyCompare,
9233 JimStringCopyHTKeyDestructor,
9234 JimVariablesHTValDestructor
9235 };
9236
9237 static void JimCommandsHT_ValDestructor(void *interp, void *val)
9238 {
9239 JimDecrCmdRefCount(interp, val);
9240 }
9241
9242 static const Jim_HashTableType JimCommandsHashTableType = {
9243 JimStringCopyHTHashFunction,
9244 JimStringCopyHTDup,
9245 NULL,
9246 JimStringCopyHTKeyCompare,
9247 JimStringCopyHTKeyDestructor,
9248 JimCommandsHT_ValDestructor
9249 };
9250
9251
9252
9253 #ifdef jim_ext_namespace
9254 static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
9255 {
9256 const char *name = Jim_String(nsObj);
9257 if (name[0] == ':' && name[1] == ':') {
9258
9259 while (*++name == ':') {
9260 }
9261 nsObj = Jim_NewStringObj(interp, name, -1);
9262 }
9263 else if (Jim_Length(interp->framePtr->nsObj)) {
9264
9265 nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9266 Jim_AppendStrings(interp, nsObj, "::", name, NULL);
9267 }
9268 return nsObj;
9269 }
@@ -9287,16 +9239,16 @@
9287 static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
9288 {
9289 Jim_Obj *objPtr = interp->emptyObj;
9290
9291 if (name[0] == ':' && name[1] == ':') {
9292
9293 while (*++name == ':') {
9294 }
9295 }
9296 else if (Jim_Length(interp->framePtr->nsObj)) {
9297
9298 objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9299 Jim_AppendStrings(interp, objPtr, "::", name, NULL);
9300 name = Jim_String(objPtr);
9301 }
9302 Jim_IncrRefCount(objPtr);
@@ -9305,11 +9257,11 @@
9305 }
9306
9307 #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
9308
9309 #else
9310
9311 #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
9312 #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
9313
9314 Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
9315 {
@@ -9324,17 +9276,17 @@
9324
9325 Jim_InterpIncrProcEpoch(interp);
9326 }
9327
9328 if (he && interp->local) {
9329
9330 cmd->prevCmd = Jim_GetHashEntryVal(he);
9331 Jim_SetHashVal(&interp->commands, he, cmd);
9332 }
9333 else {
9334 if (he) {
9335
9336 Jim_DeleteHashEntry(&interp->commands, name);
9337 }
9338
9339 Jim_AddHashEntry(&interp->commands, name, cmd);
9340 }
@@ -9345,11 +9297,11 @@
9345 int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
9346 Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
9347 {
9348 Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
9349
9350
9351 memset(cmdPtr, 0, sizeof(*cmdPtr));
9352 cmdPtr->inUse = 1;
9353 cmdPtr->u.native.delProc = delProc;
9354 cmdPtr->u.native.cmdProc = cmdProc;
9355 cmdPtr->u.native.privData = privData;
@@ -9374,11 +9326,11 @@
9374 Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
9375 Jim_Var *varPtr;
9376 int subLen;
9377
9378 objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
9379
9380 subLen = Jim_ListLength(interp, objPtr);
9381 if (subLen == 1 || subLen == 2) {
9382 nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
9383 if (subLen == 1) {
9384 initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9420,19 +9372,19 @@
9420
9421 static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
9422 {
9423 #ifdef jim_ext_namespace
9424 if (cmdPtr->isproc) {
9425
9426 const char *pt = strrchr(cmdname, ':');
9427 if (pt && pt != cmdname && pt[-1] == ':') {
9428 Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
9429 cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
9430 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9431
9432 if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
9433
9434 Jim_InterpIncrProcEpoch(interp);
9435 }
9436 }
9437 }
9438 #endif
@@ -9445,11 +9397,11 @@
9445 int argListLen;
9446 int i;
9447
9448 argListLen = Jim_ListLength(interp, argListObjPtr);
9449
9450
9451 cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
9452 memset(cmdPtr, 0, sizeof(*cmdPtr));
9453 cmdPtr->inUse = 1;
9454 cmdPtr->isproc = 1;
9455 cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9460,24 +9412,24 @@
9460 cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
9461 Jim_IncrRefCount(argListObjPtr);
9462 Jim_IncrRefCount(bodyObjPtr);
9463 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9464
9465
9466 if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
9467 goto err;
9468 }
9469
9470
9471
9472 for (i = 0; i < argListLen; i++) {
9473 Jim_Obj *argPtr;
9474 Jim_Obj *nameObjPtr;
9475 Jim_Obj *defaultObjPtr;
9476 int len;
9477
9478
9479 argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
9480 len = Jim_ListLength(interp, argPtr);
9481 if (len == 0) {
9482 Jim_SetResultString(interp, "argument with no name", -1);
9483 err:
@@ -9488,16 +9440,16 @@
9488 Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
9489 goto err;
9490 }
9491
9492 if (len == 2) {
9493
9494 nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
9495 defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
9496 }
9497 else {
9498
9499 nameObjPtr = argPtr;
9500 defaultObjPtr = NULL;
9501 }
9502
9503
@@ -9558,29 +9510,29 @@
9558 }
9559
9560 fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
9561 fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
9562
9563
9564 he = Jim_FindHashEntry(&interp->commands, fqold);
9565 if (he == NULL) {
9566 Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
9567 }
9568 else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
9569 Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
9570 }
9571 else {
9572
9573 cmdPtr = Jim_GetHashEntryVal(he);
9574 JimIncrCmdRefCount(cmdPtr);
9575 JimUpdateProcNamespace(interp, cmdPtr, fqnew);
9576 Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
9577
9578
9579 Jim_DeleteHashEntry(&interp->commands, fqold);
9580
9581
9582 Jim_InterpIncrProcEpoch(interp);
9583
9584 ret = JIM_OK;
9585 }
9586
@@ -9619,23 +9571,23 @@
9619 objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
9620 #ifdef jim_ext_namespace
9621 || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
9622 #endif
9623 ) {
 
9624
9625
9626
9627 const char *name = Jim_String(objPtr);
9628 Jim_HashEntry *he;
9629
9630 if (name[0] == ':' && name[1] == ':') {
9631 while (*++name == ':') {
9632 }
9633 }
9634 #ifdef jim_ext_namespace
9635 else if (Jim_Length(interp->framePtr->nsObj)) {
9636
9637 Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9638 Jim_AppendStrings(interp, nameObj, "::", name, NULL);
9639 he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
9640 Jim_FreeNewObj(interp, nameObj);
9641 if (he) {
@@ -9642,11 +9594,11 @@
9642 goto found;
9643 }
9644 }
9645 #endif
9646
9647
9648 he = Jim_FindHashEntry(&interp->commands, name);
9649 if (he == NULL) {
9650 if (flags & JIM_ERRMSG) {
9651 Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
9652 }
@@ -9655,11 +9607,11 @@
9655 #ifdef jim_ext_namespace
9656 found:
9657 #endif
9658 cmd = Jim_GetHashEntryVal(he);
9659
9660
9661 Jim_FreeIntRep(interp, objPtr);
9662 objPtr->typePtr = &commandObjType;
9663 objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
9664 objPtr->internalRep.cmdValue.cmdPtr = cmd;
9665 objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9674,11 +9626,11 @@
9674 return cmd;
9675 }
9676
9677
9678
9679 #define JIM_DICT_SUGAR 100
9680
9681 static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
9682
9683 static const Jim_ObjType variableObjType = {
9684 "variable",
@@ -9688,11 +9640,11 @@
9688 JIM_TYPE_REFERENCES,
9689 };
9690
9691 static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
9692 {
9693
9694 if (nameObjPtr->typePtr != &variableObjType) {
9695 int len;
9696 const char *str = Jim_GetString(nameObjPtr, &len);
9697 if (memchr(str, '\0', len)) {
9698 Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9708,18 +9660,18 @@
9708 Jim_CallFrame *framePtr;
9709 Jim_HashEntry *he;
9710 int global;
9711 int len;
9712
9713
9714 if (objPtr->typePtr == &variableObjType) {
9715 framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
9716 if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
9717
9718 return JIM_OK;
9719 }
9720
9721 }
9722 else if (objPtr->typePtr == &dictSubstObjType) {
9723 return JIM_DICT_SUGAR;
9724 }
9725 else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9727,11 +9679,11 @@
9727 }
9728
9729
9730 varName = Jim_GetString(objPtr, &len);
9731
9732
9733 if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
9734 return JIM_DICT_SUGAR;
9735 }
9736
9737 if (varName[0] == ':' && varName[1] == ':') {
@@ -9743,23 +9695,23 @@
9743 else {
9744 global = 0;
9745 framePtr = interp->framePtr;
9746 }
9747
9748
9749 he = Jim_FindHashEntry(&framePtr->vars, varName);
9750 if (he == NULL) {
9751 if (!global && framePtr->staticVars) {
9752
9753 he = Jim_FindHashEntry(framePtr->staticVars, varName);
9754 }
9755 if (he == NULL) {
9756 return JIM_ERR;
9757 }
9758 }
9759
9760
9761 Jim_FreeIntRep(interp, objPtr);
9762 objPtr->typePtr = &variableObjType;
9763 objPtr->internalRep.varValue.callFrameId = framePtr->id;
9764 objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
9765 objPtr->internalRep.varValue.global = global;
@@ -9774,11 +9726,11 @@
9774 {
9775 const char *name;
9776 Jim_CallFrame *framePtr;
9777 int global;
9778
9779
9780 Jim_Var *var = Jim_Alloc(sizeof(*var));
9781
9782 var->objPtr = valObjPtr;
9783 Jim_IncrRefCount(valObjPtr);
9784 var->linkFramePtr = NULL;
@@ -9793,14 +9745,14 @@
9793 else {
9794 framePtr = interp->framePtr;
9795 global = 0;
9796 }
9797
9798
9799 Jim_AddHashEntry(&framePtr->vars, name, var);
9800
9801
9802 Jim_FreeIntRep(interp, nameObjPtr);
9803 nameObjPtr->typePtr = &variableObjType;
9804 nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
9805 nameObjPtr->internalRep.varValue.varPtr = var;
9806 nameObjPtr->internalRep.varValue.global = global;
@@ -9830,11 +9782,11 @@
9830 if (var->linkFramePtr == NULL) {
9831 Jim_IncrRefCount(valObjPtr);
9832 Jim_DecrRefCount(interp, var->objPtr);
9833 var->objPtr = valObjPtr;
9834 }
9835 else {
9836 Jim_CallFrame *savedCallFrame;
9837
9838 savedCallFrame = interp->framePtr;
9839 interp->framePtr = var->linkFramePtr;
9840 err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9891,14 +9843,14 @@
9891 const char *varName;
9892 const char *targetName;
9893 Jim_CallFrame *framePtr;
9894 Jim_Var *varPtr;
9895
9896
9897 switch (SetVariableFromAny(interp, nameObjPtr)) {
9898 case JIM_DICT_SUGAR:
9899
9900 Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
9901 return JIM_ERR;
9902
9903 case JIM_OK:
9904 varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9906,23 +9858,23 @@
9906 if (varPtr->linkFramePtr == NULL) {
9907 Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
9908 return JIM_ERR;
9909 }
9910
9911
9912 varPtr->linkFramePtr = NULL;
9913 break;
9914 }
9915
9916
9917
9918 varName = Jim_String(nameObjPtr);
9919
9920 if (varName[0] == ':' && varName[1] == ':') {
9921 while (*++varName == ':') {
9922 }
9923
9924 framePtr = interp->topFramePtr;
9925 }
9926 else {
9927 framePtr = interp->framePtr;
9928 }
@@ -9942,15 +9894,15 @@
9942 nameObjPtr);
9943 Jim_DecrRefCount(interp, targetNameObjPtr);
9944 return JIM_ERR;
9945 }
9946
9947
9948 if (framePtr == targetCallFrame) {
9949 Jim_Obj *objPtr = targetNameObjPtr;
9950
9951
9952 while (1) {
9953 if (strcmp(Jim_String(objPtr), varName) == 0) {
9954 Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
9955 Jim_DecrRefCount(interp, targetNameObjPtr);
9956 return JIM_ERR;
@@ -9962,13 +9914,13 @@
9962 break;
9963 objPtr = varPtr->objPtr;
9964 }
9965 }
9966
9967
9968 Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
9969
9970 nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
9971 Jim_DecrRefCount(interp, targetNameObjPtr);
9972 return JIM_OK;
9973 }
9974
@@ -9982,26 +9934,26 @@
9982 return varPtr->objPtr;
9983 }
9984 else {
9985 Jim_Obj *objPtr;
9986
9987
9988 Jim_CallFrame *savedCallFrame = interp->framePtr;
9989
9990 interp->framePtr = varPtr->linkFramePtr;
9991 objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
9992 interp->framePtr = savedCallFrame;
9993 if (objPtr) {
9994 return objPtr;
9995 }
9996
9997 }
9998 }
9999 break;
10000
10001 case JIM_DICT_SUGAR:
10002
10003 return JimDictSugarGet(interp, nameObjPtr, flags);
10004 }
10005 if (flags & JIM_ERRMSG) {
10006 Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
10007 }
@@ -10051,17 +10003,17 @@
10051 int retval;
10052 Jim_CallFrame *framePtr;
10053
10054 retval = SetVariableFromAny(interp, nameObjPtr);
10055 if (retval == JIM_DICT_SUGAR) {
10056
10057 return JimDictSugarSet(interp, nameObjPtr, NULL);
10058 }
10059 else if (retval == JIM_OK) {
10060 varPtr = nameObjPtr->internalRep.varValue.varPtr;
10061
10062
10063 if (varPtr->linkFramePtr) {
10064 framePtr = interp->framePtr;
10065 interp->framePtr = varPtr->linkFramePtr;
10066 retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
10067 interp->framePtr = framePtr;
@@ -10076,11 +10028,11 @@
10076 framePtr = interp->framePtr;
10077 }
10078
10079 retval = Jim_DeleteHashEntry(&framePtr->vars, name);
10080 if (retval == JIM_OK) {
10081
10082 framePtr->id = interp->callFrameEpoch++;
10083 }
10084 }
10085 }
10086 if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -10109,11 +10061,11 @@
10109 keyLen = (str + len) - p;
10110 if (str[len - 1] == ')') {
10111 keyLen--;
10112 }
10113
10114
10115 keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
10116
10117 Jim_IncrRefCount(varObjPtr);
10118 Jim_IncrRefCount(keyObjPtr);
10119 *varPtrPtr = varObjPtr;
@@ -10128,23 +10080,23 @@
10128
10129 err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
10130 &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
10131
10132 if (err == JIM_OK) {
10133
10134 Jim_SetEmptyResult(interp);
10135 }
10136 else {
10137 if (!valObjPtr) {
10138
10139 if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
10140 Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
10141 objPtr);
10142 return err;
10143 }
10144 }
10145
10146 Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
10147 (valObjPtr ? "set" : "unset"), objPtr);
10148 }
10149 return err;
10150 }
@@ -10166,11 +10118,11 @@
10166 Jim_SetResultFormatted(interp,
10167 "can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
10168 ret < 0 ? "variable isn't" : "no such element in");
10169 }
10170 else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
10171
10172 Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
10173 }
10174
10175 return resObjPtr;
10176 }
@@ -10208,11 +10160,11 @@
10208 {
10209 if (objPtr->typePtr != &dictSubstObjType) {
10210 Jim_Obj *varObjPtr, *keyObjPtr;
10211
10212 if (objPtr->typePtr == &interpolatedObjType) {
10213
10214
10215 varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
10216 keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
10217
10218 Jim_IncrRefCount(varObjPtr);
@@ -10253,11 +10205,11 @@
10253 static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
10254 {
10255 Jim_Obj *resultObjPtr;
10256
10257 if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
10258
10259 resultObjPtr->refCount--;
10260 return resultObjPtr;
10261 }
10262 return NULL;
10263 }
@@ -10297,11 +10249,11 @@
10297 return cf;
10298 }
10299
10300 static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
10301 {
10302
10303 if (localCommands) {
10304 Jim_Obj *cmdNameObj;
10305
10306 while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
10307 Jim_HashEntry *he;
@@ -10316,20 +10268,20 @@
10316 Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
10317 if (cmd->prevCmd) {
10318 Jim_Cmd *prevCmd = cmd->prevCmd;
10319 cmd->prevCmd = NULL;
10320
10321
10322 JimDecrCmdRefCount(interp, cmd);
10323
10324
10325 Jim_SetHashVal(ht, he, prevCmd);
10326 }
10327 else {
10328 Jim_DeleteHashEntry(ht, fqname);
 
10329 }
10330 Jim_InterpIncrProcEpoch(interp);
10331 }
10332 Jim_DecrRefCount(interp, cmdNameObj);
10333 JimFreeQualifiedName(interp, fqObjName);
10334 }
10335 Jim_FreeStack(localCommands);
@@ -10337,12 +10289,12 @@
10337 }
10338 return JIM_OK;
10339 }
10340
10341
10342 #define JIM_FCF_FULL 0
10343 #define JIM_FCF_REUSE 1
10344 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
10345 {
10346 JimDeleteLocalProcs(interp, cf->localCommands);
10347
10348 if (cf->procArgsObjPtr)
@@ -10375,10 +10327,263 @@
10375 cf->next = interp->freeFramesList;
10376 interp->freeFramesList = cf;
10377 }
10378
10379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10380
10381 int Jim_IsBigEndian(void)
10382 {
10383 union {
10384 unsigned short s;
@@ -10425,11 +10630,11 @@
10425 Jim_IncrRefCount(i->nullScriptObj);
10426 Jim_IncrRefCount(i->errorProc);
10427 Jim_IncrRefCount(i->trueObj);
10428 Jim_IncrRefCount(i->falseObj);
10429
10430
10431 Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
10432 Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
10433
10434 Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim");
10435 Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
@@ -10447,11 +10652,11 @@
10447 {
10448 Jim_CallFrame *cf, *cfx;
10449
10450 Jim_Obj *objPtr, *nextObjPtr;
10451
10452
10453 for (cf = i->framePtr; cf; cf = cfx) {
10454 cfx = cf->parent;
10455 JimFreeCallFrame(i, cf, JIM_FCF_FULL);
10456 }
10457
@@ -10500,27 +10705,27 @@
10500 printf("-------------------------------------\n\n");
10501 JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
10502 }
10503 #endif
10504
10505
10506 objPtr = i->freeList;
10507 while (objPtr) {
10508 nextObjPtr = objPtr->nextObjPtr;
10509 Jim_Free(objPtr);
10510 objPtr = nextObjPtr;
10511 }
10512
10513
10514 for (cf = i->freeFramesList; cf; cf = cfx) {
10515 cfx = cf->next;
10516 if (cf->vars.table)
10517 Jim_FreeHashTable(&cf->vars);
10518 Jim_Free(cf);
10519 }
10520
10521
10522 Jim_Free(i);
10523 }
10524
10525 Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
10526 {
@@ -10541,25 +10746,25 @@
10541 else {
10542 if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
10543 level = -1;
10544 }
10545 else {
10546
10547 level = interp->framePtr->level - level;
10548 }
10549 }
10550 }
10551 else {
10552 str = "1";
10553 level = interp->framePtr->level - 1;
10554 }
10555
10556 if (level == 0) {
10557 return interp->topFramePtr;
10558 }
10559 if (level > 0) {
10560
10561 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10562 if (framePtr->level == level) {
10563 return framePtr;
10564 }
10565 }
@@ -10574,19 +10779,19 @@
10574 long level;
10575 Jim_CallFrame *framePtr;
10576
10577 if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
10578 if (level <= 0) {
10579
10580 level = interp->framePtr->level + level;
10581 }
10582
10583 if (level == 0) {
10584 return interp->topFramePtr;
10585 }
10586
10587
10588 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10589 if (framePtr->level == level) {
10590 return framePtr;
10591 }
10592 }
@@ -10605,11 +10810,11 @@
10605
10606 static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
10607 {
10608 int len;
10609
10610
10611 Jim_IncrRefCount(stackTraceObj);
10612 Jim_DecrRefCount(interp, interp->stackTrace);
10613 interp->stackTrace = stackTraceObj;
10614 interp->errorFlag = 1;
10615
@@ -10626,32 +10831,32 @@
10626 {
10627 if (strcmp(procname, "unknown") == 0) {
10628 procname = "";
10629 }
10630 if (!*procname && !Jim_Length(fileNameObj)) {
10631
10632 return;
10633 }
10634
10635 if (Jim_IsShared(interp->stackTrace)) {
10636 Jim_DecrRefCount(interp, interp->stackTrace);
10637 interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
10638 Jim_IncrRefCount(interp->stackTrace);
10639 }
10640
10641
10642 if (!*procname && Jim_Length(fileNameObj)) {
10643
10644 int len = Jim_ListLength(interp, interp->stackTrace);
10645
10646 if (len >= 3) {
10647 Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
10648 if (Jim_Length(objPtr)) {
10649
10650 objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
10651 if (Jim_Length(objPtr) == 0) {
10652
10653 ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
10654 ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
10655 return;
10656 }
10657 }
@@ -10753,18 +10958,18 @@
10753 {
10754 jim_wide wideValue;
10755 const char *str;
10756
10757 if (objPtr->typePtr == &coercedDoubleObjType) {
10758
10759 objPtr->typePtr = &intObjType;
10760 return JIM_OK;
10761 }
10762
10763
10764 str = Jim_String(objPtr);
10765
10766 if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
10767 if (flags & JIM_ERRMSG) {
10768 Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
10769 }
10770 return JIM_ERR;
@@ -10771,11 +10976,11 @@
10771 }
10772 if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
10773 Jim_SetResultString(interp, "Integer value too big to be represented", -1);
10774 return JIM_ERR;
10775 }
10776
10777 Jim_FreeIntRep(interp, objPtr);
10778 objPtr->typePtr = &intObjType;
10779 objPtr->internalRep.wideValue = wideValue;
10780 return JIM_OK;
10781 }
@@ -10870,17 +11075,17 @@
10870 {
10871 char buf[JIM_DOUBLE_SPACE + 1];
10872 int i;
10873 int len = sprintf(buf, "%.12g", value);
10874
10875
10876 for (i = 0; i < len; i++) {
10877 if (buf[i] == '.' || buf[i] == 'e') {
10878 #if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
10879 char *e = strchr(buf, 'e');
10880 if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
10881
10882 e += 2;
10883 memmove(e, e + 1, len - (e - buf));
10884 }
10885 #endif
10886 break;
@@ -10902,38 +11107,38 @@
10902 const char *str;
10903
10904 str = Jim_String(objPtr);
10905
10906 #ifdef HAVE_LONG_LONG
10907
10908 #define MIN_INT_IN_DOUBLE -(1LL << 53)
10909 #define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
10910
10911 if (objPtr->typePtr == &intObjType
10912 && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
10913 && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
10914
10915
10916 objPtr->typePtr = &coercedDoubleObjType;
10917 return JIM_OK;
10918 }
10919 else
10920 #endif
10921 if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
10922
10923 Jim_FreeIntRep(interp, objPtr);
10924 objPtr->typePtr = &coercedDoubleObjType;
10925 objPtr->internalRep.wideValue = wideValue;
10926 return JIM_OK;
10927 }
10928 else {
10929
10930 if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
10931 Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
10932 return JIM_ERR;
10933 }
10934
10935 Jim_FreeIntRep(interp, objPtr);
10936 }
10937 objPtr->typePtr = &doubleObjType;
10938 objPtr->internalRep.doubleValue = doubleValue;
10939 return JIM_OK;
@@ -10966,50 +11171,10 @@
10966 objPtr->bytes = NULL;
10967 objPtr->internalRep.doubleValue = doubleValue;
10968 return objPtr;
10969 }
10970
10971 static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags);
10972
10973 int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr)
10974 {
10975 if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR)
10976 return JIM_ERR;
10977 *booleanPtr = (int) JimWideValue(objPtr);
10978 return JIM_OK;
10979 }
10980
10981 static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
10982 {
10983 static const char * const falses[] = {
10984 "0", "false", "no", "off", NULL
10985 };
10986 static const char * const trues[] = {
10987 "1", "true", "yes", "on", NULL
10988 };
10989
10990 int boolean;
10991
10992 int index;
10993 if (Jim_GetEnum(interp, objPtr, falses, &index, NULL, 0) == JIM_OK) {
10994 boolean = 0;
10995 } else if (Jim_GetEnum(interp, objPtr, trues, &index, NULL, 0) == JIM_OK) {
10996 boolean = 1;
10997 } else {
10998 if (flags & JIM_ERRMSG) {
10999 Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr);
11000 }
11001 return JIM_ERR;
11002 }
11003
11004
11005 Jim_FreeIntRep(interp, objPtr);
11006 objPtr->typePtr = &intObjType;
11007 objPtr->internalRep.wideValue = boolean;
11008 return JIM_OK;
11009 }
11010
11011 static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
11012 static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
11013 static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
11014 static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
11015 static void UpdateStringOfList(struct Jim_Obj *objPtr);
@@ -11056,11 +11221,11 @@
11056 #define JIM_ELESTR_QUOTE 2
11057 static unsigned char ListElementQuotingType(const char *s, int len)
11058 {
11059 int i, level, blevel, trySimple = 1;
11060
11061
11062 if (len == 0)
11063 return JIM_ELESTR_BRACE;
11064 if (s[0] == '"' || s[0] == '{') {
11065 trySimple = 0;
11066 goto testbrace;
@@ -11078,20 +11243,20 @@
11078 case '\n':
11079 case '\t':
11080 case '\f':
11081 case '\v':
11082 trySimple = 0;
11083
11084 case '{':
11085 case '}':
11086 goto testbrace;
11087 }
11088 }
11089 return JIM_ELESTR_SIMPLE;
11090
11091 testbrace:
11092
11093 if (s[len - 1] == '\\')
11094 return JIM_ELESTR_QUOTE;
11095 level = 0;
11096 blevel = 0;
11097 for (i = 0; i < len; i++) {
@@ -11207,11 +11372,11 @@
11207 int i, bufLen, realLength;
11208 const char *strRep;
11209 char *p;
11210 unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
11211
11212
11213 if (objc > STATIC_QUOTING_LEN) {
11214 quotingType = Jim_Alloc(objc);
11215 }
11216 else {
11217 quotingType = staticQuoting;
@@ -11226,25 +11391,25 @@
11226 case JIM_ELESTR_SIMPLE:
11227 if (i != 0 || strRep[0] != '#') {
11228 bufLen += len;
11229 break;
11230 }
11231
11232 quotingType[i] = JIM_ELESTR_BRACE;
11233
11234 case JIM_ELESTR_BRACE:
11235 bufLen += len + 2;
11236 break;
11237 case JIM_ELESTR_QUOTE:
11238 bufLen += len * 2;
11239 break;
11240 }
11241 bufLen++;
11242 }
11243 bufLen++;
11244
11245
11246 p = objPtr->bytes = Jim_Alloc(bufLen + 1);
11247 realLength = 0;
11248 for (i = 0; i < objc; i++) {
11249 int len, qlen;
11250
@@ -11271,17 +11436,17 @@
11271 qlen = BackslashQuoteString(strRep, len, p);
11272 p += qlen;
11273 realLength += qlen;
11274 break;
11275 }
11276
11277 if (i + 1 != objc) {
11278 *p++ = ' ';
11279 realLength++;
11280 }
11281 }
11282 *p = '\0';
11283 objPtr->length = realLength;
11284
11285 if (quotingType != staticQuoting) {
11286 Jim_Free(quotingType);
11287 }
@@ -11312,21 +11477,21 @@
11312 listObjPtrPtr = JimDictPairs(objPtr, &len);
11313 for (i = 0; i < len; i++) {
11314 Jim_IncrRefCount(listObjPtrPtr[i]);
11315 }
11316
11317
11318 Jim_FreeIntRep(interp, objPtr);
11319 objPtr->typePtr = &listObjType;
11320 objPtr->internalRep.listValue.len = len;
11321 objPtr->internalRep.listValue.maxLen = len;
11322 objPtr->internalRep.listValue.ele = listObjPtrPtr;
11323
11324 return JIM_OK;
11325 }
11326
11327
11328 if (objPtr->typePtr == &sourceObjType) {
11329 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
11330 linenr = objPtr->internalRep.sourceValue.lineNumber;
11331 }
11332 else {
@@ -11333,20 +11498,20 @@
11333 fileNameObj = interp->emptyObj;
11334 linenr = 1;
11335 }
11336 Jim_IncrRefCount(fileNameObj);
11337
11338
11339 str = Jim_GetString(objPtr, &strLen);
11340
11341 Jim_FreeIntRep(interp, objPtr);
11342 objPtr->typePtr = &listObjType;
11343 objPtr->internalRep.listValue.len = 0;
11344 objPtr->internalRep.listValue.maxLen = 0;
11345 objPtr->internalRep.listValue.ele = NULL;
11346
11347
11348 if (strLen) {
11349 JimParserInit(&parser, str, strLen, linenr);
11350 while (!parser.eof) {
11351 Jim_Obj *elementPtr;
11352
@@ -11476,11 +11641,11 @@
11476 Jim_Obj *compare_script;
11477 int rc;
11478
11479 jim_wide ret = 0;
11480
11481
11482 compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
11483 Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
11484 Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
11485
11486 rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11498,23 +11663,23 @@
11498 int dst = 0;
11499 Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
11500
11501 for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
11502 if (comp(&ele[dst], &ele[src]) == 0) {
11503
11504 Jim_DecrRefCount(sort_info->interp, ele[dst]);
11505 }
11506 else {
11507
11508 dst++;
11509 }
11510 ele[dst] = ele[src];
11511 }
11512
11513 ele[++dst] = ele[src];
11514
11515
11516 listObjPtr->internalRep.listValue.len = dst;
11517 }
11518
11519
11520 static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11528,11 +11693,11 @@
11528 int rc;
11529
11530 JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
11531 SetListFromAny(interp, listObjPtr);
11532
11533
11534 prev_info = sort_info;
11535 sort_info = info;
11536
11537 vector = listObjPtr->internalRep.listValue.ele;
11538 len = listObjPtr->internalRep.listValue.len;
@@ -11551,17 +11716,17 @@
11551 break;
11552 case JIM_LSORT_COMMAND:
11553 fn = ListSortCommand;
11554 break;
11555 default:
11556 fn = NULL;
11557 JimPanic((1, "ListSort called with invalid sort type"));
11558 return -1;
11559 }
11560
11561 if (info->indexed) {
11562
11563 info->subfn = fn;
11564 fn = ListSortIndexHelper;
11565 }
11566
11567 if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11585,11 +11750,11 @@
11585 int i;
11586 Jim_Obj **point;
11587
11588 if (requiredLen > listPtr->internalRep.listValue.maxLen) {
11589 if (requiredLen < 2) {
11590
11591 requiredLen = 4;
11592 }
11593 else {
11594 requiredLen *= 2;
11595 }
@@ -11771,34 +11936,34 @@
11771 for (i = 0; i < objc; i++)
11772 ListAppendList(objPtr, objv[i]);
11773 return objPtr;
11774 }
11775 else {
11776
11777 int len = 0, objLen;
11778 char *bytes, *p;
11779
11780
11781 for (i = 0; i < objc; i++) {
11782 len += Jim_Length(objv[i]);
11783 }
11784 if (objc)
11785 len += objc - 1;
11786
11787 p = bytes = Jim_Alloc(len + 1);
11788 for (i = 0; i < objc; i++) {
11789 const char *s = Jim_GetString(objv[i], &objLen);
11790
11791
11792 while (objLen && isspace(UCHAR(*s))) {
11793 s++;
11794 objLen--;
11795 len--;
11796 }
11797
11798 while (objLen && isspace(UCHAR(s[objLen - 1]))) {
11799
11800 if (objLen > 1 && s[objLen - 2] == '\\') {
11801 break;
11802 }
11803 objLen--;
11804 len--;
@@ -11825,11 +11990,11 @@
11825 int len, rangeLen;
11826
11827 if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
11828 Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
11829 return NULL;
11830 len = Jim_ListLength(interp, listObjPtr);
11831 first = JimRelToAbsIndex(len, first);
11832 last = JimRelToAbsIndex(len, last);
11833 JimRelToAbsRange(len, &first, &last, &rangeLen);
11834 if (first == 0 && last == len) {
11835 return listObjPtr;
@@ -11865,16 +12030,16 @@
11865 {
11866 Jim_DecrRefCount(interp, (Jim_Obj *)val);
11867 }
11868
11869 static const Jim_HashTableType JimDictHashTableType = {
11870 JimObjectHTHashFunction,
11871 JimObjectHTKeyValDup,
11872 JimObjectHTKeyValDup,
11873 JimObjectHTKeyCompare,
11874 JimObjectHTKeyValDestructor,
11875 JimObjectHTKeyValDestructor
11876 };
11877
11878 static const Jim_ObjType dictObjType = {
11879 "dict",
11880 FreeDictInternalRep,
@@ -11895,17 +12060,17 @@
11895 {
11896 Jim_HashTable *ht, *dupHt;
11897 Jim_HashTableIterator htiter;
11898 Jim_HashEntry *he;
11899
11900
11901 ht = srcPtr->internalRep.ptr;
11902 dupHt = Jim_Alloc(sizeof(*dupHt));
11903 Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
11904 if (ht->size != 0)
11905 Jim_ExpandHashTable(dupHt, ht->size);
11906
11907 JimInitHashTableIterator(ht, &htiter);
11908 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
11909 Jim_AddHashEntry(dupHt, he->key, he->u.val);
11910 }
11911
@@ -11921,11 +12086,11 @@
11921 Jim_Obj **objv;
11922 int i;
11923
11924 ht = dictPtr->internalRep.ptr;
11925
11926
11927 objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
11928 JimInitHashTableIterator(ht, &htiter);
11929 i = 0;
11930 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
11931 objv[i++] = Jim_GetHashEntryKey(he);
@@ -11935,15 +12100,15 @@
11935 return objv;
11936 }
11937
11938 static void UpdateStringOfDict(struct Jim_Obj *objPtr)
11939 {
11940
11941 int len;
11942 Jim_Obj **objv = JimDictPairs(objPtr, &len);
11943
11944
11945 JimMakeListStringRep(objPtr, objv, len);
11946
11947 Jim_Free(objv);
11948 }
11949
@@ -11957,18 +12122,18 @@
11957
11958 if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
11959 Jim_String(objPtr);
11960 }
11961
11962
11963 listlen = Jim_ListLength(interp, objPtr);
11964 if (listlen % 2) {
11965 Jim_SetResultString(interp, "missing value to go with key", -1);
11966 return JIM_ERR;
11967 }
11968 else {
11969
11970 Jim_HashTable *ht;
11971 int i;
11972
11973 ht = Jim_Alloc(sizeof(*ht));
11974 Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -11993,11 +12158,11 @@
11993 static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
11994 Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
11995 {
11996 Jim_HashTable *ht = objPtr->internalRep.ptr;
11997
11998 if (valueObjPtr == NULL) {
11999 return Jim_DeleteHashEntry(ht, keyObjPtr);
12000 }
12001 Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
12002 return JIM_OK;
12003 }
@@ -12093,11 +12258,11 @@
12093 int shared, i;
12094
12095 varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
12096 if (objPtr == NULL) {
12097 if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
12098
12099 return JIM_ERR;
12100 }
12101 varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
12102 if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
12103 Jim_FreeNewObj(interp, varObjPtr);
@@ -12107,26 +12272,26 @@
12107 if ((shared = Jim_IsShared(objPtr)))
12108 varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
12109 for (i = 0; i < keyc; i++) {
12110 dictObjPtr = objPtr;
12111
12112
12113 if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
12114 goto err;
12115 }
12116
12117 if (i == keyc - 1) {
12118
12119 if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
12120 if (newObjPtr || (flags & JIM_MUSTEXIST)) {
12121 goto err;
12122 }
12123 }
12124 break;
12125 }
12126
12127
12128 Jim_InvalidateStringRep(dictObjPtr);
12129 if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
12130 newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
12131 if (Jim_IsShared(objPtr)) {
12132 objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12139,11 +12304,11 @@
12139 }
12140 objPtr = Jim_NewDictObj(interp, NULL, 0);
12141 DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
12142 }
12143 }
12144
12145 Jim_InvalidateStringRep(objPtr);
12146 Jim_InvalidateStringRep(varObjPtr);
12147 if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
12148 goto err;
12149 }
@@ -12176,11 +12341,11 @@
12176 char buf[JIM_INTEGER_SPACE + 1];
12177 if (objPtr->internalRep.intValue >= 0) {
12178 sprintf(buf, "%d", objPtr->internalRep.intValue);
12179 }
12180 else {
12181
12182 sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
12183 }
12184 JimSetStringBytes(objPtr, buf);
12185 }
12186 }
@@ -12189,14 +12354,14 @@
12189 {
12190 int idx, end = 0;
12191 const char *str;
12192 char *endptr;
12193
12194
12195 str = Jim_String(objPtr);
12196
12197
12198 if (strncmp(str, "end", 3) == 0) {
12199 end = 1;
12200 str += 3;
12201 idx = 0;
12202 }
@@ -12207,21 +12372,21 @@
12207 goto badindex;
12208 }
12209 str = endptr;
12210 }
12211
12212
12213 if (*str == '+' || *str == '-') {
12214 int sign = (*str == '+' ? 1 : -1);
12215
12216 idx += sign * jim_strtol(++str, &endptr);
12217 if (str == endptr || *endptr) {
12218 goto badindex;
12219 }
12220 str = endptr;
12221 }
12222
12223 while (isspace(UCHAR(*str))) {
12224 str++;
12225 }
12226 if (*str) {
12227 goto badindex;
@@ -12229,19 +12394,19 @@
12229 if (end) {
12230 if (idx > 0) {
12231 idx = INT_MAX;
12232 }
12233 else {
12234
12235 idx--;
12236 }
12237 }
12238 else if (idx < 0) {
12239 idx = -INT_MAX;
12240 }
12241
12242
12243 Jim_FreeIntRep(interp, objPtr);
12244 objPtr->typePtr = &indexObjType;
12245 objPtr->internalRep.intValue = idx;
12246 return JIM_OK;
12247
@@ -12251,11 +12416,11 @@
12251 return JIM_ERR;
12252 }
12253
12254 int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
12255 {
12256
12257 if (objPtr->typePtr == &intObjType) {
12258 jim_wide val = JimWideValue(objPtr);
12259
12260 if (val < 0)
12261 *indexPtr = -INT_MAX;
@@ -12308,18 +12473,18 @@
12308 static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
12309 {
12310 int returnCode;
12311 jim_wide wideValue;
12312
12313
12314 if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
12315 returnCode = (int)wideValue;
12316 else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
12317 Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
12318 return JIM_ERR;
12319 }
12320
12321 Jim_FreeIntRep(interp, objPtr);
12322 objPtr->typePtr = &returnCodeObjType;
12323 objPtr->internalRep.intValue = returnCode;
12324 return JIM_OK;
12325 }
@@ -12333,20 +12498,19 @@
12333 }
12334
12335 static int JimParseExprOperator(struct JimParserCtx *pc);
12336 static int JimParseExprNumber(struct JimParserCtx *pc);
12337 static int JimParseExprIrrational(struct JimParserCtx *pc);
12338 static int JimParseExprBoolean(struct JimParserCtx *pc);
12339
12340
12341
12342
12343 enum
12344 {
12345
12346
12347 JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
12348 JIM_EXPROP_DIV,
12349 JIM_EXPROP_MOD,
12350 JIM_EXPROP_SUB,
12351 JIM_EXPROP_ADD,
12352 JIM_EXPROP_LSHIFT,
@@ -12357,67 +12521,66 @@
12357 JIM_EXPROP_GT,
12358 JIM_EXPROP_LTE,
12359 JIM_EXPROP_GTE,
12360 JIM_EXPROP_NUMEQ,
12361 JIM_EXPROP_NUMNE,
12362 JIM_EXPROP_BITAND,
12363 JIM_EXPROP_BITXOR,
12364 JIM_EXPROP_BITOR,
12365
12366
12367 JIM_EXPROP_LOGICAND,
12368 JIM_EXPROP_LOGICAND_LEFT,
12369 JIM_EXPROP_LOGICAND_RIGHT,
12370
12371
12372 JIM_EXPROP_LOGICOR,
12373 JIM_EXPROP_LOGICOR_LEFT,
12374 JIM_EXPROP_LOGICOR_RIGHT,
12375
12376
12377
12378 JIM_EXPROP_TERNARY,
12379 JIM_EXPROP_TERNARY_LEFT,
12380 JIM_EXPROP_TERNARY_RIGHT,
12381
12382
12383 JIM_EXPROP_COLON,
12384 JIM_EXPROP_COLON_LEFT,
12385 JIM_EXPROP_COLON_RIGHT,
12386
12387 JIM_EXPROP_POW,
12388
12389
12390 JIM_EXPROP_STREQ,
12391 JIM_EXPROP_STRNE,
12392 JIM_EXPROP_STRIN,
12393 JIM_EXPROP_STRNI,
12394
12395
12396 JIM_EXPROP_NOT,
12397 JIM_EXPROP_BITNOT,
12398 JIM_EXPROP_UNARYMINUS,
12399 JIM_EXPROP_UNARYPLUS,
12400
12401
12402 JIM_EXPROP_FUNC_FIRST,
12403 JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
12404 JIM_EXPROP_FUNC_WIDE,
12405 JIM_EXPROP_FUNC_ABS,
12406 JIM_EXPROP_FUNC_DOUBLE,
12407 JIM_EXPROP_FUNC_ROUND,
12408 JIM_EXPROP_FUNC_RAND,
12409 JIM_EXPROP_FUNC_SRAND,
12410
12411
12412 JIM_EXPROP_FUNC_SIN,
12413 JIM_EXPROP_FUNC_COS,
12414 JIM_EXPROP_FUNC_TAN,
12415 JIM_EXPROP_FUNC_ASIN,
12416 JIM_EXPROP_FUNC_ACOS,
12417 JIM_EXPROP_FUNC_ATAN,
12418 JIM_EXPROP_FUNC_ATAN2,
12419 JIM_EXPROP_FUNC_SINH,
12420 JIM_EXPROP_FUNC_COSH,
12421 JIM_EXPROP_FUNC_TANH,
12422 JIM_EXPROP_FUNC_CEIL,
12423 JIM_EXPROP_FUNC_FLOOR,
@@ -12424,12 +12587,10 @@
12424 JIM_EXPROP_FUNC_EXP,
12425 JIM_EXPROP_FUNC_LOG,
12426 JIM_EXPROP_FUNC_LOG10,
12427 JIM_EXPROP_FUNC_SQRT,
12428 JIM_EXPROP_FUNC_POW,
12429 JIM_EXPROP_FUNC_HYPOT,
12430 JIM_EXPROP_FUNC_FMOD,
12431 };
12432
12433 struct JimExprState
12434 {
12435 Jim_Obj **stack;
@@ -12506,15 +12667,11 @@
12506 case JIM_EXPROP_UNARYPLUS:
12507 dC = dA;
12508 intresult = 0;
12509 break;
12510 case JIM_EXPROP_FUNC_ABS:
12511 #ifdef JIM_MATH_FUNCTIONS
12512 dC = fabs(dA);
12513 #else
12514 dC = dA >= 0 ? dA : -dA;
12515 #endif
12516 intresult = 0;
12517 break;
12518 case JIM_EXPROP_UNARYMINUS:
12519 dC = -dA;
12520 intresult = 0;
@@ -12702,16 +12859,16 @@
12702 }
12703 }
12704 break;
12705 case JIM_EXPROP_ROTL:
12706 case JIM_EXPROP_ROTR:{
12707
12708 unsigned long uA = (unsigned long)wA;
12709 unsigned long uB = (unsigned long)wB;
12710 const unsigned int S = sizeof(unsigned long) * 8;
12711
12712
12713 uB %= S;
12714
12715 if (e->opcode == JIM_EXPROP_ROTR) {
12716 uB = S - uB;
12717 }
@@ -12733,10 +12890,11 @@
12733
12734
12735
12736 static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
12737 {
 
12738 int rc = JIM_OK;
12739 double dA, dB, dC = 0;
12740 jim_wide wA, wB, wC = 0;
12741
12742 Jim_Obj *B = ExprPop(e);
@@ -12744,36 +12902,30 @@
12744
12745 if ((A->typePtr != &doubleObjType || A->bytes) &&
12746 (B->typePtr != &doubleObjType || B->bytes) &&
12747 JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
12748
12749
12750
12751 switch (e->opcode) {
12752 case JIM_EXPROP_POW:
12753 case JIM_EXPROP_FUNC_POW:
12754 if (wA == 0 && wB < 0) {
12755 Jim_SetResultString(interp, "exponentiation of zero by negative power", -1);
12756 rc = JIM_ERR;
12757 goto done;
12758 }
12759 wC = JimPowWide(wA, wB);
12760 goto intresult;
12761 case JIM_EXPROP_ADD:
12762 wC = wA + wB;
12763 goto intresult;
12764 case JIM_EXPROP_SUB:
12765 wC = wA - wB;
12766 goto intresult;
12767 case JIM_EXPROP_MUL:
12768 wC = wA * wB;
12769 goto intresult;
12770 case JIM_EXPROP_DIV:
12771 if (wB == 0) {
12772 Jim_SetResultString(interp, "Division by zero", -1);
12773 rc = JIM_ERR;
12774 goto done;
12775 }
12776 else {
12777 if (wB < 0) {
12778 wB = -wB;
12779 wA = -wA;
@@ -12780,67 +12932,55 @@
12780 }
12781 wC = wA / wB;
12782 if (wA % wB < 0) {
12783 wC--;
12784 }
12785 goto intresult;
12786 }
12787 case JIM_EXPROP_LT:
12788 wC = wA < wB;
12789 goto intresult;
12790 case JIM_EXPROP_GT:
12791 wC = wA > wB;
12792 goto intresult;
12793 case JIM_EXPROP_LTE:
12794 wC = wA <= wB;
12795 goto intresult;
12796 case JIM_EXPROP_GTE:
12797 wC = wA >= wB;
12798 goto intresult;
12799 case JIM_EXPROP_NUMEQ:
12800 wC = wA == wB;
12801 goto intresult;
12802 case JIM_EXPROP_NUMNE:
12803 wC = wA != wB;
12804 goto intresult;
12805 }
12806 }
12807 if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12808 switch (e->opcode) {
12809 #ifndef JIM_MATH_FUNCTIONS
12810 case JIM_EXPROP_POW:
12811 case JIM_EXPROP_FUNC_POW:
12812 case JIM_EXPROP_FUNC_ATAN2:
12813 case JIM_EXPROP_FUNC_HYPOT:
12814 case JIM_EXPROP_FUNC_FMOD:
12815 Jim_SetResultString(interp, "unsupported", -1);
12816 rc = JIM_ERR;
12817 goto done;
12818 #else
12819 case JIM_EXPROP_POW:
12820 case JIM_EXPROP_FUNC_POW:
12821 dC = pow(dA, dB);
12822 goto doubleresult;
12823 case JIM_EXPROP_FUNC_ATAN2:
12824 dC = atan2(dA, dB);
12825 goto doubleresult;
12826 case JIM_EXPROP_FUNC_HYPOT:
12827 dC = hypot(dA, dB);
12828 goto doubleresult;
12829 case JIM_EXPROP_FUNC_FMOD:
12830 dC = fmod(dA, dB);
12831 goto doubleresult;
12832 #endif
12833 case JIM_EXPROP_ADD:
12834 dC = dA + dB;
12835 goto doubleresult;
12836 case JIM_EXPROP_SUB:
12837 dC = dA - dB;
12838 goto doubleresult;
12839 case JIM_EXPROP_MUL:
12840 dC = dA * dB;
12841 goto doubleresult;
12842 case JIM_EXPROP_DIV:
12843 if (dB == 0) {
12844 #ifdef INFINITY
12845 dC = dA < 0 ? -INFINITY : INFINITY;
12846 #else
@@ -12848,70 +12988,83 @@
12848 #endif
12849 }
12850 else {
12851 dC = dA / dB;
12852 }
12853 goto doubleresult;
12854 case JIM_EXPROP_LT:
12855 wC = dA < dB;
12856 goto intresult;
 
12857 case JIM_EXPROP_GT:
12858 wC = dA > dB;
12859 goto intresult;
 
12860 case JIM_EXPROP_LTE:
12861 wC = dA <= dB;
12862 goto intresult;
 
12863 case JIM_EXPROP_GTE:
12864 wC = dA >= dB;
12865 goto intresult;
 
12866 case JIM_EXPROP_NUMEQ:
12867 wC = dA == dB;
12868 goto intresult;
 
12869 case JIM_EXPROP_NUMNE:
12870 wC = dA != dB;
12871 goto intresult;
 
 
 
12872 }
12873 }
12874 else {
 
12875
12876
12877
12878 int i = Jim_StringCompareObj(interp, A, B, 0);
12879
12880 switch (e->opcode) {
12881 case JIM_EXPROP_LT:
12882 wC = i < 0;
12883 goto intresult;
12884 case JIM_EXPROP_GT:
12885 wC = i > 0;
12886 goto intresult;
12887 case JIM_EXPROP_LTE:
12888 wC = i <= 0;
12889 goto intresult;
12890 case JIM_EXPROP_GTE:
12891 wC = i >= 0;
12892 goto intresult;
12893 case JIM_EXPROP_NUMEQ:
12894 wC = i == 0;
12895 goto intresult;
12896 case JIM_EXPROP_NUMNE:
12897 wC = i != 0;
12898 goto intresult;
 
 
 
12899 }
12900 }
12901
12902 rc = JIM_ERR;
12903 done:
 
 
 
 
 
 
 
12904 Jim_DecrRefCount(interp, A);
12905 Jim_DecrRefCount(interp, B);
 
12906 return rc;
12907 intresult:
12908 ExprPush(e, Jim_NewIntObj(interp, wC));
12909 goto done;
12910 doubleresult:
12911 ExprPush(e, Jim_NewDoubleObj(interp, dC));
12912 goto done;
12913 }
12914
12915 static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
12916 {
12917 int listlen;
@@ -12960,21 +13113,17 @@
12960
12961 static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
12962 {
12963 long l;
12964 double d;
12965 int b;
12966
12967 if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
12968 return l != 0;
12969 }
12970 if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
12971 return d != 0;
12972 }
12973 if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
12974 return b != 0;
12975 }
12976 return -1;
12977 }
12978
12979 static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
12980 {
@@ -12982,21 +13131,21 @@
12982 Jim_Obj *A = ExprPop(e);
12983 int rc = JIM_OK;
12984
12985 switch (ExprBool(interp, A)) {
12986 case 0:
12987
12988 e->skip = JimWideValue(skip);
12989 ExprPush(e, Jim_NewIntObj(interp, 0));
12990 break;
12991
12992 case 1:
12993
12994 break;
12995
12996 case -1:
12997
12998 rc = JIM_ERR;
12999 }
13000 Jim_DecrRefCount(interp, A);
13001 Jim_DecrRefCount(interp, skip);
13002
@@ -13009,21 +13158,21 @@
13009 Jim_Obj *A = ExprPop(e);
13010 int rc = JIM_OK;
13011
13012 switch (ExprBool(interp, A)) {
13013 case 0:
13014
13015 break;
13016
13017 case 1:
13018
13019 e->skip = JimWideValue(skip);
13020 ExprPush(e, Jim_NewIntObj(interp, 1));
13021 break;
13022
13023 case -1:
13024
13025 rc = JIM_ERR;
13026 break;
13027 }
13028 Jim_DecrRefCount(interp, A);
13029 Jim_DecrRefCount(interp, skip);
@@ -13044,11 +13193,11 @@
13044 case 1:
13045 ExprPush(e, Jim_NewIntObj(interp, 1));
13046 break;
13047
13048 case -1:
13049
13050 rc = JIM_ERR;
13051 break;
13052 }
13053 Jim_DecrRefCount(interp, A);
13054
@@ -13059,27 +13208,27 @@
13059 {
13060 Jim_Obj *skip = ExprPop(e);
13061 Jim_Obj *A = ExprPop(e);
13062 int rc = JIM_OK;
13063
13064
13065 ExprPush(e, A);
13066
13067 switch (ExprBool(interp, A)) {
13068 case 0:
13069
13070 e->skip = JimWideValue(skip);
13071
13072 ExprPush(e, Jim_NewIntObj(interp, 0));
13073 break;
13074
13075 case 1:
13076
13077 break;
13078
13079 case -1:
13080
13081 rc = JIM_ERR;
13082 break;
13083 }
13084 Jim_DecrRefCount(interp, A);
13085 Jim_DecrRefCount(interp, skip);
@@ -13091,15 +13240,15 @@
13091 {
13092 Jim_Obj *skip = ExprPop(e);
13093 Jim_Obj *B = ExprPop(e);
13094 Jim_Obj *A = ExprPop(e);
13095
13096
13097 if (ExprBool(interp, A)) {
13098
13099 e->skip = JimWideValue(skip);
13100
13101 ExprPush(e, B);
13102 }
13103
13104 Jim_DecrRefCount(interp, skip);
13105 Jim_DecrRefCount(interp, A);
@@ -13115,16 +13264,15 @@
13115 enum
13116 {
13117 LAZY_NONE,
13118 LAZY_OP,
13119 LAZY_LEFT,
13120 LAZY_RIGHT,
13121 RIGHT_ASSOC,
13122 };
13123
13124 #define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1}
13125 #define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, LAZY_NONE)
13126
13127 static const struct Jim_ExprOperator Jim_ExprOperators[] = {
13128 OPRINIT("*", 110, 2, JimExprOpBin),
13129 OPRINIT("/", 110, 2, JimExprOpBin),
13130 OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13148,28 +13296,27 @@
13148
13149 OPRINIT("&", 50, 2, JimExprOpIntBin),
13150 OPRINIT("^", 49, 2, JimExprOpIntBin),
13151 OPRINIT("|", 48, 2, JimExprOpIntBin),
13152
13153 OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP),
13154 OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13155 OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13156
13157 OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP),
13158 OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13159 OPRINIT_ATTR(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13160
13161 OPRINIT_ATTR("?", 5, 2, JimExprOpNull, LAZY_OP),
13162 OPRINIT_ATTR(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13163 OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13164
13165 OPRINIT_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP),
13166 OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13167 OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13168
13169
13170 OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC),
13171
13172 OPRINIT("eq", 60, 2, JimExprOpStrBin),
13173 OPRINIT("ne", 60, 2, JimExprOpStrBin),
13174
13175 OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13195,11 +13342,10 @@
13195 OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
13196 OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
13197 OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
13198 OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
13199 OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
13200 OPRINIT("atan2", 200, 2, JimExprOpBin),
13201 OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
13202 OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
13203 OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
13204 OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
13205 OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13206,12 +13352,10 @@
13206 OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
13207 OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
13208 OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
13209 OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
13210 OPRINIT("pow", 200, 2, JimExprOpBin),
13211 OPRINIT("hypot", 200, 2, JimExprOpBin),
13212 OPRINIT("fmod", 200, 2, JimExprOpBin),
13213 #endif
13214 };
13215 #undef OPRINIT
13216 #undef OPRINIT_LAZY
13217
@@ -13218,20 +13362,20 @@
13218 #define JIM_EXPR_OPERATORS_NUM \
13219 (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
13220
13221 static int JimParseExpression(struct JimParserCtx *pc)
13222 {
13223
13224 while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
13225 if (*pc->p == '\n') {
13226 pc->linenr++;
13227 }
13228 pc->p++;
13229 pc->len--;
13230 }
13231
13232
13233 pc->tline = pc->linenr;
13234 pc->tstart = pc->p;
13235
13236 if (pc->len == 0) {
13237 pc->tend = pc->p;
@@ -13257,11 +13401,11 @@
13257 return JimParseCmd(pc);
13258 case '$':
13259 if (JimParseVar(pc) == JIM_ERR)
13260 return JimParseExprOperator(pc);
13261 else {
13262
13263 if (pc->tt == JIM_TT_EXPRSUGAR) {
13264 return JIM_ERR;
13265 }
13266 return JIM_OK;
13267 }
@@ -13286,18 +13430,10 @@
13286 case 'N':
13287 case 'I':
13288 case 'n':
13289 case 'i':
13290 if (JimParseExprIrrational(pc) == JIM_ERR)
13291 if (JimParseExprBoolean(pc) == JIM_ERR)
13292 return JimParseExprOperator(pc);
13293 break;
13294 case 't':
13295 case 'f':
13296 case 'o':
13297 case 'y':
13298 if (JimParseExprBoolean(pc) == JIM_ERR)
13299 return JimParseExprOperator(pc);
13300 break;
13301 default:
13302 return JimParseExprOperator(pc);
13303 break;
@@ -13307,21 +13443,21 @@
13307
13308 static int JimParseExprNumber(struct JimParserCtx *pc)
13309 {
13310 char *end;
13311
13312
13313 pc->tt = JIM_TT_EXPR_INT;
13314
13315 jim_strtoull(pc->p, (char **)&pc->p);
13316
13317 if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
13318 if (strtod(pc->tstart, &end)) { }
13319 if (end == pc->tstart)
13320 return JIM_ERR;
13321 if (end > pc->p) {
13322
13323 pc->tt = JIM_TT_EXPR_DOUBLE;
13324 pc->p = end;
13325 }
13326 }
13327 pc->tend = pc->p - 1;
@@ -13346,37 +13482,16 @@
13346 }
13347 }
13348 return JIM_ERR;
13349 }
13350
13351 static int JimParseExprBoolean(struct JimParserCtx *pc)
13352 {
13353 const char *booleans[] = { "false", "no", "off", "true", "yes", "on", NULL };
13354 const int lengths[] = { 5, 2, 3, 4, 3, 2, 0 };
13355 int i;
13356
13357 for (i = 0; booleans[i]; i++) {
13358 const char *boolean = booleans[i];
13359 int length = lengths[i];
13360
13361 if (strncmp(boolean, pc->p, length) == 0) {
13362 pc->p += length;
13363 pc->len -= length;
13364 pc->tend = pc->p - 1;
13365 pc->tt = JIM_TT_EXPR_BOOLEAN;
13366 return JIM_OK;
13367 }
13368 }
13369 return JIM_ERR;
13370 }
13371
13372 static int JimParseExprOperator(struct JimParserCtx *pc)
13373 {
13374 int i;
13375 int bestIdx = -1, bestLen = 0;
13376
13377
13378 for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
13379 const char * const opname = Jim_ExprOperators[i].name;
13380 const int oplen = Jim_ExprOperators[i].namelen;
13381
13382 if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13390,11 +13505,11 @@
13390 }
13391 if (bestIdx == -1) {
13392 return JIM_ERR;
13393 }
13394
13395
13396 if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
13397 const char *p = pc->p + bestLen;
13398 int len = pc->len - bestLen;
13399
13400 while (len && isspace(UCHAR(*p))) {
@@ -13424,20 +13539,14 @@
13424
13425 const char *jim_tt_name(int type)
13426 {
13427 static const char * const tt_names[JIM_TT_EXPR_OP] =
13428 { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
13429 "DBL", "BOO", "$()" };
13430 if (type < JIM_TT_EXPR_OP) {
13431 return tt_names[type];
13432 }
13433 else if (type == JIM_EXPROP_UNARYMINUS) {
13434 return "-VE";
13435 }
13436 else if (type == JIM_EXPROP_UNARYPLUS) {
13437 return "+VE";
13438 }
13439 else {
13440 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
13441 static char buf[20];
13442
13443 if (op->name) {
@@ -13461,13 +13570,13 @@
13461 };
13462
13463
13464 typedef struct ExprByteCode
13465 {
13466 ScriptToken *token;
13467 int len;
13468 int inUse;
13469 } ExprByteCode;
13470
13471 static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
13472 {
13473 int i;
@@ -13495,29 +13604,26 @@
13495 static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
13496 {
13497 JIM_NOTUSED(interp);
13498 JIM_NOTUSED(srcPtr);
13499
13500
13501 dupPtr->typePtr = NULL;
13502 }
13503
13504 static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr)
 
13505 {
13506 int i;
13507 int stacklen = 0;
13508 int ternary = 0;
13509 int lasttt = JIM_TT_NONE;
13510 const char *errmsg;
13511
13512 for (i = 0; i < expr->len; i++) {
13513 ScriptToken *t = &expr->token[i];
13514 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13515 lasttt = t->type;
13516
13517 stacklen -= op->arity;
13518
13519 if (stacklen < 0) {
13520 break;
13521 }
13522 if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
13523 ternary++;
@@ -13524,47 +13630,26 @@
13524 }
13525 else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
13526 ternary--;
13527 }
13528
13529
13530 stacklen++;
13531 }
13532 if (stacklen == 1 && ternary == 0) {
13533 return JIM_OK;
13534 }
13535
13536 if (stacklen <= 0) {
13537
13538 if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
13539 errmsg = "too few arguments for math function";
13540 Jim_SetResultString(interp, "too few arguments for math function", -1);
13541 } else {
13542 errmsg = "premature end of expression";
13543 }
13544 }
13545 else if (stacklen > 1) {
13546 if (lasttt >= JIM_EXPROP_FUNC_FIRST) {
13547 errmsg = "too many arguments for math function";
13548 } else {
13549 errmsg = "extra tokens at end of expression";
13550 }
13551 }
13552 else {
13553 errmsg = "invalid ternary expression";
13554 }
13555 Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg);
13556 return JIM_ERR;
13557 }
13558
13559 static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
13560 {
13561 int i;
13562
13563 int leftindex, arity, offset;
13564
13565
13566 leftindex = expr->len - 1;
13567
13568 arity = 1;
13569 while (arity) {
13570 ScriptToken *tt = &expr->token[leftindex];
@@ -13577,11 +13662,11 @@
13577 return JIM_ERR;
13578 }
13579 }
13580 leftindex++;
13581
13582
13583 memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
13584 sizeof(*expr->token) * (expr->len - leftindex));
13585 expr->len += 2;
13586 offset = (expr->len - leftindex) - 1;
13587
@@ -13589,16 +13674,16 @@
13589 expr->token[leftindex + 1].objPtr = interp->emptyObj;
13590
13591 expr->token[leftindex].type = JIM_TT_EXPR_INT;
13592 expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
13593
13594
13595 expr->token[expr->len].objPtr = interp->emptyObj;
13596 expr->token[expr->len].type = t->type + 2;
13597 expr->len++;
13598
13599
13600 for (i = leftindex - 1; i > 0; i--) {
13601 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
13602 if (op->lazy == LAZY_LEFT) {
13603 if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
13604 JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13644,11 +13729,11 @@
13644 return right_index;
13645 }
13646 right_index--;
13647 }
13648
13649
13650 return -1;
13651 }
13652
13653 static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
13654 {
@@ -13686,11 +13771,11 @@
13686
13687 if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
13688 continue;
13689 }
13690
13691
13692 if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
13693 continue;
13694 }
13695
13696 tmp = expr->token[prev_right_index];
@@ -13699,25 +13784,25 @@
13699 }
13700 expr->token[i] = tmp;
13701
13702 JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
13703
13704
13705 i++;
13706 }
13707 }
13708
13709 static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
13710 {
13711 Jim_Stack stack;
13712 ExprByteCode *expr;
13713 int ok = 1;
13714 int i;
13715 int prevtt = JIM_TT_NONE;
13716 int have_ternary = 0;
13717
13718
13719 int count = tokenlist->count - 1;
13720
13721 expr = Jim_Alloc(sizeof(*expr));
13722 expr->inUse = 1;
13723 expr->len = 0;
@@ -13728,11 +13813,11 @@
13728 ParseToken *t = &tokenlist->list[i];
13729 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13730
13731 if (op->lazy == LAZY_OP) {
13732 count += 2;
13733
13734 if (t->type == JIM_EXPROP_TERNARY) {
13735 have_ternary = 1;
13736 }
13737 }
13738 }
@@ -13740,128 +13825,128 @@
13740 expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
13741
13742 for (i = 0; i < tokenlist->count && ok; i++) {
13743 ParseToken *t = &tokenlist->list[i];
13744
13745
13746 struct ScriptToken *token = &expr->token[expr->len];
13747
13748 if (t->type == JIM_TT_EOL) {
13749 break;
13750 }
13751
13752 if (TOKEN_IS_EXPR_OP(t->type)) {
13753 const struct Jim_ExprOperator *op;
13754 ParseToken *tt;
13755
13756
13757 if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) {
13758 if (t->type == JIM_EXPROP_SUB) {
13759 t->type = JIM_EXPROP_UNARYMINUS;
13760 }
13761 else if (t->type == JIM_EXPROP_ADD) {
13762 t->type = JIM_EXPROP_UNARYPLUS;
13763 }
13764 }
13765
13766 op = JimExprOperatorInfoByOpcode(t->type);
13767
13768
13769 while ((tt = Jim_StackPeek(&stack)) != NULL) {
13770 const struct Jim_ExprOperator *tt_op =
13771 JimExprOperatorInfoByOpcode(tt->type);
13772
13773
13774 if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13775
13776 if (tt_op->precedence == op->precedence && tt_op->lazy == RIGHT_ASSOC) {
13777 break;
13778 }
13779 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13780 ok = 0;
13781 goto err;
13782 }
13783 Jim_StackPop(&stack);
13784 }
13785 else {
13786 break;
13787 }
13788 }
13789 Jim_StackPush(&stack, t);
13790 }
13791 else if (t->type == JIM_TT_SUBEXPR_START) {
13792 Jim_StackPush(&stack, t);
13793 }
13794 else if (t->type == JIM_TT_SUBEXPR_END || t->type == JIM_TT_SUBEXPR_COMMA) {
13795
13796 ok = 0;
13797 while (Jim_StackLen(&stack)) {
13798 ParseToken *tt = Jim_StackPop(&stack);
13799
13800 if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) {
13801 if (t->type == JIM_TT_SUBEXPR_COMMA) {
13802
13803 Jim_StackPush(&stack, tt);
13804 }
13805 ok = 1;
13806 break;
13807 }
13808 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13809 goto err;
13810 }
13811 }
13812 if (!ok) {
13813 Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr);
13814 goto err;
13815 }
13816 }
13817 else {
13818 Jim_Obj *objPtr = NULL;
13819
13820
13821 token->type = t->type;
13822
13823
13824 if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) {
13825 Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr);
13826 ok = 0;
13827 goto err;
13828 }
13829
13830
13831 if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) {
13832 char *endptr;
13833 if (t->type == JIM_TT_EXPR_INT) {
13834 objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13835 }
13836 else {
13837 objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13838 }
13839 if (endptr != t->token + t->len) {
13840
13841 Jim_FreeNewObj(interp, objPtr);
13842 objPtr = NULL;
13843 }
13844 }
13845
13846 if (objPtr) {
13847 token->objPtr = objPtr;
13848 }
13849 else {
13850
13851 token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13852 if (t->type == JIM_TT_CMD) {
13853
13854 JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13855 }
13856 }
13857 expr->len++;
13858 }
13859 prevtt = t->type;
13860 }
13861
13862
13863 while (Jim_StackLen(&stack)) {
13864 ParseToken *tt = Jim_StackPop(&stack);
13865
13866 if (tt->type == JIM_TT_SUBEXPR_START) {
13867 ok = 0;
@@ -13877,11 +13962,11 @@
13877 if (have_ternary) {
13878 ExprTernaryReorderExpression(interp, expr);
13879 }
13880
13881 err:
13882
13883 Jim_FreeStack(&stack);
13884
13885 for (i = 0; i < expr->len; i++) {
13886 Jim_IncrRefCount(expr->token[i].objPtr);
13887 }
@@ -13904,11 +13989,11 @@
13904 ParseTokenList tokenlist;
13905 int line;
13906 Jim_Obj *fileNameObj;
13907 int rc = JIM_ERR;
13908
13909
13910 if (objPtr->typePtr == &sourceObjType) {
13911 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
13912 line = objPtr->internalRep.sourceValue.lineNumber;
13913 }
13914 else {
@@ -13917,17 +14002,18 @@
13917 }
13918 Jim_IncrRefCount(fileNameObj);
13919
13920 exprText = Jim_GetString(objPtr, &exprTextLen);
13921
13922
13923 ScriptTokenListInit(&tokenlist);
13924
13925 JimParserInit(&parser, exprText, exprTextLen, line);
13926 while (!parser.eof) {
13927 if (JimParseExpression(&parser) != JIM_OK) {
13928 ScriptTokenListFree(&tokenlist);
 
13929 Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
13930 expr = NULL;
13931 goto err;
13932 }
13933
@@ -13950,14 +14036,14 @@
13950 ScriptTokenListFree(&tokenlist);
13951 Jim_DecrRefCount(interp, fileNameObj);
13952 return JIM_ERR;
13953 }
13954
 
 
13955
13956 expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj);
13957
13958
13959 ScriptTokenListFree(&tokenlist);
13960
13961 if (!expr) {
13962 goto err;
13963 }
@@ -13973,22 +14059,20 @@
13973 printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
13974 }
13975 }
13976 #endif
13977
13978
13979 if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) {
13980
13981 ExprFreeByteCode(interp, expr);
13982 expr = NULL;
13983 goto err;
13984 }
13985
13986 rc = JIM_OK;
13987
13988 err:
13989
13990 Jim_DecrRefCount(interp, fileNameObj);
13991 Jim_FreeIntRep(interp, objPtr);
13992 Jim_SetIntRepPtr(objPtr, expr);
13993 objPtr->typePtr = &exprObjType;
13994 return rc;
@@ -14028,11 +14112,11 @@
14028 int retcode = JIM_OK;
14029 struct JimExprState e;
14030
14031 expr = JimGetExpression(interp, exprObjPtr);
14032 if (!expr) {
14033 return JIM_ERR;
14034 }
14035
14036 #ifdef JIM_OPTIMIZATION
14037 {
14038 Jim_Obj *objPtr;
@@ -14101,27 +14185,26 @@
14101 noopt:
14102 #endif
14103
14104 expr->inUse++;
14105
14106
14107
14108 if (expr->len > JIM_EE_STATICSTACK_LEN)
14109 e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
14110 else
14111 e.stack = staticStack;
14112
14113 e.stacklen = 0;
14114
14115
14116 for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
14117 Jim_Obj *objPtr;
14118
14119 switch (expr->token[i].type) {
14120 case JIM_TT_EXPR_INT:
14121 case JIM_TT_EXPR_DOUBLE:
14122 case JIM_TT_EXPR_BOOLEAN:
14123 case JIM_TT_STR:
14124 ExprPush(&e, expr->token[i].objPtr);
14125 break;
14126
14127 case JIM_TT_VAR:
@@ -14157,16 +14240,16 @@
14157 ExprPush(&e, Jim_GetResult(interp));
14158 }
14159 break;
14160
14161 default:{
14162
14163 e.skip = 0;
14164 e.opcode = expr->token[i].type;
14165
14166 retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
14167
14168 i += e.skip;
14169 continue;
14170 }
14171 }
14172 }
@@ -14190,27 +14273,20 @@
14190 int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
14191 {
14192 int retcode;
14193 jim_wide wideValue;
14194 double doubleValue;
14195 int booleanValue;
14196 Jim_Obj *exprResultPtr;
14197
14198 retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
14199 if (retcode != JIM_OK)
14200 return retcode;
14201
14202 if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
14203 if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
14204 if (Jim_GetBoolean(interp, exprResultPtr, &booleanValue) != JIM_OK) {
14205 Jim_DecrRefCount(interp, exprResultPtr);
14206 return JIM_ERR;
14207 } else {
14208 Jim_DecrRefCount(interp, exprResultPtr);
14209 *boolPtr = booleanValue;
14210 return JIM_OK;
14211 }
14212 }
14213 else {
14214 Jim_DecrRefCount(interp, exprResultPtr);
14215 *boolPtr = doubleValue != 0;
14216 return JIM_OK;
@@ -14225,29 +14301,29 @@
14225
14226
14227
14228 typedef struct ScanFmtPartDescr
14229 {
14230 char *arg;
14231 char *prefix;
14232 size_t width;
14233 int pos;
14234 char type;
14235 char modifier;
14236 } ScanFmtPartDescr;
14237
14238
14239 typedef struct ScanFmtStringObj
14240 {
14241 jim_wide size;
14242 char *stringRep;
14243 size_t count;
14244 size_t convCount;
14245 size_t maxPos;
14246 const char *error;
14247 char *scratch;
14248 ScanFmtPartDescr descr[1];
14249 } ScanFmtStringObj;
14250
14251
14252 static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
14253 static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14294,22 +14370,22 @@
14294 int maxFmtLen = objPtr->length;
14295 const char *fmtEnd = fmt + maxFmtLen;
14296 int curr;
14297
14298 Jim_FreeIntRep(interp, objPtr);
14299
14300 for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
14301 if (fmt[i] == '%')
14302 ++maxCount;
14303
14304 approxSize = sizeof(ScanFmtStringObj)
14305 +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14306 +maxFmtLen * sizeof(char) + 3 + 1
14307 + maxFmtLen * sizeof(char) + 1
14308 + maxFmtLen * sizeof(char)
14309 +(maxCount + 1) * sizeof(char)
14310 +1;
14311 fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
14312 memset(fmtObj, 0, approxSize);
14313 fmtObj->size = approxSize;
14314 fmtObj->maxPos = 0;
14315 fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14321,12 +14397,12 @@
14321 for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
14322 int width = 0, skip;
14323 ScanFmtPartDescr *descr = &fmtObj->descr[curr];
14324
14325 fmtObj->count++;
14326 descr->width = 0;
14327
14328 if (*fmt != '%' || fmt[1] == '%') {
14329 descr->type = 0;
14330 descr->prefix = &buffer[i];
14331 for (; fmt < fmtEnd; ++fmt) {
14332 if (*fmt == '%') {
@@ -14336,65 +14412,65 @@
14336 }
14337 buffer[i++] = *fmt;
14338 }
14339 buffer[i++] = 0;
14340 }
14341
14342 ++fmt;
14343
14344 if (fmt >= fmtEnd)
14345 goto done;
14346 descr->pos = 0;
14347 if (*fmt == '*') {
14348 descr->pos = -1;
14349 ++fmt;
14350 }
14351 else
14352 fmtObj->convCount++;
14353
14354 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14355 fmt += skip;
14356
14357 if (descr->pos != -1 && *fmt == '$') {
14358 int prev;
14359
14360 ++fmt;
14361 descr->pos = width;
14362 width = 0;
14363
14364 if ((lastPos == 0 && descr->pos > 0)
14365 || (lastPos > 0 && descr->pos == 0)) {
14366 fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
14367 return JIM_ERR;
14368 }
14369
14370 for (prev = 0; prev < curr; ++prev) {
14371 if (fmtObj->descr[prev].pos == -1)
14372 continue;
14373 if (fmtObj->descr[prev].pos == descr->pos) {
14374 fmtObj->error =
14375 "variable is assigned by multiple \"%n$\" conversion specifiers";
14376 return JIM_ERR;
14377 }
14378 }
14379
14380 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14381 descr->width = width;
14382 fmt += skip;
14383 }
14384 if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
14385 fmtObj->maxPos = descr->pos;
14386 }
14387 else {
14388
14389 descr->width = width;
14390 }
14391 }
14392
14393 if (lastPos == -1)
14394 lastPos = descr->pos;
14395
14396 if (*fmt == '[') {
14397 int swapped = 1, beg = i, end, j;
14398
14399 descr->type = '[';
14400 descr->arg = &buffer[i];
@@ -14409,11 +14485,11 @@
14409 fmtObj->error = "unmatched [ in format string";
14410 return JIM_ERR;
14411 }
14412 end = i;
14413 buffer[i++] = 0;
14414
14415 while (swapped) {
14416 swapped = 0;
14417 for (j = beg + 1; j < end - 1; ++j) {
14418 if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
14419 char tmp = buffer[j - 1];
@@ -14424,11 +14500,11 @@
14424 }
14425 }
14426 }
14427 }
14428 else {
14429
14430 if (strchr("hlL", *fmt) != 0)
14431 descr->modifier = tolower((int)*fmt++);
14432
14433 descr->type = *fmt;
14434 if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14467,11 +14543,11 @@
14467 while (*str) {
14468 int c;
14469 int n;
14470
14471 if (!sdescr && isspace(UCHAR(*str)))
14472 break;
14473
14474 n = utf8_tounicode(str, &c);
14475 if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
14476 break;
14477 while (n--)
@@ -14490,89 +14566,89 @@
14490 size_t scanned = 0;
14491 size_t anchor = pos;
14492 int i;
14493 Jim_Obj *tmpObj = NULL;
14494
14495
14496 *valObjPtr = 0;
14497 if (descr->prefix) {
14498 for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
14499
14500 if (isspace(UCHAR(descr->prefix[i])))
14501 while (pos < strLen && isspace(UCHAR(str[pos])))
14502 ++pos;
14503 else if (descr->prefix[i] != str[pos])
14504 break;
14505 else
14506 ++pos;
14507 }
14508 if (pos >= strLen) {
14509 return -1;
14510 }
14511 else if (descr->prefix[i] != 0)
14512 return 0;
14513 }
14514
14515 if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
14516 while (isspace(UCHAR(str[pos])))
14517 ++pos;
14518
14519 scanned = pos - anchor;
14520
14521
14522 if (descr->type == 'n') {
14523
14524 *valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
14525 }
14526 else if (pos >= strLen) {
14527
14528 return -1;
14529 }
14530 else if (descr->type == 'c') {
14531 int c;
14532 scanned += utf8_tounicode(&str[pos], &c);
14533 *valObjPtr = Jim_NewIntObj(interp, c);
14534 return scanned;
14535 }
14536 else {
14537
14538 if (descr->width > 0) {
14539 size_t sLen = utf8_strlen(&str[pos], strLen - pos);
14540 size_t tLen = descr->width > sLen ? sLen : descr->width;
14541
14542 tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
14543 tok = tmpObj->bytes;
14544 }
14545 else {
14546
14547 tok = &str[pos];
14548 }
14549 switch (descr->type) {
14550 case 'd':
14551 case 'o':
14552 case 'x':
14553 case 'u':
14554 case 'i':{
14555 char *endp;
14556 jim_wide w;
14557
14558 int base = descr->type == 'o' ? 8
14559 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
14560
14561
14562 if (base == 0) {
14563 w = jim_strtoull(tok, &endp);
14564 }
14565 else {
14566 w = strtoull(tok, &endp, base);
14567 }
14568
14569 if (endp != tok) {
14570
14571 *valObjPtr = Jim_NewIntObj(interp, w);
14572
14573
14574 scanned += endp - tok;
14575 }
14576 else {
14577 scanned = *tok ? 0 : -1;
14578 }
@@ -14589,13 +14665,13 @@
14589 case 'g':{
14590 char *endp;
14591 double value = strtod(tok, &endp);
14592
14593 if (endp != tok) {
14594
14595 *valObjPtr = Jim_NewDoubleObj(interp, value);
14596
14597 scanned += endp - tok;
14598 }
14599 else {
14600 scanned = *tok ? 0 : -1;
14601 }
@@ -14620,65 +14696,65 @@
14620 Jim_Obj **resultVec = 0;
14621 int resultc;
14622 Jim_Obj *emptyStr = 0;
14623 ScanFmtStringObj *fmtObj;
14624
14625
14626 JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
14627
14628 fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
14629
14630 if (fmtObj->error != 0) {
14631 if (flags & JIM_ERRMSG)
14632 Jim_SetResultString(interp, fmtObj->error, -1);
14633 return 0;
14634 }
14635
14636 emptyStr = Jim_NewEmptyStringObj(interp);
14637 Jim_IncrRefCount(emptyStr);
14638
14639 resultList = Jim_NewListObj(interp, NULL, 0);
14640 if (fmtObj->maxPos > 0) {
14641 for (i = 0; i < fmtObj->maxPos; ++i)
14642 Jim_ListAppendElement(interp, resultList, emptyStr);
14643 JimListGetElements(interp, resultList, &resultc, &resultVec);
14644 }
14645
14646 for (i = 0, pos = 0; i < fmtObj->count; ++i) {
14647 ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
14648 Jim_Obj *value = 0;
14649
14650
14651 if (descr->type == 0)
14652 continue;
14653
14654 if (scanned > 0)
14655 scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
14656
14657 if (scanned == -1 && i == 0)
14658 goto eof;
14659
14660 pos += scanned;
14661
14662
14663 if (value == 0)
14664 value = Jim_NewEmptyStringObj(interp);
14665
14666 if (descr->pos == -1) {
14667 Jim_FreeNewObj(interp, value);
14668 }
14669 else if (descr->pos == 0)
14670
14671 Jim_ListAppendElement(interp, resultList, value);
14672 else if (resultVec[descr->pos - 1] == emptyStr) {
14673
14674 Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
14675 Jim_IncrRefCount(value);
14676 resultVec[descr->pos - 1] = value;
14677 }
14678 else {
14679
14680 Jim_FreeNewObj(interp, value);
14681 goto err;
14682 }
14683 }
14684 Jim_DecrRefCount(interp, emptyStr);
@@ -14716,15 +14792,15 @@
14716 {
14717 Jim_PrngState *prng;
14718 unsigned char *destByte = (unsigned char *)dest;
14719 unsigned int si, sj, x;
14720
14721
14722 if (interp->prngState == NULL)
14723 JimPrngInit(interp);
14724 prng = interp->prngState;
14725
14726 for (x = 0; x < len; x++) {
14727 prng->i = (prng->i + 1) & 0xff;
14728 si = prng->sbox[prng->i];
14729 prng->j = (prng->j + si) & 0xff;
14730 sj = prng->sbox[prng->j];
@@ -14738,19 +14814,19 @@
14738 static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
14739 {
14740 int i;
14741 Jim_PrngState *prng;
14742
14743
14744 if (interp->prngState == NULL)
14745 JimPrngInit(interp);
14746 prng = interp->prngState;
14747
14748
14749 for (i = 0; i < 256; i++)
14750 prng->sbox[i] = i;
14751
14752 for (i = 0; i < seedLen; i++) {
14753 unsigned char t;
14754
14755 t = prng->sbox[i & 0xFF];
14756 prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14777,11 +14853,11 @@
14777 if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
14778 return JIM_ERR;
14779 }
14780 intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
14781 if (!intObjPtr) {
14782
14783 wideValue = 0;
14784 }
14785 else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
14786 return JIM_ERR;
14787 }
@@ -14791,26 +14867,26 @@
14791 Jim_FreeNewObj(interp, intObjPtr);
14792 return JIM_ERR;
14793 }
14794 }
14795 else {
14796
14797 Jim_InvalidateStringRep(intObjPtr);
14798 JimWideValue(intObjPtr) = wideValue + increment;
14799
14800 if (argv[1]->typePtr != &variableObjType) {
14801
14802 Jim_SetVariable(interp, argv[1], intObjPtr);
14803 }
14804 }
14805 Jim_SetResult(interp, intObjPtr);
14806 return JIM_OK;
14807 }
14808
14809
14810 #define JIM_EVAL_SARGV_LEN 8
14811 #define JIM_EVAL_SINTV_LEN 8
14812
14813
14814 static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
14815 {
14816 int retcode;
@@ -14818,16 +14894,16 @@
14818 if (interp->unknown_called > 50) {
14819 return JIM_ERR;
14820 }
14821
14822
14823
14824 if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
14825 return JIM_ERR;
14826
14827 interp->unknown_called++;
14828
14829 retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
14830 interp->unknown_called--;
14831
14832 return retcode;
14833 }
@@ -14845,11 +14921,11 @@
14845 }
14846 printf("\n");
14847 #endif
14848
14849 if (interp->framePtr->tailcallCmd) {
14850
14851 cmdPtr = interp->framePtr->tailcallCmd;
14852 interp->framePtr->tailcallCmd = NULL;
14853 }
14854 else {
14855 cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14864,11 +14940,11 @@
14864 retcode = JIM_ERR;
14865 goto out;
14866 }
14867 interp->evalDepth++;
14868
14869
14870 Jim_SetEmptyResult(interp);
14871 if (cmdPtr->isproc) {
14872 retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
14873 }
14874 else {
@@ -14885,17 +14961,17 @@
14885
14886 int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
14887 {
14888 int i, retcode;
14889
14890
14891 for (i = 0; i < objc; i++)
14892 Jim_IncrRefCount(objv[i]);
14893
14894 retcode = JimInvokeCommand(interp, objc, objv);
14895
14896
14897 for (i = 0; i < objc; i++)
14898 Jim_DecrRefCount(interp, objv[i]);
14899
14900 return retcode;
14901 }
@@ -14913,25 +14989,25 @@
14913 }
14914
14915 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
14916 {
14917 if (!interp->errorFlag) {
14918
14919 interp->errorFlag = 1;
14920 Jim_IncrRefCount(script->fileNameObj);
14921 Jim_DecrRefCount(interp, interp->errorFileNameObj);
14922 interp->errorFileNameObj = script->fileNameObj;
14923 interp->errorLine = script->linenr;
14924
14925 JimResetStackTrace(interp);
14926
14927 interp->addStackTrace++;
14928 }
14929
14930
14931 if (interp->addStackTrace > 0) {
14932
14933
14934 JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
14935
14936 if (Jim_Length(script->fileNameObj)) {
14937 interp->addStackTrace = 0;
@@ -14966,14 +15042,14 @@
14966 case JIM_OK:
14967 case JIM_RETURN:
14968 objPtr = interp->result;
14969 break;
14970 case JIM_BREAK:
14971
14972 return JIM_BREAK;
14973 case JIM_CONTINUE:
14974
14975 return JIM_CONTINUE;
14976 default:
14977 return JIM_ERR;
14978 }
14979 break;
@@ -15008,23 +15084,23 @@
15008 case JIM_OK:
15009 case JIM_RETURN:
15010 break;
15011 case JIM_BREAK:
15012 if (flags & JIM_SUBST_FLAG) {
15013
15014 tokens = i;
15015 continue;
15016 }
15017
15018
15019 case JIM_CONTINUE:
15020 if (flags & JIM_SUBST_FLAG) {
15021 intv[i] = NULL;
15022 continue;
15023 }
15024
15025
15026 default:
15027 while (i--) {
15028 Jim_DecrRefCount(interp, intv[i]);
15029 }
15030 if (intv != sintv) {
@@ -15035,28 +15111,28 @@
15035 Jim_IncrRefCount(intv[i]);
15036 Jim_String(intv[i]);
15037 totlen += intv[i]->length;
15038 }
15039
15040
15041 if (tokens == 1 && intv[0] && intv == sintv) {
15042 Jim_DecrRefCount(interp, intv[0]);
15043 return intv[0];
15044 }
15045
15046 objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
15047
15048 if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
15049 && token[2].type == JIM_TT_VAR) {
15050
15051 objPtr->typePtr = &interpolatedObjType;
15052 objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
15053 objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
15054 Jim_IncrRefCount(intv[2]);
15055 }
15056 else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
15057
15058 JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
15059 }
15060
15061
15062 s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -15067,11 +15143,11 @@
15067 s += intv[i]->length;
15068 Jim_DecrRefCount(interp, intv[i]);
15069 }
15070 }
15071 objPtr->bytes[totlen] = '\0';
15072
15073 if (intv != sintv) {
15074 Jim_Free(intv);
15075 }
15076
15077 return objPtr;
@@ -15111,11 +15187,11 @@
15111
15112 if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
15113 return JimEvalObjList(interp, scriptObjPtr);
15114 }
15115
15116 Jim_IncrRefCount(scriptObjPtr);
15117 script = JimGetScript(interp, scriptObjPtr);
15118 if (!JimScriptValid(interp, script)) {
15119 Jim_DecrRefCount(interp, scriptObjPtr);
15120 return JIM_ERR;
15121 }
@@ -15147,11 +15223,11 @@
15147 }
15148 #endif
15149
15150 script->inUse++;
15151
15152
15153 prevScriptObj = interp->currentScriptObj;
15154 interp->currentScriptObj = scriptObjPtr;
15155
15156 interp->errorFlag = 0;
15157 argv = sargv;
@@ -15158,19 +15234,19 @@
15158
15159 for (i = 0; i < script->len && retcode == JIM_OK; ) {
15160 int argc;
15161 int j;
15162
15163
15164 argc = token[i].objPtr->internalRep.scriptLineValue.argc;
15165 script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
15166
15167
15168 if (argc > JIM_EVAL_SARGV_LEN)
15169 argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
15170
15171
15172 i++;
15173
15174 for (j = 0; j < argc; j++) {
15175 long wordtokens = 1;
15176 int expand = 0;
@@ -15226,11 +15302,11 @@
15226
15227 if (!expand) {
15228 argv[j] = wordObjPtr;
15229 }
15230 else {
15231
15232 int len = Jim_ListLength(interp, wordObjPtr);
15233 int newargc = argc + len - 1;
15234 int k;
15235
15236 if (len > 1) {
@@ -15239,39 +15315,39 @@
15239 argv = Jim_Alloc(sizeof(*argv) * newargc);
15240 memcpy(argv, sargv, sizeof(*argv) * j);
15241 }
15242 }
15243 else {
15244
15245 argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
15246 }
15247 }
15248
15249
15250 for (k = 0; k < len; k++) {
15251 argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
15252 Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
15253 }
15254
15255 Jim_DecrRefCount(interp, wordObjPtr);
15256
15257
15258 j--;
15259 argc += len - 1;
15260 }
15261 }
15262
15263 if (retcode == JIM_OK && argc) {
15264
15265 retcode = JimInvokeCommand(interp, argc, argv);
15266
15267 if (Jim_CheckSignal(interp)) {
15268 retcode = JIM_SIGNAL;
15269 }
15270 }
15271
15272
15273 while (j-- > 0) {
15274 Jim_DecrRefCount(interp, argv[j]);
15275 }
15276
15277 if (argv != sargv) {
@@ -15278,21 +15354,21 @@
15278 Jim_Free(argv);
15279 argv = sargv;
15280 }
15281 }
15282
15283
15284 if (retcode == JIM_ERR) {
15285 JimAddErrorToStack(interp, script);
15286 }
15287
15288 else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
15289
15290 interp->addStackTrace = 0;
15291 }
15292
15293
15294 interp->currentScriptObj = prevScriptObj;
15295
15296 Jim_FreeIntRep(interp, scriptObjPtr);
15297 scriptObjPtr->typePtr = &scriptObjType;
15298 Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15302,14 +15378,14 @@
15302 }
15303
15304 static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
15305 {
15306 int retcode;
15307
15308 const char *varname = Jim_String(argNameObj);
15309 if (*varname == '&') {
15310
15311 Jim_Obj *objPtr;
15312 Jim_CallFrame *savedCallFrame = interp->framePtr;
15313
15314 interp->framePtr = interp->framePtr->parent;
15315 objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15316,11 +15392,11 @@
15316 interp->framePtr = savedCallFrame;
15317 if (!objPtr) {
15318 return JIM_ERR;
15319 }
15320
15321
15322 objPtr = Jim_NewStringObj(interp, varname + 1, -1);
15323 Jim_IncrRefCount(objPtr);
15324 retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
15325 Jim_DecrRefCount(interp, objPtr);
15326 }
@@ -15330,26 +15406,26 @@
15330 return retcode;
15331 }
15332
15333 static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
15334 {
15335
15336 Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
15337 int i;
15338
15339 for (i = 0; i < cmd->u.proc.argListLen; i++) {
15340 Jim_AppendString(interp, argmsg, " ", 1);
15341
15342 if (i == cmd->u.proc.argsPos) {
15343 if (cmd->u.proc.arglist[i].defaultObjPtr) {
15344
15345 Jim_AppendString(interp, argmsg, "?", 1);
15346 Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
15347 Jim_AppendString(interp, argmsg, " ...?", -1);
15348 }
15349 else {
15350
15351 Jim_AppendString(interp, argmsg, "?arg...?", -1);
15352 }
15353 }
15354 else {
15355 if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15374,11 +15450,11 @@
15374 int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
15375 {
15376 Jim_CallFrame *callFramePtr;
15377 int retcode;
15378
15379
15380 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
15381 callFramePtr->argv = &interp->emptyObj;
15382 callFramePtr->argc = 0;
15383 callFramePtr->procArgsObjPtr = NULL;
15384 callFramePtr->procBodyObjPtr = scriptObj;
@@ -15386,21 +15462,21 @@
15386 callFramePtr->fileNameObj = interp->emptyObj;
15387 callFramePtr->line = 0;
15388 Jim_IncrRefCount(scriptObj);
15389 interp->framePtr = callFramePtr;
15390
15391
15392 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15393 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15394 retcode = JIM_ERR;
15395 }
15396 else {
15397
15398 retcode = Jim_EvalObj(interp, scriptObj);
15399 }
15400
15401
15402 interp->framePtr = interp->framePtr->parent;
15403 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15404
15405 return retcode;
15406 }
@@ -15410,62 +15486,62 @@
15410 {
15411 Jim_CallFrame *callFramePtr;
15412 int i, d, retcode, optargs;
15413 ScriptObj *script;
15414
15415
15416 if (argc - 1 < cmd->u.proc.reqArity ||
15417 (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
15418 JimSetProcWrongArgs(interp, argv[0], cmd);
15419 return JIM_ERR;
15420 }
15421
15422 if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15423
15424 return JIM_OK;
15425 }
15426
15427
15428 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15429 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15430 return JIM_ERR;
15431 }
15432
15433
15434 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
15435 callFramePtr->argv = argv;
15436 callFramePtr->argc = argc;
15437 callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
15438 callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
15439 callFramePtr->staticVars = cmd->u.proc.staticVars;
15440
15441
15442 script = JimGetScript(interp, interp->currentScriptObj);
15443 callFramePtr->fileNameObj = script->fileNameObj;
15444 callFramePtr->line = script->linenr;
15445
15446 Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
15447 Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
15448 interp->framePtr = callFramePtr;
15449
15450
15451 optargs = (argc - 1 - cmd->u.proc.reqArity);
15452
15453
15454 i = 1;
15455 for (d = 0; d < cmd->u.proc.argListLen; d++) {
15456 Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
15457 if (d == cmd->u.proc.argsPos) {
15458
15459 Jim_Obj *listObjPtr;
15460 int argsLen = 0;
15461 if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
15462 argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
15463 }
15464 listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
15465
15466
15467 if (cmd->u.proc.arglist[d].defaultObjPtr) {
15468 nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
15469 }
15470 retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
15471 if (retcode != JIM_OK) {
@@ -15474,33 +15550,33 @@
15474
15475 i += argsLen;
15476 continue;
15477 }
15478
15479
15480 if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
15481 retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
15482 }
15483 else {
15484
15485 retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
15486 }
15487 if (retcode != JIM_OK) {
15488 goto badargset;
15489 }
15490 }
15491
15492
15493 retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
15494
15495 badargset:
15496
15497
15498 interp->framePtr = interp->framePtr->parent;
15499 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15500
15501
15502 if (interp->framePtr->tailcallObj) {
15503 do {
15504 Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
15505
15506 interp->framePtr->tailcallObj = NULL;
@@ -15512,18 +15588,18 @@
15512 }
15513 }
15514 Jim_DecrRefCount(interp, tailcallObj);
15515 } while (interp->framePtr->tailcallObj);
15516
15517
15518 if (interp->framePtr->tailcallCmd) {
15519 JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
15520 interp->framePtr->tailcallCmd = NULL;
15521 }
15522 }
15523
15524
15525 if (retcode == JIM_RETURN) {
15526 if (--interp->returnLevel <= 0) {
15527 retcode = interp->returnCode;
15528 interp->returnCode = JIM_OK;
15529 interp->returnLevel = 0;
@@ -15635,20 +15711,20 @@
15635 prevScriptObj = interp->currentScriptObj;
15636 interp->currentScriptObj = scriptObjPtr;
15637
15638 retcode = Jim_EvalObj(interp, scriptObjPtr);
15639
15640
15641 if (retcode == JIM_RETURN) {
15642 if (--interp->returnLevel <= 0) {
15643 retcode = interp->returnCode;
15644 interp->returnCode = JIM_OK;
15645 interp->returnLevel = 0;
15646 }
15647 }
15648 if (retcode == JIM_ERR) {
15649
15650 interp->addStackTrace++;
15651 }
15652
15653 interp->currentScriptObj = prevScriptObj;
15654
@@ -15674,11 +15750,11 @@
15674 }
15675 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15676 if (JimParseVar(pc) == JIM_OK) {
15677 return;
15678 }
15679
15680 pc->tstart = pc->p;
15681 flags |= JIM_SUBST_NOVAR;
15682 }
15683 while (pc->len) {
15684 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15705,32 +15781,32 @@
15705 const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
15706 struct JimParserCtx parser;
15707 struct ScriptObj *script = Jim_Alloc(sizeof(*script));
15708 ParseTokenList tokenlist;
15709
15710
15711 ScriptTokenListInit(&tokenlist);
15712
15713 JimParserInit(&parser, scriptText, scriptTextLen, 1);
15714 while (1) {
15715 JimParseSubst(&parser, flags);
15716 if (parser.eof) {
15717
15718 break;
15719 }
15720 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
15721 parser.tline);
15722 }
15723
15724
15725 script->inUse = 1;
15726 script->substFlags = flags;
15727 script->fileNameObj = interp->emptyObj;
15728 Jim_IncrRefCount(script->fileNameObj);
15729 SubstObjAddTokens(interp, script, &tokenlist);
15730
15731
15732 ScriptTokenListFree(&tokenlist);
15733
15734 #ifdef DEBUG_SHOW_SUBST
15735 {
15736 int i;
@@ -15741,11 +15817,11 @@
15741 Jim_String(script->token[i].objPtr));
15742 }
15743 }
15744 #endif
15745
15746
15747 Jim_FreeIntRep(interp, objPtr);
15748 Jim_SetIntRepPtr(objPtr, script);
15749 objPtr->typePtr = &scriptObjType;
15750 return JIM_OK;
15751 }
@@ -15759,11 +15835,11 @@
15759
15760 int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
15761 {
15762 ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
15763
15764 Jim_IncrRefCount(substObjPtr);
15765 script->inUse++;
15766
15767 *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
15768
15769 script->inUse--;
@@ -15775,15 +15851,11 @@
15775 }
15776
15777 void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
15778 {
15779 Jim_Obj *objPtr;
15780 Jim_Obj *listObjPtr;
15781
15782 JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0"));
15783
15784 listObjPtr = Jim_NewListObj(interp, argv, argc);
15785
15786 if (*msg) {
15787 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
15788 }
15789 Jim_IncrRefCount(listObjPtr);
@@ -15804,11 +15876,11 @@
15804 JimHashtableIteratorCallbackType *callback, int type)
15805 {
15806 Jim_HashEntry *he;
15807 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
15808
15809
15810 if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
15811 he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
15812 if (he) {
15813 callback(interp, listObjPtr, he, type);
15814 }
@@ -15835,11 +15907,11 @@
15835 {
15836 Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
15837 Jim_Obj *objPtr;
15838
15839 if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
15840
15841 return;
15842 }
15843
15844 objPtr = Jim_NewStringObj(interp, he->key, -1);
15845 Jim_IncrRefCount(objPtr);
@@ -15895,11 +15967,11 @@
15895
15896 targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
15897 if (targetCallFrame == NULL) {
15898 return JIM_ERR;
15899 }
15900
15901 if (targetCallFrame == interp->topFramePtr) {
15902 Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
15903 return JIM_ERR;
15904 }
15905 if (info_level_cmd) {
@@ -16082,11 +16154,11 @@
16082 if (!objPtr)
16083 return JIM_ERR;
16084 Jim_SetResult(interp, objPtr);
16085 return JIM_OK;
16086 }
16087
16088 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
16089 return JIM_ERR;
16090 Jim_SetResult(interp, argv[2]);
16091 return JIM_OK;
16092 }
@@ -16125,11 +16197,11 @@
16125 if (argc != 3) {
16126 Jim_WrongNumArgs(interp, 1, argv, "condition body");
16127 return JIM_ERR;
16128 }
16129
16130
16131 while (1) {
16132 int boolean, retval;
16133
16134 if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
16135 return retval;
@@ -16165,11 +16237,11 @@
16165 if (argc != 5) {
16166 Jim_WrongNumArgs(interp, 1, argv, "start test next body");
16167 return JIM_ERR;
16168 }
16169
16170
16171 if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
16172 return retval;
16173 }
16174
16175 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16181,19 +16253,19 @@
16181 ExprByteCode *expr;
16182 jim_wide stop, currentVal;
16183 Jim_Obj *objPtr;
16184 int cmpOffset;
16185
16186
16187 expr = JimGetExpression(interp, argv[2]);
16188 incrScript = JimGetScript(interp, argv[3]);
16189
16190
16191 if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
16192 goto evalstart;
16193 }
16194
16195 if (incrScript->token[1].type != JIM_TT_ESC ||
16196 expr->token[0].type != JIM_TT_VAR ||
16197 (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
16198 goto evalstart;
16199 }
@@ -16206,48 +16278,48 @@
16206 }
16207 else {
16208 goto evalstart;
16209 }
16210
16211
16212 if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
16213 goto evalstart;
16214 }
16215
16216
16217 if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
16218 goto evalstart;
16219 }
16220
16221
16222 if (expr->token[1].type == JIM_TT_EXPR_INT) {
16223 if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
16224 goto evalstart;
16225 }
16226 }
16227 else {
16228 stopVarNamePtr = expr->token[1].objPtr;
16229 Jim_IncrRefCount(stopVarNamePtr);
16230
16231 stop = 0;
16232 }
16233
16234
16235 varNamePtr = expr->token[0].objPtr;
16236 Jim_IncrRefCount(varNamePtr);
16237
16238 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
16239 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &currentVal) != JIM_OK) {
16240 goto testcond;
16241 }
16242
16243
16244 while (retval == JIM_OK) {
 
 
16245
16246
16247
16248
16249 if (stopVarNamePtr) {
16250 objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
16251 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
16252 goto testcond;
16253 }
@@ -16255,18 +16327,18 @@
16255
16256 if (currentVal >= stop + cmpOffset) {
16257 break;
16258 }
16259
16260
16261 retval = Jim_EvalObj(interp, argv[4]);
16262 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16263 retval = JIM_OK;
16264
16265 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
16266
16267
16268 if (objPtr == NULL) {
16269 retval = JIM_ERR;
16270 goto out;
16271 }
16272 if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16286,25 +16358,25 @@
16286 }
16287 evalstart:
16288 #endif
16289
16290 while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
16291
16292 retval = Jim_EvalObj(interp, argv[4]);
16293
16294 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16295
16296 JIM_IF_OPTIM(evalnext:)
16297 retval = Jim_EvalObj(interp, argv[3]);
16298 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16299
16300 JIM_IF_OPTIM(testcond:)
16301 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
16302 }
16303 }
16304 }
16305 JIM_IF_OPTIM(out:)
16306 if (stopVarNamePtr) {
16307 Jim_DecrRefCount(interp, stopVarNamePtr);
16308 }
16309 if (varNamePtr) {
16310 Jim_DecrRefCount(interp, varNamePtr);
@@ -16346,11 +16418,11 @@
16346 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16347 Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
16348
16349 retval = JIM_OK;
16350
16351
16352 i += incr;
16353
16354 if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
16355 if (argv[1]->typePtr != &variableObjType) {
16356 if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16411,21 +16483,21 @@
16411
16412 static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
16413 {
16414 int result = JIM_OK;
16415 int i, numargs;
16416 Jim_ListIter twoiters[2];
16417 Jim_ListIter *iters;
16418 Jim_Obj *script;
16419 Jim_Obj *resultObj;
16420
16421 if (argc < 4 || argc % 2 != 0) {
16422 Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
16423 return JIM_ERR;
16424 }
16425 script = argv[argc - 1];
16426 numargs = (argc - 1 - 1);
16427
16428 if (numargs == 2) {
16429 iters = twoiters;
16430 }
16431 else {
@@ -16449,34 +16521,34 @@
16449 resultObj = interp->emptyObj;
16450 }
16451 Jim_IncrRefCount(resultObj);
16452
16453 while (1) {
16454
16455 for (i = 0; i < numargs; i += 2) {
16456 if (!JimListIterDone(interp, &iters[i + 1])) {
16457 break;
16458 }
16459 }
16460 if (i == numargs) {
16461
16462 break;
16463 }
16464
16465
16466 for (i = 0; i < numargs; i += 2) {
16467 Jim_Obj *varName;
16468
16469
16470 JimListIterInit(&iters[i], argv[i + 1]);
16471 while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
16472 Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
16473 if (!valObj) {
16474
16475 valObj = interp->emptyObj;
16476 }
16477
16478 Jim_IncrRefCount(valObj);
16479 result = Jim_SetVariable(interp, varName, valObj);
16480 Jim_DecrRefCount(interp, valObj);
16481 if (result != JIM_OK) {
16482 goto err;
@@ -16558,41 +16630,41 @@
16558 {
16559 int boolean, retval, current = 1, falsebody = 0;
16560
16561 if (argc >= 3) {
16562 while (1) {
16563
16564 if (current >= argc)
16565 goto err;
16566 if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
16567 != JIM_OK)
16568 return retval;
16569
16570 if (current >= argc)
16571 goto err;
16572 if (Jim_CompareStringImmediate(interp, argv[current], "then"))
16573 current++;
16574
16575 if (current >= argc)
16576 goto err;
16577 if (boolean)
16578 return Jim_EvalObj(interp, argv[current]);
16579
16580 if (++current >= argc) {
16581 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
16582 return JIM_OK;
16583 }
16584 falsebody = current++;
16585 if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
16586
16587 if (current != argc - 1)
16588 goto err;
16589 return Jim_EvalObj(interp, argv[current]);
16590 }
16591 else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
16592 continue;
16593
16594 else if (falsebody != argc - 1)
16595 goto err;
16596 return Jim_EvalObj(interp, argv[falsebody]);
16597 }
16598 return JIM_OK;
@@ -16700,21 +16772,21 @@
16700 if (Jim_StringMatchObj(interp, patObj, strObj, 0))
16701 script = caseList[i + 1];
16702 break;
16703 case SWITCH_RE:
16704 command = Jim_NewStringObj(interp, "regexp", -1);
16705
16706 case SWITCH_CMD:{
16707 int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
16708
16709 if (argc - opt == 1) {
16710 Jim_Obj **vector;
16711
16712 JimListGetElements(interp, argv[opt], &patCount, &vector);
16713 caseList = vector;
16714 }
16715
16716 if (rc < 0) {
16717 return -rc;
16718 }
16719 if (rc)
16720 script = caseList[i + 1];
@@ -16848,11 +16920,11 @@
16848 case OPT_COMMAND:
16849 if (i >= argc - 2) {
16850 goto wrongargs;
16851 }
16852 commandObj = argv[++i];
16853
16854 case OPT_EXACT:
16855 case OPT_GLOB:
16856 case OPT_REGEXP:
16857 opt_match = option;
16858 break;
@@ -16896,17 +16968,17 @@
16896 goto done;
16897 }
16898 break;
16899 }
16900
16901
16902 if (!eq && opt_bool && opt_not && !opt_all) {
16903 continue;
16904 }
16905
16906 if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
16907
16908 Jim_Obj *resultObj;
16909
16910 if (opt_bool) {
16911 resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
16912 }
@@ -16929,11 +17001,11 @@
16929
16930 if (opt_all) {
16931 Jim_SetResult(interp, listObjPtr);
16932 }
16933 else {
16934
16935 if (opt_bool) {
16936 Jim_SetResultBool(interp, opt_not);
16937 }
16938 else if (!opt_inline) {
16939 Jim_SetResultInt(interp, -1);
@@ -16958,11 +17030,11 @@
16958 Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
16959 return JIM_ERR;
16960 }
16961 listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
16962 if (!listObjPtr) {
16963
16964 listObjPtr = Jim_NewListObj(interp, NULL, 0);
16965 new_obj = 1;
16966 }
16967 else if (Jim_IsShared(listObjPtr)) {
16968 listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
@@ -17031,31 +17103,31 @@
17031 first = JimRelToAbsIndex(len, first);
17032 last = JimRelToAbsIndex(len, last);
17033 JimRelToAbsRange(len, &first, &last, &rangeLen);
17034
17035
17036
17037 if (first < len) {
17038
17039 }
17040 else if (len == 0) {
17041
17042 first = 0;
17043 }
17044 else {
17045 Jim_SetResultString(interp, "list doesn't contain element ", -1);
17046 Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
17047 return JIM_ERR;
17048 }
17049
17050
17051 newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
17052
17053
17054 ListInsertElements(newListObj, -1, argc - 4, argv + 4);
17055
17056
17057 ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
17058
17059 Jim_SetResult(interp, newListObj);
17060 return JIM_OK;
17061 }
@@ -17066,11 +17138,11 @@
17066 if (argc < 3) {
17067 Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
17068 return JIM_ERR;
17069 }
17070 else if (argc == 3) {
17071
17072 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
17073 return JIM_ERR;
17074 Jim_SetResult(interp, argv[2]);
17075 return JIM_OK;
17076 }
@@ -17181,11 +17253,11 @@
17181 }
17182 else {
17183 int new_obj = 0;
17184 stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
17185 if (!stringObjPtr) {
17186
17187 stringObjPtr = Jim_NewEmptyStringObj(interp);
17188 new_obj = 1;
17189 }
17190 else if (Jim_IsShared(stringObjPtr)) {
17191 new_obj = 1;
@@ -17230,11 +17302,11 @@
17230 else {
17231 rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
17232 }
17233
17234 if (rc == JIM_ERR) {
17235
17236 interp->addStackTrace++;
17237 }
17238 return rc;
17239 }
17240
@@ -17244,14 +17316,14 @@
17244 if (argc >= 2) {
17245 int retcode;
17246 Jim_CallFrame *savedCallFrame, *targetCallFrame;
17247 const char *str;
17248
17249
17250 savedCallFrame = interp->framePtr;
17251
17252
17253 str = Jim_String(argv[1]);
17254 if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
17255 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17256 argc--;
17257 argv++;
@@ -17264,11 +17336,11 @@
17264 }
17265 if (argc < 2) {
17266 Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
17267 return JIM_ERR;
17268 }
17269
17270 interp->framePtr = targetCallFrame;
17271 if (argc == 2) {
17272 retcode = Jim_EvalObj(interp, argv[1]);
17273 }
17274 else {
@@ -17366,15 +17438,15 @@
17366 if (i != argc - 1 && i != argc) {
17367 Jim_WrongNumArgs(interp, 1, argv,
17368 "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
17369 }
17370
17371
17372 if (stackTraceObj && returnCode == JIM_ERR) {
17373 JimSetStackTrace(interp, stackTraceObj);
17374 }
17375
17376 if (errorCodeObj && returnCode == JIM_ERR) {
17377 Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
17378 }
17379 interp->returnCode = returnCode;
17380 interp->returnLevel = level;
@@ -17391,31 +17463,31 @@
17391 if (interp->framePtr->level == 0) {
17392 Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
17393 return JIM_ERR;
17394 }
17395 else if (argc >= 2) {
17396
17397 Jim_CallFrame *cf = interp->framePtr->parent;
17398
17399 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17400 if (cmdPtr == NULL) {
17401 return JIM_ERR;
17402 }
17403
17404 JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
17405
17406
17407 JimIncrCmdRefCount(cmdPtr);
17408 cf->tailcallCmd = cmdPtr;
17409
17410
17411 JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
17412
17413 cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
17414 Jim_IncrRefCount(cf->tailcallObj);
17415
17416
17417 return JIM_EVAL;
17418 }
17419 return JIM_OK;
17420 }
17421
@@ -17422,11 +17494,11 @@
17422 static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17423 {
17424 Jim_Obj *cmdList;
17425 Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
17426
17427
17428 cmdList = Jim_DuplicateObj(interp, prefixListObj);
17429 Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
17430
17431 return JimEvalObjList(interp, cmdList);
17432 }
@@ -17480,22 +17552,22 @@
17480 else {
17481 cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
17482 }
17483
17484 if (cmd) {
17485
17486 Jim_Obj *qualifiedCmdNameObj;
17487 const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
17488
17489 JimCreateCommand(interp, cmdname, cmd);
17490
17491
17492 JimUpdateProcNamespace(interp, cmd, cmdname);
17493
17494 JimFreeQualifiedName(interp, qualifiedCmdNameObj);
17495
17496
17497 Jim_SetResult(interp, argv[1]);
17498 return JIM_OK;
17499 }
17500 return JIM_ERR;
17501 }
@@ -17508,17 +17580,17 @@
17508 if (argc < 2) {
17509 Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
17510 return JIM_ERR;
17511 }
17512
17513
17514 interp->local++;
17515 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17516 interp->local--;
17517
17518
17519
17520 if (retcode == 0) {
17521 Jim_Obj *cmdNameObj = Jim_GetResult(interp);
17522
17523 if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
17524 return JIM_ERR;
@@ -17547,18 +17619,18 @@
17547 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17548 if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
17549 Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
17550 return JIM_ERR;
17551 }
17552
17553 cmdPtr->u.proc.upcall++;
17554 JimIncrCmdRefCount(cmdPtr);
17555
17556
17557 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17558
17559
17560 cmdPtr->u.proc.upcall--;
17561 JimDecrCmdRefCount(interp, cmdPtr);
17562
17563 return retcode;
17564 }
@@ -17585,11 +17657,11 @@
17585 return JIM_ERR;
17586 }
17587
17588 if (len == 3) {
17589 #ifdef jim_ext_namespace
17590
17591 nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
17592 #else
17593 Jim_SetResultString(interp, "namespaces not enabled", -1);
17594 return JIM_ERR;
17595 #endif
@@ -17598,11 +17670,11 @@
17598 bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
17599
17600 cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
17601
17602 if (cmd) {
17603
17604 nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
17605 nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
17606 Jim_IncrRefCount(nargv[0]);
17607 memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
17608 ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17628,11 +17700,11 @@
17628 static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17629 {
17630 int i;
17631 Jim_CallFrame *targetCallFrame;
17632
17633
17634 if (argc > 3 && (argc % 2 == 0)) {
17635 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17636 argc--;
17637 argv++;
17638 }
@@ -17641,17 +17713,17 @@
17641 }
17642 if (targetCallFrame == NULL) {
17643 return JIM_ERR;
17644 }
17645
17646
17647 if (argc < 3) {
17648 Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
17649 return JIM_ERR;
17650 }
17651
17652
17653 for (i = 1; i < argc; i += 2) {
17654 if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
17655 return JIM_ERR;
17656 }
17657 return JIM_OK;
@@ -17664,15 +17736,15 @@
17664
17665 if (argc < 2) {
17666 Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
17667 return JIM_ERR;
17668 }
17669
17670 if (interp->framePtr->level == 0)
17671 return JIM_OK;
17672 for (i = 1; i < argc; i++) {
17673
17674 const char *name = Jim_String(argv[i]);
17675 if (name[0] != ':' || name[1] != ':') {
17676 if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
17677 return JIM_ERR;
17678 }
@@ -17695,21 +17767,21 @@
17695 }
17696
17697 str = Jim_String(objPtr);
17698 strLen = Jim_Utf8Length(interp, objPtr);
17699
17700
17701 resultObjPtr = Jim_NewStringObj(interp, "", 0);
17702 while (strLen) {
17703 for (i = 0; i < numMaps; i += 2) {
17704 Jim_Obj *eachObjPtr;
17705 const char *k;
17706 int kl;
17707
17708 eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17709 k = Jim_String(eachObjPtr);
17710 kl = Jim_Utf8Length(interp, eachObjPtr);
17711
17712 if (strLen >= kl && kl) {
17713 int rc;
17714 rc = JimStringCompareLen(str, k, kl, nocase);
17715 if (rc == 0) {
@@ -17722,11 +17794,11 @@
17722 strLen -= kl;
17723 break;
17724 }
17725 }
17726 }
17727 if (i == numMaps) {
17728 int c;
17729 if (noMatchStart == NULL)
17730 noMatchStart = str;
17731 str += utf8_tounicode(str, &c);
17732 strLen--;
@@ -17787,11 +17859,11 @@
17787 return JIM_OK;
17788
17789 case OPT_CAT:{
17790 Jim_Obj *objPtr;
17791 if (argc == 3) {
17792
17793 objPtr = argv[2];
17794 }
17795 else {
17796 int i;
17797
@@ -17806,11 +17878,11 @@
17806 }
17807
17808 case OPT_COMPARE:
17809 case OPT_EQUAL:
17810 {
17811
17812 long opt_length = -1;
17813 int n = argc - 4;
17814 int i = 2;
17815 while (n > 0) {
17816 int subopt;
@@ -17819,16 +17891,16 @@
17819 badcompareargs:
17820 Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
17821 return JIM_ERR;
17822 }
17823 if (subopt == 0) {
17824
17825 opt_case = 0;
17826 n--;
17827 }
17828 else {
17829
17830 if (n < 2) {
17831 goto badcompareargs;
17832 }
17833 if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
17834 return JIM_ERR;
@@ -17839,11 +17911,11 @@
17839 if (n) {
17840 goto badcompareargs;
17841 }
17842 argv += argc - 2;
17843 if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17844
17845 Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
17846 }
17847 else {
17848 if (opt_length >= 0) {
17849 n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -17953,10 +18025,11 @@
17953 }
17954
17955 case OPT_REVERSE:{
17956 char *buf, *p;
17957 const char *str;
 
17958 int i;
17959
17960 if (argc != 3) {
17961 Jim_WrongNumArgs(interp, 2, argv, "string");
17962 return JIM_ERR;
@@ -17996,11 +18069,11 @@
17996 }
17997 if (idx < 0 || idx >= len || str == NULL) {
17998 Jim_SetResultString(interp, "", 0);
17999 }
18000 else if (len == Jim_Length(argv[2])) {
18001
18002 Jim_SetResultString(interp, str + idx, 1);
18003 }
18004 else {
18005 int c;
18006 int i = utf8_index(str, idx);
@@ -18150,11 +18223,11 @@
18150 {
18151 int exitCode = 0;
18152 int i;
18153 int sig = 0;
18154
18155
18156 jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
18157 static const int max_ignore_code = sizeof(ignore_mask) * 8;
18158
18159 Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
18160
@@ -18161,11 +18234,11 @@
18161 for (i = 1; i < argc - 1; i++) {
18162 const char *arg = Jim_String(argv[i]);
18163 jim_wide option;
18164 int ignore;
18165
18166
18167 if (strcmp(arg, "--") == 0) {
18168 i++;
18169 break;
18170 }
18171 if (*arg != '-') {
@@ -18212,28 +18285,28 @@
18212 sig++;
18213 }
18214
18215 interp->signal_level += sig;
18216 if (Jim_CheckSignal(interp)) {
18217
18218 exitCode = JIM_SIGNAL;
18219 }
18220 else {
18221 exitCode = Jim_EvalObj(interp, argv[0]);
18222
18223 interp->errorFlag = 0;
18224 }
18225 interp->signal_level -= sig;
18226
18227
18228 if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
18229
18230 return exitCode;
18231 }
18232
18233 if (sig && exitCode == JIM_SIGNAL) {
18234
18235 if (interp->signal_set_result) {
18236 interp->signal_set_result(interp, interp->sigmask);
18237 }
18238 else {
18239 Jim_SetResultInt(interp, interp->sigmask);
@@ -18272,10 +18345,125 @@
18272 }
18273 Jim_SetResultInt(interp, exitCode);
18274 return JIM_OK;
18275 }
18276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18277
18278
18279 static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18280 {
18281 if (argc != 3) {
@@ -18306,11 +18494,11 @@
18306 JimDictMatchCallbackType *callback, int type)
18307 {
18308 Jim_HashEntry *he;
18309 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
18310
18311
18312 Jim_HashTableIterator htiter;
18313 JimInitHashTableIterator(ht, &htiter);
18314 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18315 if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
18316 callback(interp, listObjPtr, he, type);
@@ -18356,11 +18544,11 @@
18356 return JIM_ERR;
18357 }
18358
18359 ht = (Jim_HashTable *)objPtr->internalRep.ptr;
18360
18361
18362 printf("%d entries in table, %d buckets\n", ht->used, ht->size);
18363
18364 for (i = 0; i < ht->size; i++) {
18365 Jim_HashEntry *he = ht->table[i];
18366
@@ -18480,16 +18668,16 @@
18480 return JIM_OK;
18481 }
18482 if (Jim_DictSize(interp, argv[2]) < 0) {
18483 return JIM_ERR;
18484 }
18485
18486 break;
18487
18488 case OPT_UPDATE:
18489 if (argc < 6 || argc % 2) {
18490
18491 argc = 2;
18492 }
18493 break;
18494
18495 case OPT_CREATE:
@@ -18506,11 +18694,11 @@
18506 Jim_WrongNumArgs(interp, 2, argv, "dictionary");
18507 return JIM_ERR;
18508 }
18509 return Jim_DictInfo(interp, argv[2]);
18510 }
18511
18512 return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
18513 }
18514
18515
18516 static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18576,11 +18764,11 @@
18576
18577 #ifdef jim_ext_namespace
18578 int nons = 0;
18579
18580 if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18581
18582 argc--;
18583 argv++;
18584 nons = 1;
18585 }
18586 #endif
@@ -18592,11 +18780,11 @@
18592 if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
18593 != JIM_OK) {
18594 return JIM_ERR;
18595 }
18596
18597
18598 switch (cmd) {
18599 case INFO_EXISTS:
18600 if (argc != 3) {
18601 Jim_WrongNumArgs(interp, 2, argv, "varName");
18602 return JIM_ERR;
@@ -18621,21 +18809,21 @@
18621 Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
18622 return JIM_OK;
18623 }
18624
18625 case INFO_CHANNELS:
18626 mode++;
18627 #ifndef jim_ext_aio
18628 Jim_SetResultString(interp, "aio not enabled", -1);
18629 return JIM_ERR;
18630 #endif
18631
18632 case INFO_PROCS:
18633 mode++;
18634
18635 case INFO_COMMANDS:
18636
18637 if (argc != 2 && argc != 3) {
18638 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18639 return JIM_ERR;
18640 }
18641 #ifdef jim_ext_namespace
@@ -18647,17 +18835,17 @@
18647 #endif
18648 Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
18649 break;
18650
18651 case INFO_VARS:
18652 mode++;
18653
18654 case INFO_LOCALS:
18655 mode++;
18656
18657 case INFO_GLOBALS:
18658
18659 if (argc != 2 && argc != 3) {
18660 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18661 return JIM_ERR;
18662 }
18663 #ifdef jim_ext_namespace
@@ -18763,12 +18951,13 @@
18763 case INFO_ARGS:
18764 Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
18765 break;
18766 case INFO_STATICS:
18767 if (cmdPtr->u.proc.staticVars) {
 
18768 Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
18769 NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES));
18770 }
18771 break;
18772 }
18773 break;
18774 }
@@ -18796,15 +18985,15 @@
18796 }
18797 }
18798 break;
18799
18800 case INFO_HOSTNAME:
18801
18802 return Jim_Eval(interp, "os.gethostname");
18803
18804 case INFO_NAMEOFEXECUTABLE:
18805
18806 return Jim_Eval(interp, "{info nameofexecutable}");
18807
18808 case INFO_RETURNCODES:
18809 if (argc == 2) {
18810 int i;
@@ -18881,11 +19070,11 @@
18881
18882 if (option == OPT_VAR) {
18883 result = Jim_GetVariable(interp, objPtr, 0) != NULL;
18884 }
18885 else {
18886
18887 Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
18888
18889 if (cmd) {
18890 switch (option) {
18891 case OPT_COMMAND:
@@ -18924,11 +19113,11 @@
18924 if (len == 0) {
18925 return JIM_OK;
18926 }
18927 strLen = Jim_Utf8Length(interp, argv[1]);
18928
18929
18930 if (argc == 2) {
18931 splitChars = " \n\t\r";
18932 splitLen = 4;
18933 }
18934 else {
@@ -18937,11 +19126,11 @@
18937 }
18938
18939 noMatchStart = str;
18940 resObjPtr = Jim_NewListObj(interp, NULL, 0);
18941
18942
18943 if (splitLen) {
18944 Jim_Obj *objPtr;
18945 while (strLen--) {
18946 const char *sc = splitChars;
18947 int scLen = splitLen;
@@ -18966,11 +19155,11 @@
18966 #define NUM_COMMON (128 - 9)
18967 while (strLen--) {
18968 int n = utf8_tounicode(str, &c);
18969 #ifdef JIM_OPTIMIZATION
18970 if (c >= 9 && c < 128) {
18971
18972 c -= 9;
18973 if (!commonObj) {
18974 commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
18975 memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
18976 }
@@ -19000,11 +19189,11 @@
19000
19001 if (argc != 2 && argc != 3) {
19002 Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
19003 return JIM_ERR;
19004 }
19005
19006 if (argc == 2) {
19007 joinStr = " ";
19008 joinStrLen = 1;
19009 }
19010 else {
@@ -19279,13 +19468,13 @@
19279 return -1;
19280 else if (step < 0 && end > start)
19281 return -1;
19282 len = end - start;
19283 if (len < 0)
19284 len = -len;
19285 if (step < 0)
19286 step = -step;
19287 len = 1 + ((len - 1) / step);
19288 if (len > INT_MAX)
19289 len = INT_MAX;
19290 return (int)((len < 0) ? -1 : len);
19291 }
@@ -19499,11 +19688,11 @@
19499
19500 *indexPtr = -1;
19501
19502 for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
19503 if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
19504
19505 *indexPtr = i;
19506 return JIM_OK;
19507 }
19508 if (flags & JIM_ENUM_ABBREV) {
19509 if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19517,11 +19706,11 @@
19517 match = i;
19518 }
19519 }
19520 }
19521
19522
19523 if (match >= 0) {
19524 *indexPtr = match;
19525 return JIM_OK;
19526 }
19527
@@ -19554,11 +19743,11 @@
19554 return objPtr->typePtr == &listObjType;
19555 }
19556
19557 void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
19558 {
19559
19560 int len = strlen(format);
19561 int extra = 0;
19562 int n = 0;
19563 const char *params[5];
19564 char *buf;
@@ -19619,11 +19808,11 @@
19619 #include <string.h>
19620
19621
19622 static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19623 {
19624
19625 return JIM_OK;
19626 }
19627
19628 static const jim_subcmd_type dummy_subcmd = {
19629 "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19698,43 +19887,43 @@
19698 return 0;
19699 }
19700
19701 cmd = argv[1];
19702
19703
19704 if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
19705 if (argc == 2) {
19706
19707 show_cmd_usage(interp, command_table, argc, argv);
19708 return &dummy_subcmd;
19709 }
19710 help = 1;
19711
19712
19713 cmd = argv[2];
19714 }
19715
19716
19717 if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
19718
19719 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
19720 add_commands(interp, command_table, " ");
19721 return &dummy_subcmd;
19722 }
19723
19724 cmdstr = Jim_GetString(cmd, &cmdlen);
19725
19726 for (ct = command_table; ct->cmd; ct++) {
19727 if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
19728
19729 break;
19730 }
19731 if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
19732 if (partial) {
19733
19734 if (help) {
19735
19736 show_cmd_usage(interp, command_table, argc, argv);
19737 return &dummy_subcmd;
19738 }
19739 bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
19740 return 0;
@@ -19742,44 +19931,44 @@
19742 partial = ct;
19743 }
19744 continue;
19745 }
19746
19747
19748 if (partial && !ct->cmd) {
19749 ct = partial;
19750 }
19751
19752 if (!ct->cmd) {
19753
19754 if (help) {
19755
19756 show_cmd_usage(interp, command_table, argc, argv);
19757 return &dummy_subcmd;
19758 }
19759 bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
19760 return 0;
19761 }
19762
19763 if (help) {
19764 Jim_SetResultString(interp, "Usage: ", -1);
19765
19766 add_cmd_usage(interp, ct, argv[0]);
19767 return &dummy_subcmd;
19768 }
19769
19770
19771 if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
19772 Jim_SetResultString(interp, "wrong # args: should be \"", -1);
19773
19774 add_cmd_usage(interp, ct, argv[0]);
19775 Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
19776
19777 return 0;
19778 }
19779
19780
19781 return ct;
19782 }
19783
19784 int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
19785 {
@@ -19830,11 +20019,11 @@
19830 *p++ = 0xe0 | ((uc & 0xf000) >> 12);
19831 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
19832 *p = 0x80 | (uc & 0x3f);
19833 return 3;
19834 }
19835
19836 else {
19837 *p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
19838 *p++ = 0x80 | ((uc & 0x3f000) >> 12);
19839 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
19840 *p = 0x80 | (uc & 0x3f);
@@ -20021,11 +20210,11 @@
20021 if (ch == 'h') {
20022 useShort = 1;
20023 format += step;
20024 step = utf8_tounicode(format, &ch);
20025 } else if (ch == 'l') {
20026
20027 format += step;
20028 step = utf8_tounicode(format, &ch);
20029 if (ch == 'l') {
20030 format += step;
20031 step = utf8_tounicode(format, &ch);
@@ -20048,11 +20237,11 @@
20048 goto errorMsg;
20049 case 's': {
20050 formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
20051 formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
20052 if (gotPrecision && (precision < formatted_chars)) {
20053
20054 formatted_chars = precision;
20055 formatted_bytes = utf8_index(formatted_buf, precision);
20056 }
20057 break;
20058 }
@@ -20060,11 +20249,11 @@
20060 jim_wide code;
20061
20062 if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
20063 goto error;
20064 }
20065
20066 formatted_bytes = utf8_getchars(spec, code);
20067 formatted_buf = spec;
20068 formatted_chars = 1;
20069 break;
20070 }
@@ -20078,11 +20267,11 @@
20078 goto error;
20079 }
20080 length = sizeof(w) * 8;
20081
20082
20083
20084 if (num_buffer_size < length + 1) {
20085 num_buffer_size = length + 1;
20086 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20087 }
20088
@@ -20106,29 +20295,29 @@
20106 case 'E':
20107 case 'f':
20108 case 'g':
20109 case 'G':
20110 doubleType = 1;
20111
20112 case 'd':
20113 case 'u':
20114 case 'o':
20115 case 'x':
20116 case 'X': {
20117 jim_wide w;
20118 double d;
20119 int length;
20120
20121
20122 if (width) {
20123 p += sprintf(p, "%ld", width);
20124 }
20125 if (gotPrecision) {
20126 p += sprintf(p, ".%ld", precision);
20127 }
20128
20129
20130 if (doubleType) {
20131 if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
20132 goto error;
20133 }
20134 length = MAX_FLOAT_WIDTH;
@@ -20155,19 +20344,19 @@
20155 }
20156
20157 *p++ = (char) ch;
20158 *p = '\0';
20159
20160
20161 if (width > length) {
20162 length = width;
20163 }
20164 if (gotPrecision) {
20165 length += precision;
20166 }
20167
20168
20169 if (num_buffer_size < length + 1) {
20170 num_buffer_size = length + 1;
20171 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20172 }
20173
@@ -20181,11 +20370,11 @@
20181 formatted_buf = num_buffer;
20182 break;
20183 }
20184
20185 default: {
20186
20187 spec[0] = ch;
20188 spec[1] = '\0';
20189 Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
20190 goto error;
20191 }
@@ -20233,37 +20422,37 @@
20233
20234 #define REG_MAX_PAREN 100
20235
20236
20237
20238 #define END 0
20239 #define BOL 1
20240 #define EOL 2
20241 #define ANY 3
20242 #define ANYOF 4
20243 #define ANYBUT 5
20244 #define BRANCH 6
20245 #define BACK 7
20246 #define EXACTLY 8
20247 #define NOTHING 9
20248 #define REP 10
20249 #define REPMIN 11
20250 #define REPX 12
20251 #define REPXMIN 13
20252 #define BOLX 14
20253 #define EOLX 15
20254 #define WORDA 16
20255 #define WORDZ 17
20256
20257 #define OPENNC 1000
20258 #define OPEN 1001
20259
20260
20261
20262
20263 #define CLOSENC 2000
20264 #define CLOSE 2001
20265 #define CLOSE_END (CLOSE+REG_MAX_PAREN)
20266
20267 #define REG_MAGIC 0xFADED00D
20268
20269
@@ -20276,18 +20465,18 @@
20276
20277 #define FAIL(R,M) { (R)->err = (M); return (M); }
20278 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
20279 #define META "^$.[()|?{+*"
20280
20281 #define HASWIDTH 1
20282 #define SIMPLE 2
20283 #define SPSTART 4
20284 #define WORST 0
20285
20286 #define MAX_REP_COUNT 1000000
20287
20288 static int reg(regex_t *preg, int paren, int *flagp );
20289 static int regpiece(regex_t *preg, int *flagp );
20290 static int regbranch(regex_t *preg, int *flagp );
20291 static int regatom(regex_t *preg, int *flagp );
20292 static int regnode(regex_t *preg, int op );
20293 static int regnext(regex_t *preg, int p );
@@ -20331,15 +20520,15 @@
20331 memset(preg, 0, sizeof(*preg));
20332
20333 if (exp == NULL)
20334 FAIL(preg, REG_ERR_NULL_ARGUMENT);
20335
20336
20337 preg->cflags = cflags;
20338 preg->regparse = exp;
20339
20340
20341 preg->proglen = (strlen(exp) + 1) * 5;
20342 preg->program = malloc(preg->proglen * sizeof(int));
20343 if (preg->program == NULL)
20344 FAIL(preg, REG_ERR_NOMEM);
20345
@@ -20346,24 +20535,24 @@
20346 regc(preg, REG_MAGIC);
20347 if (reg(preg, 0, &flags) == 0) {
20348 return preg->err;
20349 }
20350
20351
20352 if (preg->re_nsub >= REG_MAX_PAREN)
20353 FAIL(preg,REG_ERR_TOO_BIG);
20354
20355
20356 preg->regstart = 0;
20357 preg->reganch = 0;
20358 preg->regmust = 0;
20359 preg->regmlen = 0;
20360 scan = 1;
20361 if (OP(preg, regnext(preg, scan)) == END) {
20362 scan = OPERAND(scan);
20363
20364
20365 if (OP(preg, scan) == EXACTLY) {
20366 preg->regstart = preg->program[OPERAND(scan)];
20367 }
20368 else if (OP(preg, scan) == BOL)
20369 preg->reganch++;
@@ -20390,24 +20579,24 @@
20390 #endif
20391
20392 return 0;
20393 }
20394
20395 static int reg(regex_t *preg, int paren, int *flagp )
20396 {
20397 int ret;
20398 int br;
20399 int ender;
20400 int parno = 0;
20401 int flags;
20402
20403 *flagp = HASWIDTH;
20404
20405
20406 if (paren) {
20407 if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
20408
20409 preg->regparse += 2;
20410 parno = -1;
20411 }
20412 else {
20413 parno = ++preg->re_nsub;
@@ -20414,16 +20603,16 @@
20414 }
20415 ret = regnode(preg, OPEN+parno);
20416 } else
20417 ret = 0;
20418
20419
20420 br = regbranch(preg, &flags);
20421 if (br == 0)
20422 return 0;
20423 if (ret != 0)
20424 regtail(preg, ret, br);
20425 else
20426 ret = br;
20427 if (!(flags&HASWIDTH))
20428 *flagp &= ~HASWIDTH;
20429 *flagp |= flags&SPSTART;
@@ -20430,25 +20619,25 @@
20430 while (*preg->regparse == '|') {
20431 preg->regparse++;
20432 br = regbranch(preg, &flags);
20433 if (br == 0)
20434 return 0;
20435 regtail(preg, ret, br);
20436 if (!(flags&HASWIDTH))
20437 *flagp &= ~HASWIDTH;
20438 *flagp |= flags&SPSTART;
20439 }
20440
20441
20442 ender = regnode(preg, (paren) ? CLOSE+parno : END);
20443 regtail(preg, ret, ender);
20444
20445
20446 for (br = ret; br != 0; br = regnext(preg, br))
20447 regoptail(preg, br, ender);
20448
20449
20450 if (paren && *preg->regparse++ != ')') {
20451 preg->err = REG_ERR_UNMATCHED_PAREN;
20452 return 0;
20453 } else if (!paren && *preg->regparse != '\0') {
20454 if (*preg->regparse == ')') {
@@ -20468,11 +20657,11 @@
20468 int ret;
20469 int chain;
20470 int latest;
20471 int flags;
20472
20473 *flagp = WORST;
20474
20475 ret = regnode(preg, BRANCH);
20476 chain = 0;
20477 while (*preg->regparse != '\0' && *preg->regparse != ')' &&
20478 *preg->regparse != '|') {
@@ -20486,11 +20675,11 @@
20486 else {
20487 regtail(preg, chain, latest);
20488 }
20489 chain = latest;
20490 }
20491 if (chain == 0)
20492 (void) regnode(preg, NOTHING);
20493
20494 return(ret);
20495 }
20496
@@ -20516,11 +20705,11 @@
20516 if (!(flags&HASWIDTH) && op != '?') {
20517 preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
20518 return 0;
20519 }
20520
20521
20522 if (op == '{') {
20523 char *end;
20524
20525 min = strtoul(preg->regparse + 1, &end, 10);
20526 if (end == preg->regparse + 1) {
@@ -20588,11 +20777,11 @@
20588 static void reg_addrange(regex_t *preg, int lower, int upper)
20589 {
20590 if (lower > upper) {
20591 reg_addrange(preg, upper, lower);
20592 }
20593
20594 regc(preg, upper - lower + 1);
20595 regc(preg, lower);
20596 }
20597
20598 static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20656,17 +20845,17 @@
20656 case 'r': *ch = '\r'; break;
20657 case 't': *ch = '\t'; break;
20658 case 'v': *ch = '\v'; break;
20659 case 'u':
20660 if (*s == '{') {
20661
20662 n = parse_hex(s + 1, 6, ch);
20663 if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
20664 s += n + 2;
20665 }
20666 else {
20667
20668 *ch = 'u';
20669 }
20670 }
20671 else if ((n = parse_hex(s, 4, ch)) > 0) {
20672 s += n;
@@ -20697,15 +20886,15 @@
20697 int nocase = (preg->cflags & REG_ICASE);
20698
20699 int ch;
20700 int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
20701
20702 *flagp = WORST;
20703
20704 preg->regparse += n;
20705 switch (ch) {
20706
20707 case '^':
20708 ret = regnode(preg, BOL);
20709 break;
20710 case '$':
20711 ret = regnode(preg, EOL);
@@ -20715,24 +20904,24 @@
20715 *flagp |= HASWIDTH|SIMPLE;
20716 break;
20717 case '[': {
20718 const char *pattern = preg->regparse;
20719
20720 if (*pattern == '^') {
20721 ret = regnode(preg, ANYBUT);
20722 pattern++;
20723 } else
20724 ret = regnode(preg, ANYOF);
20725
20726
20727 if (*pattern == ']' || *pattern == '-') {
20728 reg_addrange(preg, *pattern, *pattern);
20729 pattern++;
20730 }
20731
20732 while (*pattern && *pattern != ']') {
20733
20734 int start;
20735 int end;
20736
20737 pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
20738 if (start == '\\') {
@@ -20741,11 +20930,11 @@
20741 preg->err = REG_ERR_NULL_CHAR;
20742 return 0;
20743 }
20744 }
20745 if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
20746
20747 pattern += utf8_tounicode(pattern, &end);
20748 pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
20749 if (end == '\\') {
20750 pattern += reg_decode_escape(pattern, &end);
20751 if (end == 0) {
@@ -20768,22 +20957,22 @@
20768 CC_NUM
20769 };
20770 int i;
20771
20772 for (i = 0; i < CC_NUM; i++) {
20773 n = strlen(character_class[i]);
20774 if (strncmp(pattern, character_class[i], n) == 0) {
20775
20776 pattern += n + 1;
20777 break;
20778 }
20779 }
20780 if (i != CC_NUM) {
20781 switch (i) {
20782 case CC_ALNUM:
20783 reg_addrange(preg, '0', '9');
20784
20785 case CC_ALPHA:
20786 if ((preg->cflags & REG_ICASE) == 0) {
20787 reg_addrange(preg, 'a', 'z');
20788 }
20789 reg_addrange(preg, 'A', 'Z');
@@ -20801,11 +20990,11 @@
20801 reg_addrange(preg, 'a', 'z');
20802 break;
20803 case CC_XDIGIT:
20804 reg_addrange(preg, 'a', 'f');
20805 reg_addrange(preg, 'A', 'F');
20806
20807 case CC_DIGIT:
20808 reg_addrange(preg, '0', '9');
20809 break;
20810 case CC_CNTRL:
20811 reg_addrange(preg, 0, 31);
@@ -20825,11 +21014,11 @@
20825 break;
20826 }
20827 continue;
20828 }
20829 }
20830
20831 reg_addrange(preg, start, start);
20832 }
20833 regc(preg, '\0');
20834
20835 if (*pattern) {
@@ -20848,11 +21037,11 @@
20848 break;
20849 case '\0':
20850 case '|':
20851 case ')':
20852 preg->err = REG_ERR_INTERNAL;
20853 return 0;
20854 case '?':
20855 case '+':
20856 case '*':
20857 case '{':
20858 preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
@@ -20901,34 +21090,34 @@
20901 ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT);
20902 reg_addrange_str(preg," \t\r\n\f\v");
20903 regc(preg, '\0');
20904 *flagp |= HASWIDTH|SIMPLE;
20905 break;
20906
20907 default:
20908
20909
20910 preg->regparse--;
20911 goto de_fault;
20912 }
20913 break;
20914 de_fault:
20915 default: {
20916 int added = 0;
20917
20918
20919 preg->regparse -= n;
20920
20921 ret = regnode(preg, EXACTLY);
20922
20923
20924
20925 while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
20926 n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
20927 if (ch == '\\' && preg->regparse[n]) {
20928 if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) {
20929
20930 break;
20931 }
20932 n += reg_decode_escape(preg->regparse + n, &ch);
20933 if (ch == 0) {
20934 preg->err = REG_ERR_NULL_CHAR;
@@ -20936,23 +21125,23 @@
20936 }
20937 }
20938
20939
20940 if (ISMULT(preg->regparse[n])) {
20941
20942 if (added) {
20943
20944 break;
20945 }
20946
20947 regc(preg, ch);
20948 added++;
20949 preg->regparse += n;
20950 break;
20951 }
20952
20953
20954 regc(preg, ch);
20955 added++;
20956 preg->regparse += n;
20957 }
20958 regc(preg, '\0');
@@ -20979,15 +21168,15 @@
20979
20980 static int regnode(regex_t *preg, int op)
20981 {
20982 reg_grow(preg, 2);
20983
20984
20985 preg->program[preg->p++] = op;
20986 preg->program[preg->p++] = 0;
20987
20988
20989 return preg->p - 2;
20990 }
20991
20992 static void regc(regex_t *preg, int b )
20993 {
@@ -20997,13 +21186,13 @@
20997
20998 static int reginsert(regex_t *preg, int op, int size, int opnd )
20999 {
21000 reg_grow(preg, size);
21001
21002
21003 memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
21004
21005 memset(preg->program + opnd, 0, sizeof(int) * size);
21006
21007 preg->program[opnd] = op;
21008
21009 preg->p += size;
@@ -21015,11 +21204,11 @@
21015 {
21016 int scan;
21017 int temp;
21018 int offset;
21019
21020
21021 scan = p;
21022 for (;;) {
21023 temp = regnext(preg, scan);
21024 if (temp == 0)
21025 break;
@@ -21035,11 +21224,11 @@
21035 }
21036
21037
21038 static void regoptail(regex_t *preg, int p, int val )
21039 {
21040
21041 if (p != 0 && OP(preg, p) == BRANCH) {
21042 regtail(preg, OPERAND(p), val);
21043 }
21044 }
21045
@@ -21051,16 +21240,16 @@
21051 int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
21052 {
21053 const char *s;
21054 int scan;
21055
21056
21057 if (preg == NULL || preg->program == NULL || string == NULL) {
21058 return REG_ERR_NULL_ARGUMENT;
21059 }
21060
21061
21062 if (*preg->program != REG_MAGIC) {
21063 return REG_ERR_CORRUPTED;
21064 }
21065
21066 #ifdef DEBUG
@@ -21069,51 +21258,51 @@
21069 #endif
21070
21071 preg->eflags = eflags;
21072 preg->pmatch = pmatch;
21073 preg->nmatch = nmatch;
21074 preg->start = string;
21075
21076
21077 for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
21078 int op = OP(preg, scan);
21079 if (op == END)
21080 break;
21081 if (op == REPX || op == REPXMIN)
21082 preg->program[scan + 4] = 0;
21083 }
21084
21085
21086 if (preg->regmust != 0) {
21087 s = string;
21088 while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
21089 if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
21090 break;
21091 }
21092 s++;
21093 }
21094 if (s == NULL)
21095 return REG_NOMATCH;
21096 }
21097
21098
21099 preg->regbol = string;
21100
21101
21102 if (preg->reganch) {
21103 if (eflags & REG_NOTBOL) {
21104
21105 goto nextline;
21106 }
21107 while (1) {
21108 if (regtry(preg, string)) {
21109 return REG_NOERROR;
21110 }
21111 if (*string) {
21112 nextline:
21113 if (preg->cflags & REG_NEWLINE) {
21114
21115 string = strchr(string, '\n');
21116 if (string) {
21117 preg->regbol = ++string;
21118 continue;
21119 }
@@ -21121,22 +21310,22 @@
21121 }
21122 return REG_NOMATCH;
21123 }
21124 }
21125
21126
21127 s = string;
21128 if (preg->regstart != '\0') {
21129
21130 while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
21131 if (regtry(preg, s))
21132 return REG_NOERROR;
21133 s++;
21134 }
21135 }
21136 else
21137
21138 while (1) {
21139 if (regtry(preg, s))
21140 return REG_NOERROR;
21141 if (*s == '\0') {
21142 break;
@@ -21145,15 +21334,15 @@
21145 int c;
21146 s += utf8_tounicode(s, &c);
21147 }
21148 }
21149
21150
21151 return REG_NOMATCH;
21152 }
21153
21154
21155 static int regtry( regex_t *preg, const char *string )
21156 {
21157 int i;
21158
21159 preg->reginput = string;
@@ -21190,11 +21379,11 @@
21190 }
21191
21192 static int reg_range_find(const int *range, int c)
21193 {
21194 while (*range) {
21195
21196 if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
21197 return 1;
21198 }
21199 range += 2;
21200 }
@@ -21202,11 +21391,11 @@
21202 }
21203
21204 static const char *str_find(const char *string, int c, int nocase)
21205 {
21206 if (nocase) {
21207
21208 c = utf8_upper(c);
21209 }
21210 while (*string) {
21211 int ch;
21212 int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21246,15 +21435,15 @@
21246 no = regrepeat(preg, scan + 5, max);
21247 if (no < min) {
21248 return 0;
21249 }
21250 if (matchmin) {
21251
21252 max = no;
21253 no = min;
21254 }
21255
21256 while (1) {
21257 if (matchmin) {
21258 if (no > max) {
21259 break;
21260 }
@@ -21264,22 +21453,22 @@
21264 break;
21265 }
21266 }
21267 preg->reginput = save + utf8_index(save, no);
21268 reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21269
21270 if (reg_iseol(preg, nextch) || c == nextch) {
21271 if (regmatch(preg, next)) {
21272 return(1);
21273 }
21274 }
21275 if (matchmin) {
21276
21277 no++;
21278 }
21279 else {
21280
21281 no--;
21282 }
21283 }
21284 return(0);
21285 }
@@ -21289,13 +21478,13 @@
21289 int *scanpt = preg->program + scan;
21290
21291 int max = scanpt[2];
21292 int min = scanpt[3];
21293
21294
21295 if (scanpt[4] < min) {
21296
21297 scanpt[4]++;
21298 if (regmatch(preg, scan + 5)) {
21299 return 1;
21300 }
21301 scanpt[4]--;
@@ -21304,39 +21493,39 @@
21304 if (scanpt[4] > max) {
21305 return 0;
21306 }
21307
21308 if (matchmin) {
21309
21310 if (regmatch(preg, regnext(preg, scan))) {
21311 return 1;
21312 }
21313
21314 scanpt[4]++;
21315 if (regmatch(preg, scan + 5)) {
21316 return 1;
21317 }
21318 scanpt[4]--;
21319 return 0;
21320 }
21321
21322 if (scanpt[4] < max) {
21323 scanpt[4]++;
21324 if (regmatch(preg, scan + 5)) {
21325 return 1;
21326 }
21327 scanpt[4]--;
21328 }
21329
21330 return regmatch(preg, regnext(preg, scan));
21331 }
21332
21333
21334 static int regmatch(regex_t *preg, int prog)
21335 {
21336 int scan;
21337 int next;
21338 const char *save;
21339
21340 scan = prog;
21341
21342 #ifdef DEBUG
@@ -21346,11 +21535,11 @@
21346 while (scan != 0) {
21347 int n;
21348 int c;
21349 #ifdef DEBUG
21350 if (regnarrate) {
21351 fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
21352 }
21353 #endif
21354 next = regnext(preg, scan);
21355 n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21356
@@ -21357,49 +21546,49 @@
21357 switch (OP(preg, scan)) {
21358 case BOLX:
21359 if ((preg->eflags & REG_NOTBOL)) {
21360 return(0);
21361 }
21362
21363 case BOL:
21364 if (preg->reginput != preg->regbol) {
21365 return(0);
21366 }
21367 break;
21368 case EOLX:
21369 if (c != 0) {
21370
21371 return 0;
21372 }
21373 break;
21374 case EOL:
21375 if (!reg_iseol(preg, c)) {
21376 return(0);
21377 }
21378 break;
21379 case WORDA:
21380
21381 if ((!isalnum(UCHAR(c))) && c != '_')
21382 return(0);
21383
21384 if (preg->reginput > preg->regbol &&
21385 (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
21386 return(0);
21387 break;
21388 case WORDZ:
21389
21390 if (preg->reginput > preg->regbol) {
21391
21392 if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
21393 c = preg->reginput[-1];
21394
21395 if (isalnum(UCHAR(c)) || c == '_') {
21396 break;
21397 }
21398 }
21399 }
21400
21401 return(0);
21402
21403 case ANY:
21404 if (reg_iseol(preg, c))
21405 return 0;
@@ -21435,12 +21624,12 @@
21435 case NOTHING:
21436 break;
21437 case BACK:
21438 break;
21439 case BRANCH:
21440 if (OP(preg, next) != BRANCH)
21441 next = OPERAND(scan);
21442 else {
21443 do {
21444 save = preg->reginput;
21445 if (regmatch(preg, OPERAND(scan))) {
21446 return(1);
@@ -21447,11 +21636,11 @@
21447 }
21448 preg->reginput = save;
21449 scan = regnext(preg, scan);
21450 } while (scan != 0 && OP(preg, scan) == BRANCH);
21451 return(0);
21452
21453 }
21454 break;
21455 case REP:
21456 case REPMIN:
21457 return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21459,11 +21648,11 @@
21459 case REPX:
21460 case REPXMIN:
21461 return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
21462
21463 case END:
21464 return 1;
21465
21466 case OPENNC:
21467 case CLOSENC:
21468 return regmatch(preg, next);
21469
@@ -21506,11 +21695,11 @@
21506
21507 scan = preg->reginput;
21508 opnd = OPERAND(p);
21509 switch (OP(preg, p)) {
21510 case ANY:
21511
21512 while (!reg_iseol(preg, *scan) && count < max) {
21513 count++;
21514 scan++;
21515 }
21516 break;
@@ -21542,13 +21731,13 @@
21542 }
21543 count++;
21544 scan += n;
21545 }
21546 break;
21547 default:
21548 preg->err = REG_ERR_INTERNAL;
21549 count = 0;
21550 break;
21551 }
21552 preg->reginput = scan;
21553
21554 return(count);
@@ -21569,11 +21758,11 @@
21569 return(p+offset);
21570 }
21571
21572 static int regopsize(regex_t *preg, int p )
21573 {
21574
21575 switch (OP(preg, p)) {
21576 case REP:
21577 case REPMIN:
21578 case REPX:
21579 case REPXMIN:
@@ -21690,26 +21879,26 @@
21690 {
21691 DIR *dir = 0;
21692
21693 if (name && name[0]) {
21694 size_t base_length = strlen(name);
21695 const char *all =
21696 strchr("/\\", name[base_length - 1]) ? "*" : "/*";
21697
21698 if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
21699 (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
21700 strcat(strcpy(dir->name, name), all);
21701
21702 if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
21703 dir->result.d_name = 0;
21704 else {
21705 Jim_Free(dir->name);
21706 Jim_Free(dir);
21707 dir = 0;
21708 }
21709 }
21710 else {
21711 Jim_Free(dir);
21712 dir = 0;
21713 errno = ENOMEM;
21714 }
21715 }
@@ -21727,11 +21916,11 @@
21727 if (dir->handle != -1)
21728 result = _findclose(dir->handle);
21729 Jim_Free(dir->name);
21730 Jim_Free(dir);
21731 }
21732 if (result == -1)
21733 errno = EBADF;
21734 return result;
21735 }
21736
21737 struct dirent *readdir(DIR * dir)
@@ -21810,11 +21999,11 @@
21810 }
21811
21812 void Jim_HistoryShow(void)
21813 {
21814 #ifdef USE_LINENOISE
21815
21816 int i;
21817 int len;
21818 char **history = linenoiseHistory(&len);
21819 for (i = 0; i < len; i++) {
21820 printf("%4d %s\n", i + 1, history[i]);
@@ -21876,11 +22065,11 @@
21876 Jim_DecrRefCount(interp, scriptObjPtr);
21877 retcode = JIM_OK;
21878 goto out;
21879 }
21880 if (Jim_Length(scriptObjPtr) != 0) {
21881
21882 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
21883 }
21884 Jim_AppendString(interp, scriptObjPtr, line, -1);
21885 free(line);
21886 if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
@@ -21888,11 +22077,11 @@
21888
21889 snprintf(prompt, sizeof(prompt), "%c> ", state);
21890 }
21891 #ifdef USE_LINENOISE
21892 if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
21893
21894 Jim_HistoryShow();
21895 Jim_DecrRefCount(interp, scriptObjPtr);
21896 continue;
21897 }
21898
@@ -21931,11 +22120,11 @@
21931 static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
21932 {
21933 int n;
21934 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
21935
21936
21937 for (n = 0; n < argc; n++) {
21938 Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
21939
21940 Jim_ListAppendElement(interp, listObj, obj);
21941 }
@@ -21971,47 +22160,47 @@
21971 {
21972 int retcode;
21973 Jim_Interp *interp;
21974 char *const orig_argv0 = argv[0];
21975
21976
21977 if (argc > 1 && strcmp(argv[1], "--version") == 0) {
21978 printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
21979 return 0;
21980 }
21981 else if (argc > 1 && strcmp(argv[1], "--help") == 0) {
21982 usage(argv[0]);
21983 return 0;
21984 }
21985
21986
21987 interp = Jim_CreateInterp();
21988 Jim_RegisterCoreCommands(interp);
21989
21990
21991 if (Jim_InitStaticExtensions(interp) != JIM_OK) {
21992 JimPrintErrorMessage(interp);
21993 }
21994
21995 Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0);
21996 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
21997 retcode = Jim_initjimshInit(interp);
21998
21999 if (argc == 1) {
22000
22001 if (retcode == JIM_ERR) {
22002 JimPrintErrorMessage(interp);
22003 }
22004 if (retcode != JIM_EXIT) {
22005 JimSetArgv(interp, 0, NULL);
22006 retcode = Jim_InteractivePrompt(interp);
22007 }
22008 }
22009 else {
22010
22011 if (argc > 2 && strcmp(argv[1], "-e") == 0) {
22012
22013 JimSetArgv(interp, argc - 3, argv + 3);
22014 retcode = Jim_Eval(interp, argv[2]);
22015 if (retcode != JIM_ERR) {
22016 printf("%s\n", Jim_String(Jim_GetResult(interp)));
22017 }
22018
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,7 +1,9 @@
1 /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */
2 #define _GNU_SOURCE
3 #define JIM_TCL_COMPAT
4 #define JIM_REFERENCES
5 #define JIM_ANSIC
6 #define JIM_REGEXP
7 #define HAVE_NO_AUTOCONF
8 #define _JIMAUTOCONF_H
9 #define TCL_LIBRARY "."
@@ -33,26 +35,20 @@
35 #define HAVE_UNISTD_H
36 #else
37 #define TCL_PLATFORM_OS "unknown"
38 #define TCL_PLATFORM_PLATFORM "unix"
39 #define TCL_PLATFORM_PATH_SEPARATOR ":"
 
 
 
 
 
 
40 #define HAVE_VFORK
41 #define HAVE_WAITPID
42 #define HAVE_ISATTY
43 #define HAVE_MKSTEMP
44 #define HAVE_LINK
45 #define HAVE_SYS_TIME_H
46 #define HAVE_DIRENT_H
47 #define HAVE_UNISTD_H
48 #endif
49 #define JIM_VERSION 76
50 #ifndef JIM_WIN32COMPAT_H
51 #define JIM_WIN32COMPAT_H
52
53
54
@@ -109,14 +105,14 @@
105 struct dirent {
106 char *d_name;
107 };
108
109 typedef struct DIR {
110 long handle;
111 struct _finddata_t info;
112 struct dirent result;
113 char *name;
114 } DIR;
115
116 DIR *opendir(const char *name);
117 int closedir(DIR *dir);
118 struct dirent *readdir(DIR *dir);
@@ -126,11 +122,11 @@
122 #include <stdlib.h>
123 #define strtod __strtod
124
125 #endif
126
127 #endif
128
129 #ifdef __cplusplus
130 }
131 #endif
132
@@ -179,13 +175,13 @@
175 extern "C" {
176 #endif
177
178 #include <time.h>
179 #include <limits.h>
180 #include <stdio.h>
181 #include <stdlib.h>
182 #include <stdarg.h>
183
184
185 #ifndef HAVE_NO_AUTOCONF
186 #endif
187
@@ -228,31 +224,31 @@
224 #define JIM_SIGNAL 5
225 #define JIM_EXIT 6
226
227 #define JIM_EVAL 7
228
229 #define JIM_MAX_CALLFRAME_DEPTH 1000
230 #define JIM_MAX_EVAL_DEPTH 2000
231
232
233 #define JIM_PRIV_FLAG_SHIFT 20
234
235 #define JIM_NONE 0
236 #define JIM_ERRMSG 1
237 #define JIM_ENUM_ABBREV 2
238 #define JIM_UNSHARED 4
239 #define JIM_MUSTEXIST 8
240
241
242 #define JIM_SUBST_NOVAR 1
243 #define JIM_SUBST_NOCMD 2
244 #define JIM_SUBST_NOESC 4
245 #define JIM_SUBST_FLAG 128
246
247
248 #define JIM_CASESENS 0
249 #define JIM_NOCASE 1
250
251
252 #define JIM_PATH_LEN 1024
253
254
@@ -343,79 +339,79 @@
339 #define Jim_GetHashTableSize(ht) ((ht)->size)
340 #define Jim_GetHashTableUsed(ht) ((ht)->used)
341
342
343 typedef struct Jim_Obj {
344 char *bytes;
345 const struct Jim_ObjType *typePtr;
346 int refCount;
347 int length;
348
349 union {
350
351 jim_wide wideValue;
352
353 int intValue;
354
355 double doubleValue;
356
357 void *ptr;
358
359 struct {
360 void *ptr1;
361 void *ptr2;
362 } twoPtrValue;
363
364 struct {
365 struct Jim_Var *varPtr;
366 unsigned long callFrameId;
367 int global;
368 } varValue;
369
370 struct {
371 struct Jim_Obj *nsObj;
372 struct Jim_Cmd *cmdPtr;
373 unsigned long procEpoch;
374 } cmdValue;
375
376 struct {
377 struct Jim_Obj **ele;
378 int len;
379 int maxLen;
380 } listValue;
381
382 struct {
383 int maxLength;
384 int charLength;
385 } strValue;
386
387 struct {
388 unsigned long id;
389 struct Jim_Reference *refPtr;
390 } refValue;
391
392 struct {
393 struct Jim_Obj *fileNameObj;
394 int lineNumber;
395 } sourceValue;
396
397 struct {
398 struct Jim_Obj *varNameObjPtr;
399 struct Jim_Obj *indexObjPtr;
400 } dictSubstValue;
401
402 struct {
403 void *compre;
404 unsigned flags;
405 } regexpValue;
406 struct {
407 int line;
408 int argc;
409 } scriptLineValue;
410 } internalRep;
411 struct Jim_Obj *prevObjPtr;
412 struct Jim_Obj *nextObjPtr;
413 } Jim_Obj;
414
415
416 #define Jim_IncrRefCount(objPtr) \
417 ++(objPtr)->refCount
@@ -446,40 +442,40 @@
442 typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
443 struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
444 typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
445
446 typedef struct Jim_ObjType {
447 const char *name;
448 Jim_FreeInternalRepProc *freeIntRepProc;
449 Jim_DupInternalRepProc *dupIntRepProc;
450 Jim_UpdateStringProc *updateStringProc;
451 int flags;
452 } Jim_ObjType;
453
454
455 #define JIM_TYPE_NONE 0
456 #define JIM_TYPE_REFERENCES 1
457
458
459
460 typedef struct Jim_CallFrame {
461 unsigned long id;
462 int level;
463 struct Jim_HashTable vars;
464 struct Jim_HashTable *staticVars;
465 struct Jim_CallFrame *parent;
466 Jim_Obj *const *argv;
467 int argc;
468 Jim_Obj *procArgsObjPtr;
469 Jim_Obj *procBodyObjPtr;
470 struct Jim_CallFrame *next;
471 Jim_Obj *nsObj;
472 Jim_Obj *fileNameObj;
473 int line;
474 Jim_Stack *localCommands;
475 struct Jim_Obj *tailcallObj;
476 struct Jim_Cmd *tailcallCmd;
477 } Jim_CallFrame;
478
479 typedef struct Jim_Var {
480 Jim_Obj *objPtr;
481 struct Jim_CallFrame *linkFramePtr;
@@ -491,35 +487,35 @@
487 typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
488
489
490
491 typedef struct Jim_Cmd {
492 int inUse;
493 int isproc;
494 struct Jim_Cmd *prevCmd;
495 union {
496 struct {
497
498 Jim_CmdProc *cmdProc;
499 Jim_DelCmdProc *delProc;
500 void *privData;
501 } native;
502 struct {
503
504 Jim_Obj *argListObjPtr;
505 Jim_Obj *bodyObjPtr;
506 Jim_HashTable *staticVars;
507 int argListLen;
508 int reqArity;
509 int optArity;
510 int argsPos;
511 int upcall;
512 struct Jim_ProcArg {
513 Jim_Obj *nameObjPtr;
514 Jim_Obj *defaultObjPtr;
515 } *arglist;
516 Jim_Obj *nsObj;
517 } proc;
518 } u;
519 } Jim_Cmd;
520
521
@@ -527,64 +523,64 @@
523 unsigned char sbox[256];
524 unsigned int i, j;
525 } Jim_PrngState;
526
527 typedef struct Jim_Interp {
528 Jim_Obj *result;
529 int errorLine;
530 Jim_Obj *errorFileNameObj;
531 int addStackTrace;
532 int maxCallFrameDepth;
533 int maxEvalDepth;
534 int evalDepth;
535 int returnCode;
536 int returnLevel;
537 int exitCode;
538 long id;
539 int signal_level;
540 jim_wide sigmask;
541 int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
542 Jim_CallFrame *framePtr;
543 Jim_CallFrame *topFramePtr;
544 struct Jim_HashTable commands;
545 unsigned long procEpoch; /* Incremented every time the result
546 of procedures names lookup caching
547 may no longer be valid. */
548 unsigned long callFrameEpoch; /* Incremented every time a new
549 callframe is created. This id is used for the
550 'ID' field contained in the Jim_CallFrame
551 structure. */
552 int local;
553 Jim_Obj *liveList;
554 Jim_Obj *freeList;
555 Jim_Obj *currentScriptObj;
556 Jim_Obj *nullScriptObj;
557 Jim_Obj *emptyObj;
558 Jim_Obj *trueObj;
559 Jim_Obj *falseObj;
560 unsigned long referenceNextId;
561 struct Jim_HashTable references;
562 unsigned long lastCollectId; /* reference max Id of the last GC
563 execution. It's set to -1 while the collection
564 is running as sentinel to avoid to recursive
565 calls via the [collect] command inside
566 finalizers. */
567 time_t lastCollectTime;
568 Jim_Obj *stackTrace;
569 Jim_Obj *errorProc;
570 Jim_Obj *unknown;
571 int unknown_called;
572 int errorFlag;
573 void *cmdPrivData; /* Used to pass the private data pointer to
574 a command. It is set to what the user specified
575 via Jim_CreateCommand(). */
576
577 struct Jim_CallFrame *freeFramesList;
578 struct Jim_HashTable assocData;
579 Jim_PrngState *prngState;
580 struct Jim_HashTable packages;
581 Jim_Stack *loadHandles;
582 } Jim_Interp;
583
584 #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
585 #define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
586 #define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -835,14 +831,10 @@
831 JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
832 Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
833 JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
834 Jim_Obj *exprObjPtr, int *boolPtr);
835
 
 
 
 
836
837 JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
838 jim_wide *widePtr);
839 JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
840 long *longPtr);
@@ -912,11 +904,11 @@
904
905 #ifdef __cplusplus
906 }
907 #endif
908
909 #endif
910
911 #ifndef JIM_SUBCMD_H
912 #define JIM_SUBCMD_H
913
914
@@ -923,24 +915,24 @@
915 #ifdef __cplusplus
916 extern "C" {
917 #endif
918
919
920 #define JIM_MODFLAG_HIDDEN 0x0001
921 #define JIM_MODFLAG_FULLARGV 0x0002
922
923
924
925 typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
926
927 typedef struct {
928 const char *cmd;
929 const char *args;
930 jim_subcmd_function *function;
931 short minargs;
932 short maxargs;
933 unsigned short flags;
934 } jim_subcmd_type;
935
936 const jim_subcmd_type *
937 Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv);
938
@@ -968,36 +960,36 @@
960 int rm_eo;
961 } regmatch_t;
962
963
964 typedef struct regexp {
965
966 int re_nsub;
967
968
969 int cflags;
970 int err;
971 int regstart;
972 int reganch;
973 int regmust;
974 int regmlen;
975 int *program;
976
977
978 const char *regparse;
979 int p;
980 int proglen;
981
982
983 int eflags;
984 const char *start;
985 const char *reginput;
986 const char *regbol;
987
988
989 regmatch_t *pmatch;
990 int nmatch;
991 } regexp;
992
993 typedef regexp regex_t;
994
995 #define REG_EXTENDED 0
@@ -1005,13 +997,13 @@
997 #define REG_ICASE 2
998
999 #define REG_NOTBOL 16
1000
1001 enum {
1002 REG_NOERROR,
1003 REG_NOMATCH,
1004 REG_BADPAT,
1005 REG_ERR_NULL_ARGUMENT,
1006 REG_ERR_UNKNOWN,
1007 REG_ERR_TOO_BIG,
1008 REG_ERR_NOMEM,
1009 REG_ERR_TOO_MANY_PAREN,
@@ -1788,11 +1780,10 @@
1780 "}\n"
1781 );
1782 }
1783
1784
 
1785 #include <stdio.h>
1786 #include <string.h>
1787 #include <errno.h>
1788 #include <fcntl.h>
1789 #ifdef HAVE_UNISTD_H
@@ -1817,12 +1808,12 @@
1808 #include <openssl/ssl.h>
1809 #include <openssl/err.h>
1810 #endif
1811
1812
1813 #define AIO_CMD_LEN 32
1814 #define AIO_BUF_LEN 256
1815
1816 #ifndef HAVE_FTELLO
1817 #define ftello ftell
1818 #endif
1819 #ifndef HAVE_FSEEKO
@@ -1857,11 +1848,11 @@
1848 typedef struct AioFile
1849 {
1850 FILE *fp;
1851 Jim_Obj *filename;
1852 int type;
1853 int openFlags;
1854 int fd;
1855 Jim_Obj *rEvent;
1856 Jim_Obj *wEvent;
1857 Jim_Obj *eEvent;
1858 int addr_family;
@@ -1888,11 +1879,11 @@
1879 {
1880 if (!ferror(af->fp)) {
1881 return JIM_OK;
1882 }
1883 clearerr(af->fp);
1884
1885 if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
1886 return JIM_OK;
1887 }
1888 #ifdef ECONNRESET
1889 if (errno == ECONNRESET) {
@@ -1954,12 +1945,12 @@
1945 JIM_NOTUSED(interp);
1946
1947 Jim_DecrRefCount(interp, af->filename);
1948
1949 #ifdef jim_ext_eventloop
1950
1951 Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
1952 #endif
1953
1954 #if defined(JIM_SSL)
1955 if (af->ssl != NULL) {
1956 SSL_free(af->ssl);
@@ -1977,11 +1968,11 @@
1968 {
1969 AioFile *af = Jim_CmdPrivData(interp);
1970 char buf[AIO_BUF_LEN];
1971 Jim_Obj *objPtr;
1972 int nonewline = 0;
1973 jim_wide neededLen = -1;
1974
1975 if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
1976 nonewline = 1;
1977 argv++;
1978 argc--;
@@ -2016,11 +2007,11 @@
2007 }
2008 }
2009 if (retval != readlen)
2010 break;
2011 }
2012
2013 if (JimCheckStreamError(interp, af)) {
2014 Jim_FreeNewObj(interp, objPtr);
2015 return JIM_ERR;
2016 }
2017 if (nonewline) {
@@ -2038,11 +2029,11 @@
2029
2030 AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command)
2031 {
2032 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
2033
2034
2035 if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
2036 return (AioFile *) cmdPtr->u.native.privData;
2037 }
2038 Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
2039 return NULL;
@@ -2119,21 +2110,21 @@
2110 }
2111 else {
2112 len = strlen(buf);
2113
2114 if (len && (buf[len - 1] == '\n')) {
2115
2116 len--;
2117 }
2118
2119 Jim_AppendString(interp, objPtr, buf, len);
2120 break;
2121 }
2122 }
2123
2124 if (JimCheckStreamError(interp, af)) {
2125
2126 Jim_FreeNewObj(interp, objPtr);
2127 return JIM_ERR;
2128 }
2129
2130 if (argc) {
@@ -2143,11 +2134,11 @@
2134 }
2135
2136 len = Jim_Length(objPtr);
2137
2138 if (len == 0 && feof(af->fp)) {
2139
2140 len = -1;
2141 }
2142 Jim_SetResultInt(interp, len);
2143 }
2144 else {
@@ -2373,33 +2364,33 @@
2364
2365 static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
2366 int argc, Jim_Obj * const *argv)
2367 {
2368 if (argc == 0) {
2369
2370 if (*scriptHandlerObj) {
2371 Jim_SetResult(interp, *scriptHandlerObj);
2372 }
2373 return JIM_OK;
2374 }
2375
2376 if (*scriptHandlerObj) {
2377
2378 Jim_DeleteFileHandler(interp, af->fp, mask);
2379 }
2380
2381
2382 if (Jim_Length(argv[0]) == 0) {
2383
2384 return JIM_OK;
2385 }
2386
2387
2388 Jim_IncrRefCount(argv[0]);
2389 *scriptHandlerObj = argv[0];
2390
2391 Jim_CreateFileHandler(interp, af->fp, mask,
2392 JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
2393
2394 return JIM_OK;
2395 }
2396
@@ -2424,136 +2415,135 @@
2415 return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
2416 }
2417 #endif
2418
2419
 
2420 static const jim_subcmd_type aio_command_table[] = {
2421 { "read",
2422 "?-nonewline? ?len?",
2423 aio_cmd_read,
2424 0,
2425 2,
2426
2427 },
2428 { "copyto",
2429 "handle ?size?",
2430 aio_cmd_copy,
2431 1,
2432 2,
2433
2434 },
2435 { "gets",
2436 "?var?",
2437 aio_cmd_gets,
2438 0,
2439 1,
2440
2441 },
2442 { "puts",
2443 "?-nonewline? str",
2444 aio_cmd_puts,
2445 1,
2446 2,
2447
2448 },
2449 { "isatty",
2450 NULL,
2451 aio_cmd_isatty,
2452 0,
2453 0,
2454
2455 },
2456 { "flush",
2457 NULL,
2458 aio_cmd_flush,
2459 0,
2460 0,
2461
2462 },
2463 { "eof",
2464 NULL,
2465 aio_cmd_eof,
2466 0,
2467 0,
2468
2469 },
2470 { "close",
2471 "?r(ead)|w(rite)?",
2472 aio_cmd_close,
2473 0,
2474 1,
2475 JIM_MODFLAG_FULLARGV,
2476
2477 },
2478 { "seek",
2479 "offset ?start|current|end",
2480 aio_cmd_seek,
2481 1,
2482 2,
2483
2484 },
2485 { "tell",
2486 NULL,
2487 aio_cmd_tell,
2488 0,
2489 0,
2490
2491 },
2492 { "filename",
2493 NULL,
2494 aio_cmd_filename,
2495 0,
2496 0,
2497
2498 },
2499 #ifdef O_NDELAY
2500 { "ndelay",
2501 "?0|1?",
2502 aio_cmd_ndelay,
2503 0,
2504 1,
2505
2506 },
2507 #endif
2508 #ifdef HAVE_FSYNC
2509 { "sync",
2510 NULL,
2511 aio_cmd_sync,
2512 0,
2513 0,
2514
2515 },
2516 #endif
2517 { "buffering",
2518 "none|line|full",
2519 aio_cmd_buffering,
2520 1,
2521 1,
2522
2523 },
2524 #ifdef jim_ext_eventloop
2525 { "readable",
2526 "?readable-script?",
2527 aio_cmd_readable,
2528 0,
2529 1,
2530
2531 },
2532 { "writable",
2533 "?writable-script?",
2534 aio_cmd_writable,
2535 0,
2536 1,
2537
2538 },
2539 { "onexception",
2540 "?exception-script?",
2541 aio_cmd_onexception,
2542 0,
2543 1,
2544
2545 },
2546 #endif
2547 { NULL }
2548 };
2549
@@ -2576,11 +2566,11 @@
2566
2567 #ifdef jim_ext_tclcompat
2568 {
2569 const char *filename = Jim_String(argv[1]);
2570
2571
2572 if (*filename == '|') {
2573 Jim_Obj *evalObj[3];
2574
2575 evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
2576 evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2633,11 +2623,11 @@
2623 Jim_DecrRefCount(interp, filename);
2624 return NULL;
2625 }
2626 }
2627
2628
2629 af = Jim_Alloc(sizeof(*af));
2630 memset(af, 0, sizeof(*af));
2631 af->fp = fh;
2632 af->fd = fileno(fh);
2633 af->filename = filename;
@@ -2671,11 +2661,11 @@
2661 Jim_SetResult(interp, objPtr);
2662 return JIM_OK;
2663 }
2664 }
2665
2666
2667 close(p[0]);
2668 close(p[1]);
2669 JimAioSetError(interp, NULL);
2670 return JIM_ERR;
2671 }
@@ -2705,15 +2695,15 @@
2695 }
2696
2697 #if defined(S_IRWXG) && defined(S_IRWXO)
2698 mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
2699 #else
2700
2701 mask = umask(S_IXUSR);
2702 #endif
2703
2704
2705 fd = mkstemp(filenameObj->bytes);
2706 umask(mask);
2707 if (fd < 0) {
2708 JimAioSetError(interp, filenameObj);
2709 Jim_FreeNewObj(interp, filenameObj);
@@ -2741,11 +2731,11 @@
2731 Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
2732 #ifndef JIM_ANSIC
2733 Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
2734 #endif
2735
2736
2737 JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
2738 JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
2739 JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
2740
2741 return JIM_OK;
@@ -2841,20 +2831,20 @@
2831 {
2832 regex_t *compre;
2833 const char *pattern;
2834 int ret;
2835
2836
2837 if (objPtr->typePtr == &regexpObjType &&
2838 objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
2839
2840 return objPtr->internalRep.regexpValue.compre;
2841 }
2842
2843
2844
2845
 
2846 pattern = Jim_String(objPtr);
2847 compre = Jim_Alloc(sizeof(regex_t));
2848
2849 if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
2850 char buf[100];
@@ -3011,11 +3001,11 @@
3001 }
3002
3003 num_matches++;
3004
3005 if (opt_all && !opt_inline) {
3006
3007 goto try_next_match;
3008 }
3009
3010
3011 j = 0;
@@ -3051,11 +3041,11 @@
3041
3042 if (opt_inline) {
3043 Jim_ListAppendElement(interp, resultListObj, resultObj);
3044 }
3045 else {
3046
3047 result = Jim_SetVariable(interp, argv[i], resultObj);
3048
3049 if (result != JIM_OK) {
3050 Jim_FreeObj(interp, resultObj);
3051 break;
@@ -3178,11 +3168,11 @@
3168
3169 source_str = Jim_GetString(argv[i + 1], &source_len);
3170 replace_str = Jim_GetString(argv[i + 2], &replace_len);
3171 varname = argv[i + 3];
3172
3173
3174 resultObj = Jim_NewStringObj(interp, "", 0);
3175
3176 if (offset) {
3177 if (offset < 0) {
3178 offset += source_len + 1;
@@ -3193,11 +3183,11 @@
3183 else if (offset < 0) {
3184 offset = 0;
3185 }
3186 }
3187
3188
3189 Jim_AppendString(interp, resultObj, source_str, offset);
3190
3191
3192 n = source_len - offset;
3193 p = source_str + offset;
@@ -3252,23 +3242,23 @@
3242 }
3243
3244 p += pmatch[0].rm_eo;
3245 n -= pmatch[0].rm_eo;
3246
3247
3248 if (!opt_all || n == 0) {
3249 break;
3250 }
3251
3252
3253 if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
3254 break;
3255 }
3256
3257
3258 if (pattern[0] == '\0' && n) {
3259
3260 Jim_AppendString(interp, resultObj, p, 1);
3261 p++;
3262 n--;
3263 }
3264
@@ -3275,11 +3265,11 @@
3265 regexec_flags |= REG_NOTBOL;
3266 } while (n);
3267
3268 Jim_AppendString(interp, resultObj, p, -1);
3269
3270
3271 if (argc - i == 4) {
3272 result = Jim_SetVariable(interp, varname, resultObj);
3273
3274 if (result == JIM_OK) {
3275 Jim_SetResultInt(interp, num_matches);
@@ -3381,11 +3371,11 @@
3371 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
3372 }
3373
3374 static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
3375 {
3376
3377 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
3378
3379 AppendStatElement(interp, listObj, "dev", sb->st_dev);
3380 AppendStatElement(interp, listObj, "ino", sb->st_ino);
3381 AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3397,25 +3387,25 @@
3387 AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
3388 AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
3389 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
3390 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
3391
3392
3393 if (varName) {
3394 Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
3395 if (objPtr) {
3396 if (Jim_DictSize(interp, objPtr) < 0) {
3397
3398 Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
3399 Jim_FreeNewObj(interp, listObj);
3400 return JIM_ERR;
3401 }
3402
3403 if (Jim_IsShared(objPtr))
3404 objPtr = Jim_DuplicateObj(interp, objPtr);
3405
3406
3407 Jim_ListAppendList(interp, objPtr, listObj);
3408 Jim_DictSize(interp, objPtr);
3409 Jim_InvalidateStringRep(objPtr);
3410
3411 Jim_FreeNewObj(interp, listObj);
@@ -3422,11 +3412,11 @@
3412 listObj = objPtr;
3413 }
3414 Jim_SetVariable(interp, varName, listObj);
3415 }
3416
3417
3418 Jim_SetResult(interp, listObj);
3419
3420 return JIM_OK;
3421 }
3422
@@ -3442,11 +3432,11 @@
3432 }
3433 else if (p == path) {
3434 Jim_SetResultString(interp, "/", -1);
3435 }
3436 else if (ISWINDOWS && p[-1] == ':') {
3437
3438 Jim_SetResultString(interp, path, p - path + 1);
3439 }
3440 else {
3441 Jim_SetResultString(interp, path, p - path);
3442 }
@@ -3522,35 +3512,35 @@
3512 char *newname = Jim_Alloc(MAXPATHLEN + 1);
3513 char *last = newname;
3514
3515 *newname = 0;
3516
3517
3518 for (i = 0; i < argc; i++) {
3519 int len;
3520 const char *part = Jim_GetString(argv[i], &len);
3521
3522 if (*part == '/') {
3523
3524 last = newname;
3525 }
3526 else if (ISWINDOWS && strchr(part, ':')) {
3527
3528 last = newname;
3529 }
3530 else if (part[0] == '.') {
3531 if (part[1] == '/') {
3532 part += 2;
3533 len -= 2;
3534 }
3535 else if (part[1] == 0 && last != newname) {
3536
3537 continue;
3538 }
3539 }
3540
3541
3542 if (last != newname && last[-1] != '/') {
3543 *last++ = '/';
3544 }
3545
3546 if (len) {
@@ -3561,22 +3551,22 @@
3551 }
3552 memcpy(last, part, len);
3553 last += len;
3554 }
3555
3556
3557 if (last > newname + 1 && last[-1] == '/') {
3558
3559 if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
3560 *--last = 0;
3561 }
3562 }
3563 }
3564
3565 *last = 0;
3566
3567
3568
3569 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
3570
3571 return JIM_OK;
3572 }
@@ -3601,11 +3591,11 @@
3591 static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3592 {
3593 #ifdef X_OK
3594 return file_access(interp, argv[0], X_OK);
3595 #else
3596
3597 Jim_SetResultBool(interp, 1);
3598 return JIM_OK;
3599 #endif
3600 }
3601
@@ -3626,11 +3616,11 @@
3616 while (argc--) {
3617 const char *path = Jim_String(argv[0]);
3618
3619 if (unlink(path) == -1 && errno != ENOENT) {
3620 if (rmdir(path) == -1) {
3621
3622 if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
3623 Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
3624 strerror(errno));
3625 return JIM_ERR;
3626 }
@@ -3649,15 +3639,15 @@
3639
3640 static int mkdir_all(char *path)
3641 {
3642 int ok = 1;
3643
3644
3645 goto first;
3646
3647 while (ok--) {
3648
3649 {
3650 char *slash = strrchr(path, '/');
3651
3652 if (slash && slash != path) {
3653 *slash = 0;
@@ -3670,24 +3660,24 @@
3660 first:
3661 if (MKDIR_DEFAULT(path) == 0) {
3662 return 0;
3663 }
3664 if (errno == ENOENT) {
3665
3666 continue;
3667 }
3668
3669 if (errno == EEXIST) {
3670 struct stat sb;
3671
3672 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
3673 return 0;
3674 }
3675
3676 errno = EEXIST;
3677 }
3678
3679 break;
3680 }
3681 return -1;
3682 }
3683
@@ -3972,192 +3962,192 @@
3962 { "atime",
3963 "name",
3964 file_cmd_atime,
3965 1,
3966 1,
3967
3968 },
3969 { "mtime",
3970 "name ?time?",
3971 file_cmd_mtime,
3972 1,
3973 2,
3974
3975 },
3976 { "copy",
3977 "?-force? source dest",
3978 file_cmd_copy,
3979 2,
3980 3,
3981
3982 },
3983 { "dirname",
3984 "name",
3985 file_cmd_dirname,
3986 1,
3987 1,
3988
3989 },
3990 { "rootname",
3991 "name",
3992 file_cmd_rootname,
3993 1,
3994 1,
3995
3996 },
3997 { "extension",
3998 "name",
3999 file_cmd_extension,
4000 1,
4001 1,
4002
4003 },
4004 { "tail",
4005 "name",
4006 file_cmd_tail,
4007 1,
4008 1,
4009
4010 },
4011 { "normalize",
4012 "name",
4013 file_cmd_normalize,
4014 1,
4015 1,
4016
4017 },
4018 { "join",
4019 "name ?name ...?",
4020 file_cmd_join,
4021 1,
4022 -1,
4023
4024 },
4025 { "readable",
4026 "name",
4027 file_cmd_readable,
4028 1,
4029 1,
4030
4031 },
4032 { "writable",
4033 "name",
4034 file_cmd_writable,
4035 1,
4036 1,
4037
4038 },
4039 { "executable",
4040 "name",
4041 file_cmd_executable,
4042 1,
4043 1,
4044
4045 },
4046 { "exists",
4047 "name",
4048 file_cmd_exists,
4049 1,
4050 1,
4051
4052 },
4053 { "delete",
4054 "?-force|--? name ...",
4055 file_cmd_delete,
4056 1,
4057 -1,
4058
4059 },
4060 { "mkdir",
4061 "dir ...",
4062 file_cmd_mkdir,
4063 1,
4064 -1,
4065
4066 },
4067 { "tempfile",
4068 "?template?",
4069 file_cmd_tempfile,
4070 0,
4071 1,
4072
4073 },
4074 { "rename",
4075 "?-force? source dest",
4076 file_cmd_rename,
4077 2,
4078 3,
4079
4080 },
4081 #if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
4082 { "link",
4083 "?-symbolic|-hard? newname target",
4084 file_cmd_link,
4085 2,
4086 3,
4087
4088 },
4089 #endif
4090 #if defined(HAVE_READLINK)
4091 { "readlink",
4092 "name",
4093 file_cmd_readlink,
4094 1,
4095 1,
4096
4097 },
4098 #endif
4099 { "size",
4100 "name",
4101 file_cmd_size,
4102 1,
4103 1,
4104
4105 },
4106 { "stat",
4107 "name ?var?",
4108 file_cmd_stat,
4109 1,
4110 2,
4111
4112 },
4113 { "lstat",
4114 "name ?var?",
4115 file_cmd_lstat,
4116 1,
4117 2,
4118
4119 },
4120 { "type",
4121 "name",
4122 file_cmd_type,
4123 1,
4124 1,
4125
4126 },
4127 #ifdef HAVE_GETEUID
4128 { "owned",
4129 "name",
4130 file_cmd_owned,
4131 1,
4132 1,
4133
4134 },
4135 #endif
4136 { "isdirectory",
4137 "name",
4138 file_cmd_isdirectory,
4139 1,
4140 1,
4141
4142 },
4143 { "isfile",
4144 "name",
4145 file_cmd_isfile,
4146 1,
4147 1,
4148
4149 },
4150 {
4151 NULL
4152 }
4153 };
@@ -4189,11 +4179,11 @@
4179 Jim_SetResultString(interp, "Failed to get pwd", -1);
4180 Jim_Free(cwd);
4181 return JIM_ERR;
4182 }
4183 else if (ISWINDOWS) {
4184
4185 char *p = cwd;
4186 while ((p = strchr(p, '\\')) != NULL) {
4187 *p++ = '/';
4188 }
4189 }
@@ -4213,11 +4203,10 @@
4203 Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
4204 Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
4205 return JIM_OK;
4206 }
4207
 
4208 #include <string.h>
4209 #include <ctype.h>
4210
4211
4212 #if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4225,20 +4214,20 @@
4214 {
4215 Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
4216 int i, j;
4217 int rc;
4218
4219
4220 for (i = 1; i < argc; i++) {
4221 int len;
4222 const char *arg = Jim_GetString(argv[i], &len);
4223
4224 if (i > 1) {
4225 Jim_AppendString(interp, cmdlineObj, " ", 1);
4226 }
4227 if (strpbrk(arg, "\\\" ") == NULL) {
4228
4229 Jim_AppendString(interp, cmdlineObj, arg, len);
4230 continue;
4231 }
4232
4233 Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4279,11 +4268,11 @@
4268
4269 #include <errno.h>
4270 #include <signal.h>
4271
4272 #if defined(__MINGW32__)
4273
4274 #ifndef STRICT
4275 #define STRICT
4276 #endif
4277 #define WIN32_LEAN_AND_MEAN
4278 #include <windows.h>
@@ -4405,14 +4394,14 @@
4394 if (!objPtr) {
4395 return Jim_GetEnviron();
4396 }
4397
4398
4399
4400 num = Jim_ListLength(interp, objPtr);
4401 if (num % 2) {
4402
4403 num--;
4404 }
4405 size = Jim_Length(objPtr) + 2;
4406
4407 envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4504,19 +4493,19 @@
4493 }
4494
4495
4496 struct WaitInfo
4497 {
4498 pidtype pid;
4499 int status;
4500 int flags;
4501 };
4502
4503 struct WaitInfoTable {
4504 struct WaitInfo *info;
4505 int size;
4506 int used;
4507 };
4508
4509
4510 #define WI_DETACHED 2
4511
@@ -4539,12 +4528,12 @@
4528 return table;
4529 }
4530
4531 static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
4532 {
4533 fdtype outputId;
4534 fdtype errorId;
4535 pidtype *pidPtr;
4536 int numPids, result;
4537 int child_siginfo = 1;
4538 Jim_Obj *childErrObj;
4539 Jim_Obj *errStrObj;
@@ -4556,11 +4545,11 @@
4545 argc--;
4546 numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
4547 if (numPids < 0) {
4548 return JIM_ERR;
4549 }
4550
4551 listObj = Jim_NewListObj(interp, NULL, 0);
4552 for (i = 0; i < numPids; i++) {
4553 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
4554 }
4555 Jim_SetResult(interp, listObj);
@@ -4578,19 +4567,19 @@
4567
4568 result = JIM_OK;
4569
4570 errStrObj = Jim_NewStringObj(interp, "", 0);
4571
4572
4573 if (outputId != JIM_BAD_FD) {
4574 if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
4575 result = JIM_ERR;
4576 Jim_SetResultErrno(interp, "error reading from output pipe");
4577 }
4578 }
4579
4580
4581 childErrObj = Jim_NewStringObj(interp, "", 0);
4582 Jim_IncrRefCount(childErrObj);
4583
4584 if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
4585 result = JIM_ERR;
@@ -4603,25 +4592,25 @@
4592 if (ret < 0) {
4593 Jim_SetResultErrno(interp, "error reading from error pipe");
4594 result = JIM_ERR;
4595 }
4596 else if (ret > 0) {
4597
4598 child_siginfo = 0;
4599 }
4600 }
4601
4602 if (child_siginfo) {
4603
4604 Jim_AppendObj(interp, errStrObj, childErrObj);
4605 }
4606 Jim_DecrRefCount(interp, childErrObj);
4607
4608
4609 Jim_RemoveTrailingNewline(errStrObj);
4610
4611
4612 Jim_SetResult(interp, errStrObj);
4613
4614 return result;
4615 }
4616
@@ -4640,11 +4629,11 @@
4629 for (count = table->used; count > 0; waitPtr++, count--) {
4630 if (waitPtr->flags & WI_DETACHED) {
4631 int status;
4632 pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
4633 if (pid == waitPtr->pid) {
4634
4635 table->used--;
4636 continue;
4637 }
4638 }
4639 if (waitPtr != &table->info[dest]) {
@@ -4656,36 +4645,36 @@
4645
4646 static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
4647 {
4648 int i;
4649
4650
4651 for (i = 0; i < table->used; i++) {
4652 if (pid == table->info[i].pid) {
4653
4654 JimWaitPid(pid, statusPtr, 0);
4655
4656
4657 if (i != table->used - 1) {
4658 table->info[i] = table->info[table->used - 1];
4659 }
4660 table->used--;
4661 return pid;
4662 }
4663 }
4664
4665
4666 return JIM_BAD_PID;
4667 }
4668
4669 static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
4670 {
4671 int j;
4672 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4673
4674 for (j = 0; j < numPids; j++) {
4675
4676 int i;
4677 for (i = 0; i < table->used; i++) {
4678 if (pidPtr[j] == table->info[i].pid) {
4679 table->info[i].flags |= WI_DETACHED;
4680 break;
@@ -4718,16 +4707,16 @@
4707 int cmdCount; /* Count of number of distinct commands
4708 * found in argc/argv. */
4709 const char *input = NULL; /* Describes input for pipeline, depending
4710 * on "inputFile". NULL means take input
4711 * from stdin/pipe. */
4712 int input_len = 0;
4713
4714 #define FILE_NAME 0
4715 #define FILE_APPEND 1
4716 #define FILE_HANDLE 2
4717 #define FILE_TEXT 3
4718
4719 int inputFile = FILE_NAME; /* 1 means input is name of input file.
4720 * 2 means input is filehandle name.
4721 * 0 means input holds actual
4722 * text to be input to command. */
@@ -4748,20 +4737,20 @@
4737 * or NULL if stderr goes to stderr/pipe. */
4738 fdtype inputId = JIM_BAD_FD;
4739 fdtype outputId = JIM_BAD_FD;
4740 fdtype errorId = JIM_BAD_FD;
4741 fdtype lastOutputId = JIM_BAD_FD;
4742 fdtype pipeIds[2];
4743 int firstArg, lastArg; /* Indexes of first and last arguments in
4744 * current command. */
4745 int lastBar;
4746 int i;
4747 pidtype pid;
4748 char **save_environ;
4749 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4750
4751
4752 char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
4753 int arg_count = 0;
4754
4755 JimReapDetachedPids(table);
4756
@@ -4807,11 +4796,11 @@
4796 if (*output == '>') {
4797 outputFile = FILE_APPEND;
4798 output++;
4799 }
4800 if (*output == '&') {
4801
4802 output++;
4803 dup_error = 1;
4804 }
4805 if (*output == '@') {
4806 outputFile = FILE_HANDLE;
@@ -4848,11 +4837,11 @@
4837 goto badargs;
4838 }
4839 lastBar = i;
4840 cmdCount++;
4841 }
4842
4843 arg_array[arg_count++] = (char *)arg;
4844 continue;
4845 }
4846
4847 if (i >= argc) {
@@ -4866,11 +4855,11 @@
4855 badargs:
4856 Jim_Free(arg_array);
4857 return -1;
4858 }
4859
4860
4861 save_environ = JimSaveEnv(JimBuildEnv(interp));
4862
4863 if (input != NULL) {
4864 if (inputFile == FILE_TEXT) {
4865 inputId = JimCreateTemp(interp, input, input_len);
@@ -4877,11 +4866,11 @@
4866 if (inputId == JIM_BAD_FD) {
4867 goto error;
4868 }
4869 }
4870 else if (inputFile == FILE_HANDLE) {
4871
4872 FILE *fh = JimGetAioFilehandle(interp, input);
4873
4874 if (fh == NULL) {
4875 goto error;
4876 }
@@ -4929,20 +4918,20 @@
4918 }
4919 lastOutputId = pipeIds[1];
4920 *outPipePtr = pipeIds[0];
4921 pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
4922 }
4923
4924 if (error != NULL) {
4925 if (errorFile == FILE_HANDLE) {
4926 if (strcmp(error, "1") == 0) {
4927
4928 if (lastOutputId != JIM_BAD_FD) {
4929 errorId = JimDupFd(lastOutputId);
4930 }
4931 else {
4932
4933 error = "stdout";
4934 }
4935 }
4936 if (errorId == JIM_BAD_FD) {
4937 FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4984,11 +4973,11 @@
4973 pipe_dup_err = 1;
4974 }
4975 break;
4976 }
4977 }
4978
4979 arg_array[lastArg] = NULL;
4980 if (lastArg == arg_count) {
4981 outputId = lastOutputId;
4982 }
4983 else {
@@ -4997,16 +4986,16 @@
4986 goto error;
4987 }
4988 outputId = pipeIds[1];
4989 }
4990
4991
4992 if (pipe_dup_err) {
4993 errorId = outputId;
4994 }
4995
4996
4997
4998 #ifdef __MINGW32__
4999 pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
5000 if (pid == JIM_BAD_PID) {
5001 Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -5017,32 +5006,32 @@
5006 if (pid < 0) {
5007 Jim_SetResultErrno(interp, "couldn't fork child process");
5008 goto error;
5009 }
5010 if (pid == 0) {
5011
5012
5013 if (inputId != -1) dup2(inputId, 0);
5014 if (outputId != -1) dup2(outputId, 1);
5015 if (errorId != -1) dup2(errorId, 2);
5016
5017 for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
5018 close(i);
5019 }
5020
5021
5022 (void)signal(SIGPIPE, SIG_DFL);
5023
5024 execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
5025
5026
5027 fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
5028 _exit(127);
5029 }
5030 #endif
5031
5032
5033
5034 if (table->used == table->size) {
5035 table->size += WAIT_TABLE_GROW_BY;
5036 table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
5037 }
@@ -5051,11 +5040,11 @@
5040 table->info[table->used].flags = 0;
5041 table->used++;
5042
5043 pidPtr[numPids] = pid;
5044
5045
5046 errorId = origErrorId;
5047
5048
5049 if (inputId != JIM_BAD_FD) {
5050 JimCloseFd(inputId);
@@ -5122,11 +5111,11 @@
5111 {
5112 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
5113 int result = JIM_OK;
5114 int i;
5115
5116
5117 for (i = 0; i < numPids; i++) {
5118 int waitStatus = 0;
5119 if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
5120 if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) {
5121 result = JIM_ERR;
@@ -5295,21 +5284,17 @@
5284 }
5285
5286 static fdtype JimOpenForRead(const char *filename)
5287 {
5288 return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
5289 JimStdSecAttrs(), OPEN_EXISTING, 0, NULL);
5290 }
5291
5292 static fdtype JimOpenForWrite(const char *filename, int append)
5293 {
5294 return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5295 JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL);
 
 
 
 
5296 }
5297
5298 static FILE *JimFdOpenForWrite(fdtype fd)
5299 {
5300 return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5317,11 +5302,11 @@
5302
5303 static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
5304 {
5305 DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
5306 if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
5307
5308 return JIM_BAD_PID;
5309 }
5310 GetExitCodeProcess(pid, &ret);
5311 *status = ret;
5312 CloseHandle(pid);
@@ -5344,11 +5329,11 @@
5329 if (handle == INVALID_HANDLE_VALUE) {
5330 goto error;
5331 }
5332
5333 if (contents != NULL) {
5334
5335 FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
5336 if (fh == NULL) {
5337 goto error;
5338 }
5339
@@ -5616,11 +5601,11 @@
5601 #include <sys/time.h>
5602 #endif
5603
5604 static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5605 {
5606
5607 char buf[100];
5608 time_t t;
5609 long seconds;
5610
5611 const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5657,20 +5642,20 @@
5642
5643 if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
5644 return -1;
5645 }
5646
5647
5648 localtime_r(&now, &tm);
5649
5650 pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
5651 if (pt == 0 || *pt != 0) {
5652 Jim_SetResultString(interp, "Failed to parse time according to format", -1);
5653 return JIM_ERR;
5654 }
5655
5656
5657 Jim_SetResultInt(interp, mktime(&tm));
5658
5659 return JIM_OK;
5660 }
5661 #endif
@@ -5708,47 +5693,47 @@
5693 { "seconds",
5694 NULL,
5695 clock_cmd_seconds,
5696 0,
5697 0,
5698
5699 },
5700 { "clicks",
5701 NULL,
5702 clock_cmd_micros,
5703 0,
5704 0,
5705
5706 },
5707 { "microseconds",
5708 NULL,
5709 clock_cmd_micros,
5710 0,
5711 0,
5712
5713 },
5714 { "milliseconds",
5715 NULL,
5716 clock_cmd_millis,
5717 0,
5718 0,
5719
5720 },
5721 { "format",
5722 "seconds ?-format format?",
5723 clock_cmd_format,
5724 1,
5725 3,
5726
5727 },
5728 #ifdef HAVE_STRPTIME
5729 { "scan",
5730 "str -format format",
5731 clock_cmd_scan,
5732 3,
5733 3,
5734
5735 },
5736 #endif
5737 { NULL }
5738 };
5739
@@ -5768,11 +5753,11 @@
5753 #include <errno.h>
5754
5755
5756 static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5757 {
5758
5759 Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
5760 return JIM_OK;
5761 }
5762
5763 static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5784,20 +5769,20 @@
5769 return JIM_OK;
5770 }
5771
5772 patternObj = (argc == 1) ? NULL : argv[1];
5773
5774
5775 if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
5776 if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
5777
5778 Jim_SetResult(interp, objPtr);
5779 return JIM_OK;
5780 }
5781 }
5782
5783
5784 return Jim_DictValues(interp, objPtr, patternObj);
5785 }
5786
5787 static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5788 {
@@ -5817,27 +5802,27 @@
5802 Jim_Obj *resultObj;
5803 Jim_Obj *objPtr;
5804 Jim_Obj **dictValuesObj;
5805
5806 if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
5807
5808 Jim_UnsetVariable(interp, argv[0], JIM_NONE);
5809 return JIM_OK;
5810 }
5811
5812 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5813
5814 if (objPtr == NULL) {
5815
5816 return JIM_OK;
5817 }
5818
5819 if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
5820 return JIM_ERR;
5821 }
5822
5823
5824 resultObj = Jim_NewDictObj(interp, NULL, 0);
5825
5826 for (i = 0; i < len; i += 2) {
5827 if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
5828 Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5852,11 +5837,11 @@
5837 static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5838 {
5839 Jim_Obj *objPtr;
5840 int len = 0;
5841
5842
5843 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5844 if (objPtr) {
5845 len = Jim_DictSize(interp, objPtr);
5846 if (len < 0) {
5847 return JIM_ERR;
@@ -5891,11 +5876,11 @@
5876 return JIM_ERR;
5877 }
5878
5879 dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
5880 if (!dictObj) {
5881
5882 return Jim_SetVariable(interp, argv[0], listObj);
5883 }
5884 else if (Jim_DictSize(interp, dictObj) < 0) {
5885 return JIM_ERR;
5886 }
@@ -5920,53 +5905,53 @@
5905 { "exists",
5906 "arrayName",
5907 array_cmd_exists,
5908 1,
5909 1,
5910
5911 },
5912 { "get",
5913 "arrayName ?pattern?",
5914 array_cmd_get,
5915 1,
5916 2,
5917
5918 },
5919 { "names",
5920 "arrayName ?pattern?",
5921 array_cmd_names,
5922 1,
5923 2,
5924
5925 },
5926 { "set",
5927 "arrayName list",
5928 array_cmd_set,
5929 2,
5930 2,
5931
5932 },
5933 { "size",
5934 "arrayName",
5935 array_cmd_size,
5936 1,
5937 1,
5938
5939 },
5940 { "stat",
5941 "arrayName",
5942 array_cmd_stat,
5943 1,
5944 1,
5945
5946 },
5947 { "unset",
5948 "arrayName ?pattern?",
5949 array_cmd_unset,
5950 1,
5951 2,
5952
5953 },
5954 { NULL
5955 }
5956 };
5957
@@ -6002,12 +5987,11 @@
5987 Jim_arrayInit(interp);
5988 Jim_stdlibInit(interp);
5989 Jim_tclcompatInit(interp);
5990 return JIM_OK;
5991 }
5992 #define JIM_OPTIMIZATION
 
5993
5994 #include <stdio.h>
5995 #include <stdlib.h>
5996
5997 #include <string.h>
@@ -6072,16 +6056,10 @@
6056 #define JimPanic(X) JimPanicDump X
6057 #else
6058 #define JimPanic(X)
6059 #endif
6060
 
 
 
 
 
 
6061
6062 static char JimEmptyStringRep[] = "";
6063
6064 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
6065 static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -6134,34 +6112,34 @@
6112 if (*pattern == '^') {
6113 not++;
6114 pattern++;
6115 }
6116
6117
6118 if (*pattern == ']') {
6119 goto first;
6120 }
6121 }
6122
6123 while (*pattern && *pattern != ']') {
6124
6125 if (pattern[0] == '\\') {
6126 first:
6127 pattern += utf8_tounicode_case(pattern, &pchar, nocase);
6128 }
6129 else {
6130
6131 int start;
6132 int end;
6133
6134 pattern += utf8_tounicode_case(pattern, &start, nocase);
6135 if (pattern[0] == '-' && pattern[1]) {
6136
6137 pattern += utf8_tounicode(pattern, &pchar);
6138 pattern += utf8_tounicode_case(pattern, &end, nocase);
6139
6140
6141 if ((c >= start && c <= end) || (c >= end && c <= start)) {
6142 match = 1;
6143 }
6144 continue;
6145 }
@@ -6191,19 +6169,19 @@
6169 while (pattern[1] == '*') {
6170 pattern++;
6171 }
6172 pattern++;
6173 if (!pattern[0]) {
6174 return 1;
6175 }
6176 while (*string) {
6177
6178 if (JimGlobMatch(pattern, string, nocase))
6179 return 1;
6180 string += utf8_tounicode(string, &c);
6181 }
6182 return 0;
6183
6184 case '?':
6185 string += utf8_tounicode(string, &c);
6186 break;
6187
@@ -6212,20 +6190,20 @@
6190 pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
6191 if (!pattern) {
6192 return 0;
6193 }
6194 if (!*pattern) {
6195
6196 continue;
6197 }
6198 break;
6199 }
6200 case '\\':
6201 if (pattern[1]) {
6202 pattern++;
6203 }
6204
6205 default:
6206 string += utf8_tounicode_case(string, &c, nocase);
6207 utf8_tounicode_case(pattern, &pchar, nocase);
6208 if (pchar != c) {
6209 return 0;
@@ -6271,11 +6249,11 @@
6249 maxchars--;
6250 }
6251 if (!maxchars) {
6252 return 0;
6253 }
6254
6255 if (*s1) {
6256 return 1;
6257 }
6258 if (*s2) {
6259 return -1;
@@ -6312,11 +6290,11 @@
6290 const char *p;
6291
6292 if (!l1 || !l2 || l1 > l2)
6293 return -1;
6294
6295
6296 for (p = s2 + l2 - 1; p != s2 - 1; p--) {
6297 if (*p == *s1 && memcmp(s1, p, l1) == 0) {
6298 return p - s2;
6299 }
6300 }
@@ -6371,28 +6349,28 @@
6349 }
6350 *sign = 1;
6351 }
6352
6353 if (str[i] != '0') {
6354
6355 return 0;
6356 }
6357
6358
6359 switch (str[i + 1]) {
6360 case 'x': case 'X': *base = 16; break;
6361 case 'o': case 'O': *base = 8; break;
6362 case 'b': case 'B': *base = 2; break;
6363 default: return 0;
6364 }
6365 i += 2;
6366
6367 if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
6368
6369 return i;
6370 }
6371
6372 *base = 10;
6373 return 0;
6374 }
6375
6376 static long jim_strtol(const char *str, char **endptr)
@@ -6406,11 +6384,11 @@
6384 if (endptr == NULL || *endptr != str + i) {
6385 return value * sign;
6386 }
6387 }
6388
6389
6390 return strtol(str, endptr, 10);
6391 }
6392
6393
6394 static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6425,11 +6403,11 @@
6403 if (endptr == NULL || *endptr != str + i) {
6404 return value * sign;
6405 }
6406 }
6407
6408
6409 return strtoull(str, endptr, 10);
6410 #else
6411 return (unsigned long)jim_strtol(str, endptr);
6412 #endif
6413 }
@@ -6450,40 +6428,26 @@
6428
6429 int Jim_StringToDouble(const char *str, double *doublePtr)
6430 {
6431 char *endptr;
6432
6433
6434 errno = 0;
6435
6436 *doublePtr = strtod(str, &endptr);
6437
6438 return JimCheckConversion(str, endptr);
6439 }
6440
6441 static jim_wide JimPowWide(jim_wide b, jim_wide e)
6442 {
6443 jim_wide i, res = 1;
6444
6445 if ((b == 0 && e != 0) || (e < 0))
6446 return 0;
6447 for (i = 0; i < e; i++) {
6448 res *= b;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6449 }
6450 return res;
6451 }
6452
6453 #ifdef JIM_DEBUG_PANIC
@@ -6545,11 +6509,11 @@
6509 char *Jim_StrDupLen(const char *s, int l)
6510 {
6511 char *copy = Jim_Alloc(l + 1);
6512
6513 memcpy(copy, s, l + 1);
6514 copy[l] = 0;
6515 return copy;
6516 }
6517
6518
6519
@@ -6634,52 +6598,52 @@
6598 }
6599
6600
6601 void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
6602 {
6603 Jim_HashTable n;
6604 unsigned int realsize = JimHashTableNextPower(size), i;
6605
6606 if (size <= ht->used)
6607 return;
6608
6609 Jim_InitHashTable(&n, ht->type, ht->privdata);
6610 n.size = realsize;
6611 n.sizemask = realsize - 1;
6612 n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
6613
6614 n.uniq = ht->uniq;
6615
6616
6617 memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
6618
6619 n.used = ht->used;
6620 for (i = 0; ht->used > 0; i++) {
6621 Jim_HashEntry *he, *nextHe;
6622
6623 if (ht->table[i] == NULL)
6624 continue;
6625
6626
6627 he = ht->table[i];
6628 while (he) {
6629 unsigned int h;
6630
6631 nextHe = he->next;
6632
6633 h = Jim_HashKey(ht, he->key) & n.sizemask;
6634 he->next = n.table[h];
6635 n.table[h] = he;
6636 ht->used--;
6637
6638 he = nextHe;
6639 }
6640 }
6641 assert(ht->used == 0);
6642 Jim_Free(ht->table);
6643
6644
6645 *ht = n;
6646 }
6647
6648
6649 int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6688,11 +6652,11 @@
6652
6653 entry = JimInsertHashEntry(ht, key, 0);
6654 if (entry == NULL)
6655 return JIM_ERR;
6656
6657
6658 Jim_SetHashKey(ht, entry, key);
6659 Jim_SetHashVal(ht, entry, val);
6660 return JIM_OK;
6661 }
6662
@@ -6714,11 +6678,11 @@
6678 Jim_SetHashVal(ht, entry, val);
6679 }
6680 existed = 1;
6681 }
6682 else {
6683
6684 Jim_SetHashKey(ht, entry, key);
6685 Jim_SetHashVal(ht, entry, val);
6686 existed = 0;
6687 }
6688
@@ -6737,11 +6701,11 @@
6701 he = ht->table[h];
6702
6703 prevHe = NULL;
6704 while (he) {
6705 if (Jim_CompareHashKeys(ht, key, he->key)) {
6706
6707 if (prevHe)
6708 prevHe->next = he->next;
6709 else
6710 ht->table[h] = he->next;
6711 Jim_FreeEntryKey(ht, he);
@@ -6751,19 +6715,19 @@
6715 return JIM_OK;
6716 }
6717 prevHe = he;
6718 he = he->next;
6719 }
6720 return JIM_ERR;
6721 }
6722
6723
6724 int Jim_FreeHashTable(Jim_HashTable *ht)
6725 {
6726 unsigned int i;
6727
6728
6729 for (i = 0; ht->used > 0; i++) {
6730 Jim_HashEntry *he, *nextHe;
6731
6732 if ((he = ht->table[i]) == NULL)
6733 continue;
@@ -6774,15 +6738,15 @@
6738 Jim_Free(he);
6739 ht->used--;
6740 he = nextHe;
6741 }
6742 }
6743
6744 Jim_Free(ht->table);
6745
6746 JimResetHashTable(ht);
6747 return JIM_OK;
6748 }
6749
6750 Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
6751 {
6752 Jim_HashEntry *he;
@@ -6855,24 +6819,24 @@
6819 static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
6820 {
6821 unsigned int h;
6822 Jim_HashEntry *he;
6823
6824
6825 JimExpandHashTableIfNeeded(ht);
6826
6827
6828 h = Jim_HashKey(ht, key) & ht->sizemask;
6829
6830 he = ht->table[h];
6831 while (he) {
6832 if (Jim_CompareHashKeys(ht, key, he->key))
6833 return replace ? he : NULL;
6834 he = he->next;
6835 }
6836
6837
6838 he = Jim_Alloc(sizeof(*he));
6839 he->next = ht->table[h];
6840 ht->table[h] = he;
6841 ht->used++;
6842 he->key = NULL;
@@ -6901,16 +6865,16 @@
6865 {
6866 Jim_Free(key);
6867 }
6868
6869 static const Jim_HashTableType JimPackageHashTableType = {
6870 JimStringCopyHTHashFunction,
6871 JimStringCopyHTDup,
6872 NULL,
6873 JimStringCopyHTKeyCompare,
6874 JimStringCopyHTKeyDestructor,
6875 NULL
6876 };
6877
6878 typedef struct AssocDataValue
6879 {
6880 Jim_InterpDeleteProc *delProc;
@@ -6925,16 +6889,16 @@
6889 assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
6890 Jim_Free(data);
6891 }
6892
6893 static const Jim_HashTableType JimAssocDataHashTableType = {
6894 JimStringCopyHTHashFunction,
6895 JimStringCopyHTDup,
6896 NULL,
6897 JimStringCopyHTKeyCompare,
6898 JimStringCopyHTKeyDestructor,
6899 JimAssocDataHashTableValueDestructor
6900 };
6901
6902 void Jim_InitStack(Jim_Stack *stack)
6903 {
6904 stack->len = 0;
@@ -6987,61 +6951,56 @@
6951 freeFunc(stack->vector[i]);
6952 }
6953
6954
6955
6956 #define JIM_TT_NONE 0
6957 #define JIM_TT_STR 1
6958 #define JIM_TT_ESC 2
6959 #define JIM_TT_VAR 3
6960 #define JIM_TT_DICTSUGAR 4
6961 #define JIM_TT_CMD 5
6962
6963 #define JIM_TT_SEP 6
6964 #define JIM_TT_EOL 7
6965 #define JIM_TT_EOF 8
6966
6967 #define JIM_TT_LINE 9
6968 #define JIM_TT_WORD 10
6969
6970
6971 #define JIM_TT_SUBEXPR_START 11
6972 #define JIM_TT_SUBEXPR_END 12
6973 #define JIM_TT_SUBEXPR_COMMA 13
6974 #define JIM_TT_EXPR_INT 14
6975 #define JIM_TT_EXPR_DOUBLE 15
 
6976
6977 #define JIM_TT_EXPRSUGAR 16
6978
6979
6980 #define JIM_TT_EXPR_OP 20
6981
6982 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
6983
 
 
 
 
6984 struct JimParseMissing {
6985 int ch;
6986 int line;
6987 };
6988
6989 struct JimParserCtx
6990 {
6991 const char *p;
6992 int len;
6993 int linenr;
6994 const char *tstart;
6995 const char *tend;
6996 int tline;
6997 int tt;
6998 int eof;
6999 int inquote;
7000 int comment;
7001 struct JimParseMissing missing;
7002 };
7003
7004 static int JimParseScript(struct JimParserCtx *pc);
7005 static int JimParseSep(struct JimParserCtx *pc);
7006 static int JimParseEol(struct JimParserCtx *pc);
@@ -7071,11 +7030,11 @@
7030 pc->missing.line = linenr;
7031 }
7032
7033 static int JimParseScript(struct JimParserCtx *pc)
7034 {
7035 while (1) {
7036 if (!pc->len) {
7037 pc->tstart = pc->p;
7038 pc->tend = pc->p - 1;
7039 pc->tline = pc->linenr;
7040 pc->tt = JIM_TT_EOL;
@@ -7107,11 +7066,11 @@
7066 pc->comment = 0;
7067 return JimParseCmd(pc);
7068 case '$':
7069 pc->comment = 0;
7070 if (JimParseVar(pc) == JIM_ERR) {
7071
7072 pc->tstart = pc->tend = pc->p++;
7073 pc->len--;
7074 pc->tt = JIM_TT_ESC;
7075 }
7076 return JIM_OK;
@@ -7168,11 +7127,11 @@
7127
7128 static void JimParseSubBrace(struct JimParserCtx *pc)
7129 {
7130 int level = 1;
7131
7132
7133 pc->p++;
7134 pc->len--;
7135 while (pc->len) {
7136 switch (*pc->p) {
7137 case '\\':
@@ -7212,11 +7171,11 @@
7171 static int JimParseSubQuote(struct JimParserCtx *pc)
7172 {
7173 int tt = JIM_TT_STR;
7174 int line = pc->tline;
7175
7176
7177 pc->p++;
7178 pc->len--;
7179 while (pc->len) {
7180 switch (*pc->p) {
7181 case '\\':
@@ -7261,11 +7220,11 @@
7220 {
7221 int level = 1;
7222 int startofword = 1;
7223 int line = pc->tline;
7224
7225
7226 pc->p++;
7227 pc->len--;
7228 while (pc->len) {
7229 switch (*pc->p) {
7230 case '\\':
@@ -7341,17 +7300,17 @@
7300 return JIM_OK;
7301 }
7302
7303 static int JimParseVar(struct JimParserCtx *pc)
7304 {
7305
7306 pc->p++;
7307 pc->len--;
7308
7309 #ifdef EXPRSUGAR_BRACKET
7310 if (*pc->p == '[') {
7311
7312 JimParseCmd(pc);
7313 pc->tt = JIM_TT_EXPRSUGAR;
7314 return JIM_OK;
7315 }
7316 #endif
@@ -7377,11 +7336,11 @@
7336 pc->len--;
7337 }
7338 }
7339 else {
7340 while (1) {
7341
7342 if (pc->p[0] == ':' && pc->p[1] == ':') {
7343 while (*pc->p == ':') {
7344 pc->p++;
7345 pc->len--;
7346 }
@@ -7392,11 +7351,11 @@
7351 pc->len--;
7352 continue;
7353 }
7354 break;
7355 }
7356
7357 if (*pc->p == '(') {
7358 int count = 1;
7359 const char *paren = NULL;
7360
7361 pc->tt = JIM_TT_DICTSUGAR;
@@ -7419,11 +7378,11 @@
7378 if (count == 0) {
7379 pc->p++;
7380 pc->len--;
7381 }
7382 else if (paren) {
7383
7384 paren++;
7385 pc->len += (pc->p - paren);
7386 pc->p = paren;
7387 }
7388 #ifndef EXPRSUGAR_BRACKET
@@ -7444,19 +7403,19 @@
7403
7404 static int JimParseStr(struct JimParserCtx *pc)
7405 {
7406 if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
7407 pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
7408
7409 if (*pc->p == '{') {
7410 return JimParseBrace(pc);
7411 }
7412 if (*pc->p == '"') {
7413 pc->inquote = 1;
7414 pc->p++;
7415 pc->len--;
7416
7417 pc->missing.line = pc->tline;
7418 }
7419 }
7420 pc->tstart = pc->p;
7421 pc->tline = pc->linenr;
@@ -7482,25 +7441,25 @@
7441 }
7442 pc->p++;
7443 pc->len--;
7444 }
7445 else if (pc->len == 1) {
7446
7447 pc->missing.ch = '\\';
7448 }
7449 break;
7450 case '(':
7451
7452 if (pc->len > 1 && pc->p[1] != '$') {
7453 break;
7454 }
7455
7456 case ')':
7457
7458 if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
7459 if (pc->p == pc->tstart) {
7460
7461 pc->p++;
7462 pc->len--;
7463 }
7464 pc->tend = pc->p - 1;
7465 pc->tt = JIM_TT_ESC;
@@ -7540,11 +7499,11 @@
7499 break;
7500 }
7501 pc->p++;
7502 pc->len--;
7503 }
7504 return JIM_OK;
7505 }
7506
7507 static int JimParseComment(struct JimParserCtx *pc)
7508 {
7509 while (*pc->p) {
@@ -7651,34 +7610,34 @@
7610 if (c == -1) {
7611 break;
7612 }
7613 val = (val << 4) | c;
7614 }
7615
7616 if (s[i] == '{') {
7617 if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
7618
7619 i--;
7620 k = 0;
7621 }
7622 else {
7623
7624 k++;
7625 }
7626 }
7627 if (k) {
7628
7629 if (s[i] == 'x') {
7630 *p++ = val;
7631 }
7632 else {
7633 p += utf8_fromunicode(p, val);
7634 }
7635 i += k;
7636 break;
7637 }
7638
7639 *p++ = s[i];
7640 }
7641 break;
7642 case 'v':
7643 *p++ = 0xb;
@@ -7687,11 +7646,11 @@
7646 case '\0':
7647 *p++ = '\\';
7648 i++;
7649 break;
7650 case '\n':
7651
7652 *p++ = ' ';
7653 do {
7654 i++;
7655 } while (s[i + 1] == ' ' || s[i + 1] == '\t');
7656 break;
@@ -7701,11 +7660,11 @@
7660 case '3':
7661 case '4':
7662 case '5':
7663 case '6':
7664 case '7':
7665
7666 {
7667 int val = 0;
7668 int c = odigitval(s[i + 1]);
7669
7670 val = c;
@@ -7758,16 +7717,16 @@
7717 }
7718 else {
7719 len = (end - start) + 1;
7720 token = Jim_Alloc(len + 1);
7721 if (pc->tt != JIM_TT_ESC) {
7722
7723 memcpy(token, start, len);
7724 token[len] = '\0';
7725 }
7726 else {
7727
7728 len = JimEscape(token, start, len);
7729 }
7730 }
7731
7732 return Jim_NewStringObjNoAlloc(interp, token, len);
@@ -7831,11 +7790,11 @@
7790 while (pc->len) {
7791 switch (*pc->p) {
7792 case '\\':
7793 pc->tt = JIM_TT_ESC;
7794 if (--pc->len == 0) {
7795
7796 pc->tend = pc->p;
7797 return JIM_OK;
7798 }
7799 pc->p++;
7800 break;
@@ -7867,11 +7826,11 @@
7826 pc->tend = pc->p - 1;
7827 return JIM_OK;
7828 }
7829 if (*pc->p == '\\') {
7830 if (--pc->len == 0) {
7831
7832 pc->tend = pc->p;
7833 return JIM_OK;
7834 }
7835 pc->tt = JIM_TT_ESC;
7836 pc->p++;
@@ -7887,24 +7846,24 @@
7846
7847 Jim_Obj *Jim_NewObj(Jim_Interp *interp)
7848 {
7849 Jim_Obj *objPtr;
7850
7851
7852 if (interp->freeList != NULL) {
7853
7854 objPtr = interp->freeList;
7855 interp->freeList = objPtr->nextObjPtr;
7856 }
7857 else {
7858
7859 objPtr = Jim_Alloc(sizeof(*objPtr));
7860 }
7861
7862 objPtr->refCount = 0;
7863
7864
7865 objPtr->prevObjPtr = NULL;
7866 objPtr->nextObjPtr = interp->liveList;
7867 if (interp->liveList)
7868 interp->liveList->prevObjPtr = objPtr;
7869 interp->liveList = objPtr;
@@ -7912,32 +7871,32 @@
7871 return objPtr;
7872 }
7873
7874 void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
7875 {
7876
7877 JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
7878 objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>"));
7879
7880
7881 Jim_FreeIntRep(interp, objPtr);
7882
7883 if (objPtr->bytes != NULL) {
7884 if (objPtr->bytes != JimEmptyStringRep)
7885 Jim_Free(objPtr->bytes);
7886 }
7887
7888 if (objPtr->prevObjPtr)
7889 objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
7890 if (objPtr->nextObjPtr)
7891 objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
7892 if (interp->liveList == objPtr)
7893 interp->liveList = objPtr->nextObjPtr;
7894 #ifdef JIM_DISABLE_OBJECT_POOL
7895 Jim_Free(objPtr);
7896 #else
7897
7898 objPtr->prevObjPtr = NULL;
7899 objPtr->nextObjPtr = interp->freeList;
7900 if (interp->freeList)
7901 interp->freeList->prevObjPtr = objPtr;
7902 interp->freeList = objPtr;
@@ -7960,45 +7919,45 @@
7919 {
7920 Jim_Obj *dupPtr;
7921
7922 dupPtr = Jim_NewObj(interp);
7923 if (objPtr->bytes == NULL) {
7924
7925 dupPtr->bytes = NULL;
7926 }
7927 else if (objPtr->length == 0) {
7928
7929 dupPtr->bytes = JimEmptyStringRep;
7930 dupPtr->length = 0;
7931 dupPtr->typePtr = NULL;
7932 return dupPtr;
7933 }
7934 else {
7935 dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
7936 dupPtr->length = objPtr->length;
7937
7938 memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
7939 }
7940
7941
7942 dupPtr->typePtr = objPtr->typePtr;
7943 if (objPtr->typePtr != NULL) {
7944 if (objPtr->typePtr->dupIntRepProc == NULL) {
7945 dupPtr->internalRep = objPtr->internalRep;
7946 }
7947 else {
7948
7949 objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
7950 }
7951 }
7952 return dupPtr;
7953 }
7954
7955 const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
7956 {
7957 if (objPtr->bytes == NULL) {
7958
7959 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7960 objPtr->typePtr->updateStringProc(objPtr);
7961 }
7962 if (lenPtr)
7963 *lenPtr = objPtr->length;
@@ -8007,11 +7966,11 @@
7966
7967
7968 int Jim_Length(Jim_Obj *objPtr)
7969 {
7970 if (objPtr->bytes == NULL) {
7971
7972 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7973 objPtr->typePtr->updateStringProc(objPtr);
7974 }
7975 return objPtr->length;
7976 }
@@ -8018,11 +7977,11 @@
7977
7978
7979 const char *Jim_String(Jim_Obj *objPtr)
7980 {
7981 if (objPtr->bytes == NULL) {
7982
7983 JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
7984 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7985 objPtr->typePtr->updateStringProc(objPtr);
7986 }
7987 return objPtr->bytes;
@@ -8078,22 +8037,22 @@
8037 }
8038
8039 static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
8040 {
8041 if (objPtr->typePtr != &stringObjType) {
8042
8043 if (objPtr->bytes == NULL) {
8044
8045 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
8046 objPtr->typePtr->updateStringProc(objPtr);
8047 }
8048
8049 Jim_FreeIntRep(interp, objPtr);
8050
8051 objPtr->typePtr = &stringObjType;
8052 objPtr->internalRep.strValue.maxLength = objPtr->length;
8053
8054 objPtr->internalRep.strValue.charLength = -1;
8055 }
8056 return JIM_OK;
8057 }
8058
@@ -8114,14 +8073,14 @@
8073
8074 Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
8075 {
8076 Jim_Obj *objPtr = Jim_NewObj(interp);
8077
8078
8079 if (len == -1)
8080 len = strlen(s);
8081
8082 if (len == 0) {
8083 objPtr->bytes = JimEmptyStringRep;
8084 }
8085 else {
8086 objPtr->bytes = Jim_Alloc(len + 1);
@@ -8128,25 +8087,25 @@
8087 memcpy(objPtr->bytes, s, len);
8088 objPtr->bytes[len] = '\0';
8089 }
8090 objPtr->length = len;
8091
8092
8093 objPtr->typePtr = NULL;
8094 return objPtr;
8095 }
8096
8097
8098 Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
8099 {
8100 #ifdef JIM_UTF8
8101
8102 int bytelen = utf8_index(s, charlen);
8103
8104 Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
8105
8106
8107 objPtr->typePtr = &stringObjType;
8108 objPtr->internalRep.strValue.maxLength = bytelen;
8109 objPtr->internalRep.strValue.charLength = charlen;
8110
8111 return objPtr;
@@ -8173,11 +8132,11 @@
8132 len = strlen(str);
8133 needlen = objPtr->length + len;
8134 if (objPtr->internalRep.strValue.maxLength < needlen ||
8135 objPtr->internalRep.strValue.maxLength == 0) {
8136 needlen *= 2;
8137
8138 if (needlen < 7) {
8139 needlen = 7;
8140 }
8141 if (objPtr->bytes == JimEmptyStringRep) {
8142 objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8189,11 +8148,11 @@
8148 }
8149 memcpy(objPtr->bytes + objPtr->length, str, len);
8150 objPtr->bytes[objPtr->length + len] = '\0';
8151
8152 if (objPtr->internalRep.strValue.charLength >= 0) {
8153
8154 objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
8155 }
8156 objPtr->length += len;
8157 }
8158
@@ -8251,11 +8210,11 @@
8210 int l1, l2;
8211 const char *s1 = Jim_GetString(firstObjPtr, &l1);
8212 const char *s2 = Jim_GetString(secondObjPtr, &l2);
8213
8214 if (nocase) {
8215
8216 return JimStringCompareLen(s1, s2, -1, nocase);
8217 }
8218 return JimStringCompare(s1, l1, s2, l2);
8219 }
8220
@@ -8353,11 +8312,11 @@
8312
8313 if (first == 0 && rangeLen == len) {
8314 return strObjPtr;
8315 }
8316 if (len == bytelen) {
8317
8318 return Jim_NewStringObj(interp, str + first, rangeLen);
8319 }
8320 return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
8321 #else
8322 return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8382,19 +8341,19 @@
8341 return strObjPtr;
8342 }
8343
8344 str = Jim_String(strObjPtr);
8345
8346
8347 objPtr = Jim_NewStringObjUtf8(interp, str, first);
8348
8349
8350 if (newStrObj) {
8351 Jim_AppendObj(interp, objPtr, newStrObj);
8352 }
8353
8354
8355 Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
8356
8357 return objPtr;
8358 }
8359
@@ -8493,11 +8452,11 @@
8452 while (len) {
8453 int c;
8454 int n = utf8_tounicode(str, &c);
8455
8456 if (utf8_memchr(trimchars, trimlen, c) == NULL) {
8457
8458 break;
8459 }
8460 str += n;
8461 len -= n;
8462 }
@@ -8564,41 +8523,41 @@
8523
8524 len = Jim_Length(strObjPtr);
8525 nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
8526
8527 if (nontrim == NULL) {
8528
8529 return Jim_NewEmptyStringObj(interp);
8530 }
8531 if (nontrim == strObjPtr->bytes + len) {
8532
8533 return strObjPtr;
8534 }
8535
8536 if (Jim_IsShared(strObjPtr)) {
8537 strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
8538 }
8539 else {
8540
8541 strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
8542 strObjPtr->length = (nontrim - strObjPtr->bytes);
8543 }
8544
8545 return strObjPtr;
8546 }
8547
8548 static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
8549 {
8550
8551 Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
8552
8553
8554 strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
8555
8556
8557 if (objPtr != strObjPtr && objPtr->refCount == 0) {
8558
8559 Jim_FreeNewObj(interp, objPtr);
8560 }
8561
8562 return strObjPtr;
8563 }
@@ -8616,17 +8575,17 @@
8575 static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
8576 {
8577 static const char * const strclassnames[] = {
8578 "integer", "alpha", "alnum", "ascii", "digit",
8579 "double", "lower", "upper", "space", "xdigit",
8580 "control", "print", "graph", "punct",
8581 NULL
8582 };
8583 enum {
8584 STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
8585 STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
8586 STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
8587 };
8588 int strclass;
8589 int len;
8590 int i;
8591 const char *str;
@@ -8655,17 +8614,10 @@
8614 double d;
8615 Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
8616 return JIM_OK;
8617 }
8618
 
 
 
 
 
 
 
8619 case STR_IS_ALPHA: isclassfunc = isalpha; break;
8620 case STR_IS_ALNUM: isclassfunc = isalnum; break;
8621 case STR_IS_ASCII: isclassfunc = jim_isascii; break;
8622 case STR_IS_DIGIT: isclassfunc = isdigit; break;
8623 case STR_IS_LOWER: isclassfunc = islower; break;
@@ -8713,11 +8665,11 @@
8665
8666 if (objPtr->typePtr != &comparedStringObjType) {
8667 Jim_FreeIntRep(interp, objPtr);
8668 objPtr->typePtr = &comparedStringObjType;
8669 }
8670 objPtr->internalRep.ptr = (char *)str;
8671 return 1;
8672 }
8673 }
8674
8675 static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8806,20 +8758,20 @@
8758 int type;
8759 } ScriptToken;
8760
8761 typedef struct ScriptObj
8762 {
8763 ScriptToken *token;
8764 Jim_Obj *fileNameObj;
8765 int len;
8766 int substFlags;
8767 int inUse; /* Used to share a ScriptObj. Currently
8768 only used by Jim_EvalObj() as protection against
8769 shimmering of the currently evaluated object. */
8770 int firstline;
8771 int linenr;
8772 int missing;
8773 } ScriptObj;
8774
8775 static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
8776 static int JimParseCheckMissing(Jim_Interp *interp, int ch);
8777 static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -8847,23 +8799,23 @@
8799 dupPtr->typePtr = NULL;
8800 }
8801
8802 typedef struct
8803 {
8804 const char *token;
8805 int len;
8806 int type;
8807 int line;
8808 } ParseToken;
8809
8810 typedef struct
8811 {
8812
8813 ParseToken *list;
8814 int size;
8815 int count;
8816 ParseToken static_list[20];
8817 } ParseTokenList;
8818
8819 static void ScriptTokenListInit(ParseTokenList *tokenlist)
8820 {
8821 tokenlist->list = tokenlist->static_list;
@@ -8882,18 +8834,18 @@
8834 int line)
8835 {
8836 ParseToken *t;
8837
8838 if (tokenlist->count == tokenlist->size) {
8839
8840 tokenlist->size *= 2;
8841 if (tokenlist->list != tokenlist->static_list) {
8842 tokenlist->list =
8843 Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
8844 }
8845 else {
8846
8847 tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
8848 memcpy(tokenlist->list, tokenlist->static_list,
8849 tokenlist->count * sizeof(*tokenlist->list));
8850 }
8851 }
@@ -8907,20 +8859,20 @@
8859 static int JimCountWordTokens(ParseToken *t)
8860 {
8861 int expand = 1;
8862 int count = 0;
8863
8864
8865 if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
8866 if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
8867
8868 expand = -1;
8869 t++;
8870 }
8871 }
8872
8873
8874 while (!TOKEN_IS_SEP(t->type)) {
8875 t++;
8876 count++;
8877 }
8878
@@ -8930,11 +8882,11 @@
8882 static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
8883 {
8884 Jim_Obj *objPtr;
8885
8886 if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
8887
8888 int len = t->len;
8889 char *str = Jim_Alloc(len + 1);
8890 len = JimEscape(str, t->token, len);
8891 objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
8892 }
@@ -8947,13 +8899,13 @@
8899 static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
8900 ParseTokenList *tokenlist)
8901 {
8902 int i;
8903 struct ScriptToken *token;
8904
8905 int lineargs = 0;
8906
8907 ScriptToken *linefirst;
8908 int count;
8909 int linenr;
8910
8911 #ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8962,11 +8914,11 @@
8914 printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
8915 tokenlist->list[i].len, tokenlist->list[i].token);
8916 }
8917 #endif
8918
8919
8920 count = tokenlist->count;
8921 for (i = 0; i < tokenlist->count; i++) {
8922 if (tokenlist->list[i].type == JIM_TT_EOL) {
8923 count++;
8924 }
@@ -8973,59 +8925,59 @@
8925 }
8926 linenr = script->firstline = tokenlist->list[0].line;
8927
8928 token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
8929
8930
8931 linefirst = token++;
8932
8933 for (i = 0; i < tokenlist->count; ) {
8934
8935 int wordtokens;
8936
8937
8938 while (tokenlist->list[i].type == JIM_TT_SEP) {
8939 i++;
8940 }
8941
8942 wordtokens = JimCountWordTokens(tokenlist->list + i);
8943
8944 if (wordtokens == 0) {
8945
8946 if (lineargs) {
8947 linefirst->type = JIM_TT_LINE;
8948 linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
8949 Jim_IncrRefCount(linefirst->objPtr);
8950
8951
8952 lineargs = 0;
8953 linefirst = token++;
8954 }
8955 i++;
8956 continue;
8957 }
8958 else if (wordtokens != 1) {
8959
8960 token->type = JIM_TT_WORD;
8961 token->objPtr = Jim_NewIntObj(interp, wordtokens);
8962 Jim_IncrRefCount(token->objPtr);
8963 token++;
8964 if (wordtokens < 0) {
8965
8966 i++;
8967 wordtokens = -wordtokens - 1;
8968 lineargs--;
8969 }
8970 }
8971
8972 if (lineargs == 0) {
8973
8974 linenr = tokenlist->list[i].line;
8975 }
8976 lineargs++;
8977
8978
8979 while (wordtokens--) {
8980 const ParseToken *t = &tokenlist->list[i++];
8981
8982 token->type = t->type;
8983 token->objPtr = JimMakeScriptObj(interp, t);
@@ -9097,11 +9049,11 @@
9049 token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
9050
9051 for (i = 0; i < tokenlist->count; i++) {
9052 const ParseToken *t = &tokenlist->list[i];
9053
9054
9055 token->type = t->type;
9056 token->objPtr = JimMakeScriptObj(interp, t);
9057 Jim_IncrRefCount(token->objPtr);
9058 token++;
9059 }
@@ -9116,29 +9068,29 @@
9068 struct JimParserCtx parser;
9069 struct ScriptObj *script;
9070 ParseTokenList tokenlist;
9071 int line = 1;
9072
9073
9074 if (objPtr->typePtr == &sourceObjType) {
9075 line = objPtr->internalRep.sourceValue.lineNumber;
9076 }
9077
9078
9079 ScriptTokenListInit(&tokenlist);
9080
9081 JimParserInit(&parser, scriptText, scriptTextLen, line);
9082 while (!parser.eof) {
9083 JimParseScript(&parser);
9084 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
9085 parser.tline);
9086 }
9087
9088
9089 ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
9090
9091
9092 script = Jim_Alloc(sizeof(*script));
9093 memset(script, 0, sizeof(*script));
9094 script->inUse = 1;
9095 if (objPtr->typePtr == &sourceObjType) {
9096 script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -9150,14 +9102,14 @@
9102 script->missing = parser.missing.ch;
9103 script->linenr = parser.missing.line;
9104
9105 ScriptObjAddTokens(interp, script, &tokenlist);
9106
9107
9108 ScriptTokenListFree(&tokenlist);
9109
9110
9111 Jim_FreeIntRep(interp, objPtr);
9112 Jim_SetIntRepPtr(objPtr, script);
9113 objPtr->typePtr = &scriptObjType;
9114 }
9115
@@ -9164,11 +9116,11 @@
9116 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
9117
9118 static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
9119 {
9120 if (objPtr == interp->emptyObj) {
9121
9122 objPtr = interp->nullScriptObj;
9123 }
9124
9125 if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
9126 JimSetScriptFromAny(interp, objPtr);
@@ -9203,17 +9155,17 @@
9155 Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
9156 Jim_Free(cmdPtr->u.proc.staticVars);
9157 }
9158 }
9159 else {
9160
9161 if (cmdPtr->u.native.delProc) {
9162 cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
9163 }
9164 }
9165 if (cmdPtr->prevCmd) {
9166
9167 JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
9168 }
9169 Jim_Free(cmdPtr);
9170 }
9171 }
@@ -9224,46 +9176,46 @@
9176 Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
9177 Jim_Free(val);
9178 }
9179
9180 static const Jim_HashTableType JimVariablesHashTableType = {
9181 JimStringCopyHTHashFunction,
9182 JimStringCopyHTDup,
9183 NULL,
9184 JimStringCopyHTKeyCompare,
9185 JimStringCopyHTKeyDestructor,
9186 JimVariablesHTValDestructor
9187 };
9188
9189 static void JimCommandsHT_ValDestructor(void *interp, void *val)
9190 {
9191 JimDecrCmdRefCount(interp, val);
9192 }
9193
9194 static const Jim_HashTableType JimCommandsHashTableType = {
9195 JimStringCopyHTHashFunction,
9196 JimStringCopyHTDup,
9197 NULL,
9198 JimStringCopyHTKeyCompare,
9199 JimStringCopyHTKeyDestructor,
9200 JimCommandsHT_ValDestructor
9201 };
9202
9203
9204
9205 #ifdef jim_ext_namespace
9206 static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
9207 {
9208 const char *name = Jim_String(nsObj);
9209 if (name[0] == ':' && name[1] == ':') {
9210
9211 while (*++name == ':') {
9212 }
9213 nsObj = Jim_NewStringObj(interp, name, -1);
9214 }
9215 else if (Jim_Length(interp->framePtr->nsObj)) {
9216
9217 nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9218 Jim_AppendStrings(interp, nsObj, "::", name, NULL);
9219 }
9220 return nsObj;
9221 }
@@ -9287,16 +9239,16 @@
9239 static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
9240 {
9241 Jim_Obj *objPtr = interp->emptyObj;
9242
9243 if (name[0] == ':' && name[1] == ':') {
9244
9245 while (*++name == ':') {
9246 }
9247 }
9248 else if (Jim_Length(interp->framePtr->nsObj)) {
9249
9250 objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9251 Jim_AppendStrings(interp, objPtr, "::", name, NULL);
9252 name = Jim_String(objPtr);
9253 }
9254 Jim_IncrRefCount(objPtr);
@@ -9305,11 +9257,11 @@
9257 }
9258
9259 #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
9260
9261 #else
9262
9263 #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
9264 #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
9265
9266 Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
9267 {
@@ -9324,17 +9276,17 @@
9276
9277 Jim_InterpIncrProcEpoch(interp);
9278 }
9279
9280 if (he && interp->local) {
9281
9282 cmd->prevCmd = Jim_GetHashEntryVal(he);
9283 Jim_SetHashVal(&interp->commands, he, cmd);
9284 }
9285 else {
9286 if (he) {
9287
9288 Jim_DeleteHashEntry(&interp->commands, name);
9289 }
9290
9291 Jim_AddHashEntry(&interp->commands, name, cmd);
9292 }
@@ -9345,11 +9297,11 @@
9297 int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
9298 Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
9299 {
9300 Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
9301
9302
9303 memset(cmdPtr, 0, sizeof(*cmdPtr));
9304 cmdPtr->inUse = 1;
9305 cmdPtr->u.native.delProc = delProc;
9306 cmdPtr->u.native.cmdProc = cmdProc;
9307 cmdPtr->u.native.privData = privData;
@@ -9374,11 +9326,11 @@
9326 Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
9327 Jim_Var *varPtr;
9328 int subLen;
9329
9330 objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
9331
9332 subLen = Jim_ListLength(interp, objPtr);
9333 if (subLen == 1 || subLen == 2) {
9334 nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
9335 if (subLen == 1) {
9336 initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9420,19 +9372,19 @@
9372
9373 static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
9374 {
9375 #ifdef jim_ext_namespace
9376 if (cmdPtr->isproc) {
9377
9378 const char *pt = strrchr(cmdname, ':');
9379 if (pt && pt != cmdname && pt[-1] == ':') {
9380 Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
9381 cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
9382 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9383
9384 if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
9385
9386 Jim_InterpIncrProcEpoch(interp);
9387 }
9388 }
9389 }
9390 #endif
@@ -9445,11 +9397,11 @@
9397 int argListLen;
9398 int i;
9399
9400 argListLen = Jim_ListLength(interp, argListObjPtr);
9401
9402
9403 cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
9404 memset(cmdPtr, 0, sizeof(*cmdPtr));
9405 cmdPtr->inUse = 1;
9406 cmdPtr->isproc = 1;
9407 cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9460,24 +9412,24 @@
9412 cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
9413 Jim_IncrRefCount(argListObjPtr);
9414 Jim_IncrRefCount(bodyObjPtr);
9415 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9416
9417
9418 if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
9419 goto err;
9420 }
9421
9422
9423
9424 for (i = 0; i < argListLen; i++) {
9425 Jim_Obj *argPtr;
9426 Jim_Obj *nameObjPtr;
9427 Jim_Obj *defaultObjPtr;
9428 int len;
9429
9430
9431 argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
9432 len = Jim_ListLength(interp, argPtr);
9433 if (len == 0) {
9434 Jim_SetResultString(interp, "argument with no name", -1);
9435 err:
@@ -9488,16 +9440,16 @@
9440 Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
9441 goto err;
9442 }
9443
9444 if (len == 2) {
9445
9446 nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
9447 defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
9448 }
9449 else {
9450
9451 nameObjPtr = argPtr;
9452 defaultObjPtr = NULL;
9453 }
9454
9455
@@ -9558,29 +9510,29 @@
9510 }
9511
9512 fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
9513 fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
9514
9515
9516 he = Jim_FindHashEntry(&interp->commands, fqold);
9517 if (he == NULL) {
9518 Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
9519 }
9520 else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
9521 Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
9522 }
9523 else {
9524
9525 cmdPtr = Jim_GetHashEntryVal(he);
9526 JimIncrCmdRefCount(cmdPtr);
9527 JimUpdateProcNamespace(interp, cmdPtr, fqnew);
9528 Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
9529
9530
9531 Jim_DeleteHashEntry(&interp->commands, fqold);
9532
9533
9534 Jim_InterpIncrProcEpoch(interp);
9535
9536 ret = JIM_OK;
9537 }
9538
@@ -9619,23 +9571,23 @@
9571 objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
9572 #ifdef jim_ext_namespace
9573 || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
9574 #endif
9575 ) {
9576
9577
9578
 
9579 const char *name = Jim_String(objPtr);
9580 Jim_HashEntry *he;
9581
9582 if (name[0] == ':' && name[1] == ':') {
9583 while (*++name == ':') {
9584 }
9585 }
9586 #ifdef jim_ext_namespace
9587 else if (Jim_Length(interp->framePtr->nsObj)) {
9588
9589 Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9590 Jim_AppendStrings(interp, nameObj, "::", name, NULL);
9591 he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
9592 Jim_FreeNewObj(interp, nameObj);
9593 if (he) {
@@ -9642,11 +9594,11 @@
9594 goto found;
9595 }
9596 }
9597 #endif
9598
9599
9600 he = Jim_FindHashEntry(&interp->commands, name);
9601 if (he == NULL) {
9602 if (flags & JIM_ERRMSG) {
9603 Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
9604 }
@@ -9655,11 +9607,11 @@
9607 #ifdef jim_ext_namespace
9608 found:
9609 #endif
9610 cmd = Jim_GetHashEntryVal(he);
9611
9612
9613 Jim_FreeIntRep(interp, objPtr);
9614 objPtr->typePtr = &commandObjType;
9615 objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
9616 objPtr->internalRep.cmdValue.cmdPtr = cmd;
9617 objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9674,11 +9626,11 @@
9626 return cmd;
9627 }
9628
9629
9630
9631 #define JIM_DICT_SUGAR 100
9632
9633 static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
9634
9635 static const Jim_ObjType variableObjType = {
9636 "variable",
@@ -9688,11 +9640,11 @@
9640 JIM_TYPE_REFERENCES,
9641 };
9642
9643 static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
9644 {
9645
9646 if (nameObjPtr->typePtr != &variableObjType) {
9647 int len;
9648 const char *str = Jim_GetString(nameObjPtr, &len);
9649 if (memchr(str, '\0', len)) {
9650 Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9708,18 +9660,18 @@
9660 Jim_CallFrame *framePtr;
9661 Jim_HashEntry *he;
9662 int global;
9663 int len;
9664
9665
9666 if (objPtr->typePtr == &variableObjType) {
9667 framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
9668 if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
9669
9670 return JIM_OK;
9671 }
9672
9673 }
9674 else if (objPtr->typePtr == &dictSubstObjType) {
9675 return JIM_DICT_SUGAR;
9676 }
9677 else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9727,11 +9679,11 @@
9679 }
9680
9681
9682 varName = Jim_GetString(objPtr, &len);
9683
9684
9685 if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
9686 return JIM_DICT_SUGAR;
9687 }
9688
9689 if (varName[0] == ':' && varName[1] == ':') {
@@ -9743,23 +9695,23 @@
9695 else {
9696 global = 0;
9697 framePtr = interp->framePtr;
9698 }
9699
9700
9701 he = Jim_FindHashEntry(&framePtr->vars, varName);
9702 if (he == NULL) {
9703 if (!global && framePtr->staticVars) {
9704
9705 he = Jim_FindHashEntry(framePtr->staticVars, varName);
9706 }
9707 if (he == NULL) {
9708 return JIM_ERR;
9709 }
9710 }
9711
9712
9713 Jim_FreeIntRep(interp, objPtr);
9714 objPtr->typePtr = &variableObjType;
9715 objPtr->internalRep.varValue.callFrameId = framePtr->id;
9716 objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
9717 objPtr->internalRep.varValue.global = global;
@@ -9774,11 +9726,11 @@
9726 {
9727 const char *name;
9728 Jim_CallFrame *framePtr;
9729 int global;
9730
9731
9732 Jim_Var *var = Jim_Alloc(sizeof(*var));
9733
9734 var->objPtr = valObjPtr;
9735 Jim_IncrRefCount(valObjPtr);
9736 var->linkFramePtr = NULL;
@@ -9793,14 +9745,14 @@
9745 else {
9746 framePtr = interp->framePtr;
9747 global = 0;
9748 }
9749
9750
9751 Jim_AddHashEntry(&framePtr->vars, name, var);
9752
9753
9754 Jim_FreeIntRep(interp, nameObjPtr);
9755 nameObjPtr->typePtr = &variableObjType;
9756 nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
9757 nameObjPtr->internalRep.varValue.varPtr = var;
9758 nameObjPtr->internalRep.varValue.global = global;
@@ -9830,11 +9782,11 @@
9782 if (var->linkFramePtr == NULL) {
9783 Jim_IncrRefCount(valObjPtr);
9784 Jim_DecrRefCount(interp, var->objPtr);
9785 var->objPtr = valObjPtr;
9786 }
9787 else {
9788 Jim_CallFrame *savedCallFrame;
9789
9790 savedCallFrame = interp->framePtr;
9791 interp->framePtr = var->linkFramePtr;
9792 err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9891,14 +9843,14 @@
9843 const char *varName;
9844 const char *targetName;
9845 Jim_CallFrame *framePtr;
9846 Jim_Var *varPtr;
9847
9848
9849 switch (SetVariableFromAny(interp, nameObjPtr)) {
9850 case JIM_DICT_SUGAR:
9851
9852 Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
9853 return JIM_ERR;
9854
9855 case JIM_OK:
9856 varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9906,23 +9858,23 @@
9858 if (varPtr->linkFramePtr == NULL) {
9859 Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
9860 return JIM_ERR;
9861 }
9862
9863
9864 varPtr->linkFramePtr = NULL;
9865 break;
9866 }
9867
9868
9869
9870 varName = Jim_String(nameObjPtr);
9871
9872 if (varName[0] == ':' && varName[1] == ':') {
9873 while (*++varName == ':') {
9874 }
9875
9876 framePtr = interp->topFramePtr;
9877 }
9878 else {
9879 framePtr = interp->framePtr;
9880 }
@@ -9942,15 +9894,15 @@
9894 nameObjPtr);
9895 Jim_DecrRefCount(interp, targetNameObjPtr);
9896 return JIM_ERR;
9897 }
9898
9899
9900 if (framePtr == targetCallFrame) {
9901 Jim_Obj *objPtr = targetNameObjPtr;
9902
9903
9904 while (1) {
9905 if (strcmp(Jim_String(objPtr), varName) == 0) {
9906 Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
9907 Jim_DecrRefCount(interp, targetNameObjPtr);
9908 return JIM_ERR;
@@ -9962,13 +9914,13 @@
9914 break;
9915 objPtr = varPtr->objPtr;
9916 }
9917 }
9918
9919
9920 Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
9921
9922 nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
9923 Jim_DecrRefCount(interp, targetNameObjPtr);
9924 return JIM_OK;
9925 }
9926
@@ -9982,26 +9934,26 @@
9934 return varPtr->objPtr;
9935 }
9936 else {
9937 Jim_Obj *objPtr;
9938
9939
9940 Jim_CallFrame *savedCallFrame = interp->framePtr;
9941
9942 interp->framePtr = varPtr->linkFramePtr;
9943 objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
9944 interp->framePtr = savedCallFrame;
9945 if (objPtr) {
9946 return objPtr;
9947 }
9948
9949 }
9950 }
9951 break;
9952
9953 case JIM_DICT_SUGAR:
9954
9955 return JimDictSugarGet(interp, nameObjPtr, flags);
9956 }
9957 if (flags & JIM_ERRMSG) {
9958 Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
9959 }
@@ -10051,17 +10003,17 @@
10003 int retval;
10004 Jim_CallFrame *framePtr;
10005
10006 retval = SetVariableFromAny(interp, nameObjPtr);
10007 if (retval == JIM_DICT_SUGAR) {
10008
10009 return JimDictSugarSet(interp, nameObjPtr, NULL);
10010 }
10011 else if (retval == JIM_OK) {
10012 varPtr = nameObjPtr->internalRep.varValue.varPtr;
10013
10014
10015 if (varPtr->linkFramePtr) {
10016 framePtr = interp->framePtr;
10017 interp->framePtr = varPtr->linkFramePtr;
10018 retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
10019 interp->framePtr = framePtr;
@@ -10076,11 +10028,11 @@
10028 framePtr = interp->framePtr;
10029 }
10030
10031 retval = Jim_DeleteHashEntry(&framePtr->vars, name);
10032 if (retval == JIM_OK) {
10033
10034 framePtr->id = interp->callFrameEpoch++;
10035 }
10036 }
10037 }
10038 if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -10109,11 +10061,11 @@
10061 keyLen = (str + len) - p;
10062 if (str[len - 1] == ')') {
10063 keyLen--;
10064 }
10065
10066
10067 keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
10068
10069 Jim_IncrRefCount(varObjPtr);
10070 Jim_IncrRefCount(keyObjPtr);
10071 *varPtrPtr = varObjPtr;
@@ -10128,23 +10080,23 @@
10080
10081 err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
10082 &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
10083
10084 if (err == JIM_OK) {
10085
10086 Jim_SetEmptyResult(interp);
10087 }
10088 else {
10089 if (!valObjPtr) {
10090
10091 if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
10092 Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
10093 objPtr);
10094 return err;
10095 }
10096 }
10097
10098 Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
10099 (valObjPtr ? "set" : "unset"), objPtr);
10100 }
10101 return err;
10102 }
@@ -10166,11 +10118,11 @@
10118 Jim_SetResultFormatted(interp,
10119 "can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
10120 ret < 0 ? "variable isn't" : "no such element in");
10121 }
10122 else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
10123
10124 Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
10125 }
10126
10127 return resObjPtr;
10128 }
@@ -10208,11 +10160,11 @@
10160 {
10161 if (objPtr->typePtr != &dictSubstObjType) {
10162 Jim_Obj *varObjPtr, *keyObjPtr;
10163
10164 if (objPtr->typePtr == &interpolatedObjType) {
10165
10166
10167 varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
10168 keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
10169
10170 Jim_IncrRefCount(varObjPtr);
@@ -10253,11 +10205,11 @@
10205 static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
10206 {
10207 Jim_Obj *resultObjPtr;
10208
10209 if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
10210
10211 resultObjPtr->refCount--;
10212 return resultObjPtr;
10213 }
10214 return NULL;
10215 }
@@ -10297,11 +10249,11 @@
10249 return cf;
10250 }
10251
10252 static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
10253 {
10254
10255 if (localCommands) {
10256 Jim_Obj *cmdNameObj;
10257
10258 while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
10259 Jim_HashEntry *he;
@@ -10316,20 +10268,20 @@
10268 Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
10269 if (cmd->prevCmd) {
10270 Jim_Cmd *prevCmd = cmd->prevCmd;
10271 cmd->prevCmd = NULL;
10272
10273
10274 JimDecrCmdRefCount(interp, cmd);
10275
10276
10277 Jim_SetHashVal(ht, he, prevCmd);
10278 }
10279 else {
10280 Jim_DeleteHashEntry(ht, fqname);
10281 Jim_InterpIncrProcEpoch(interp);
10282 }
 
10283 }
10284 Jim_DecrRefCount(interp, cmdNameObj);
10285 JimFreeQualifiedName(interp, fqObjName);
10286 }
10287 Jim_FreeStack(localCommands);
@@ -10337,12 +10289,12 @@
10289 }
10290 return JIM_OK;
10291 }
10292
10293
10294 #define JIM_FCF_FULL 0
10295 #define JIM_FCF_REUSE 1
10296 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
10297 {
10298 JimDeleteLocalProcs(interp, cf->localCommands);
10299
10300 if (cf->procArgsObjPtr)
@@ -10375,10 +10327,263 @@
10327 cf->next = interp->freeFramesList;
10328 interp->freeFramesList = cf;
10329 }
10330
10331
10332 #ifdef JIM_REFERENCES
10333
10334 static void JimReferencesHTValDestructor(void *interp, void *val)
10335 {
10336 Jim_Reference *refPtr = (void *)val;
10337
10338 Jim_DecrRefCount(interp, refPtr->objPtr);
10339 if (refPtr->finalizerCmdNamePtr != NULL) {
10340 Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10341 }
10342 Jim_Free(val);
10343 }
10344
10345 static unsigned int JimReferencesHTHashFunction(const void *key)
10346 {
10347
10348 const unsigned long *widePtr = key;
10349 unsigned int intValue = (unsigned int)*widePtr;
10350
10351 return Jim_IntHashFunction(intValue);
10352 }
10353
10354 static void *JimReferencesHTKeyDup(void *privdata, const void *key)
10355 {
10356 void *copy = Jim_Alloc(sizeof(unsigned long));
10357
10358 JIM_NOTUSED(privdata);
10359
10360 memcpy(copy, key, sizeof(unsigned long));
10361 return copy;
10362 }
10363
10364 static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2)
10365 {
10366 JIM_NOTUSED(privdata);
10367
10368 return memcmp(key1, key2, sizeof(unsigned long)) == 0;
10369 }
10370
10371 static void JimReferencesHTKeyDestructor(void *privdata, void *key)
10372 {
10373 JIM_NOTUSED(privdata);
10374
10375 Jim_Free(key);
10376 }
10377
10378 static const Jim_HashTableType JimReferencesHashTableType = {
10379 JimReferencesHTHashFunction,
10380 JimReferencesHTKeyDup,
10381 NULL,
10382 JimReferencesHTKeyCompare,
10383 JimReferencesHTKeyDestructor,
10384 JimReferencesHTValDestructor
10385 };
10386
10387
10388
10389 #define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
10390
10391 static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
10392 {
10393 const char *fmt = "<reference.<%s>.%020lu>";
10394
10395 sprintf(buf, fmt, refPtr->tag, id);
10396 return JIM_REFERENCE_SPACE;
10397 }
10398
10399 static void UpdateStringOfReference(struct Jim_Obj *objPtr);
10400
10401 static const Jim_ObjType referenceObjType = {
10402 "reference",
10403 NULL,
10404 NULL,
10405 UpdateStringOfReference,
10406 JIM_TYPE_REFERENCES,
10407 };
10408
10409 static void UpdateStringOfReference(struct Jim_Obj *objPtr)
10410 {
10411 char buf[JIM_REFERENCE_SPACE + 1];
10412
10413 JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id);
10414 JimSetStringBytes(objPtr, buf);
10415 }
10416
10417 static int isrefchar(int c)
10418 {
10419 return (c == '_' || isalnum(c));
10420 }
10421
10422 static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
10423 {
10424 unsigned long value;
10425 int i, len;
10426 const char *str, *start, *end;
10427 char refId[21];
10428 Jim_Reference *refPtr;
10429 Jim_HashEntry *he;
10430 char *endptr;
10431
10432
10433 str = Jim_GetString(objPtr, &len);
10434
10435 if (len < JIM_REFERENCE_SPACE)
10436 goto badformat;
10437
10438 start = str;
10439 end = str + len - 1;
10440 while (*start == ' ')
10441 start++;
10442 while (*end == ' ' && end > start)
10443 end--;
10444 if (end - start + 1 != JIM_REFERENCE_SPACE)
10445 goto badformat;
10446
10447 if (memcmp(start, "<reference.<", 12) != 0)
10448 goto badformat;
10449 if (start[12 + JIM_REFERENCE_TAGLEN] != '>' || end[0] != '>')
10450 goto badformat;
10451
10452 for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10453 if (!isrefchar(start[12 + i]))
10454 goto badformat;
10455 }
10456
10457 memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
10458 refId[20] = '\0';
10459
10460 value = strtoul(refId, &endptr, 10);
10461 if (JimCheckConversion(refId, endptr) != JIM_OK)
10462 goto badformat;
10463
10464 he = Jim_FindHashEntry(&interp->references, &value);
10465 if (he == NULL) {
10466 Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
10467 return JIM_ERR;
10468 }
10469 refPtr = Jim_GetHashEntryVal(he);
10470
10471 Jim_FreeIntRep(interp, objPtr);
10472 objPtr->typePtr = &referenceObjType;
10473 objPtr->internalRep.refValue.id = value;
10474 objPtr->internalRep.refValue.refPtr = refPtr;
10475 return JIM_OK;
10476
10477 badformat:
10478 Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
10479 return JIM_ERR;
10480 }
10481
10482 Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
10483 {
10484 struct Jim_Reference *refPtr;
10485 unsigned long id;
10486 Jim_Obj *refObjPtr;
10487 const char *tag;
10488 int tagLen, i;
10489
10490
10491 Jim_CollectIfNeeded(interp);
10492
10493 refPtr = Jim_Alloc(sizeof(*refPtr));
10494 refPtr->objPtr = objPtr;
10495 Jim_IncrRefCount(objPtr);
10496 refPtr->finalizerCmdNamePtr = cmdNamePtr;
10497 if (cmdNamePtr)
10498 Jim_IncrRefCount(cmdNamePtr);
10499 id = interp->referenceNextId++;
10500 Jim_AddHashEntry(&interp->references, &id, refPtr);
10501 refObjPtr = Jim_NewObj(interp);
10502 refObjPtr->typePtr = &referenceObjType;
10503 refObjPtr->bytes = NULL;
10504 refObjPtr->internalRep.refValue.id = id;
10505 refObjPtr->internalRep.refValue.refPtr = refPtr;
10506 interp->referenceNextId++;
10507 tag = Jim_GetString(tagPtr, &tagLen);
10508 if (tagLen > JIM_REFERENCE_TAGLEN)
10509 tagLen = JIM_REFERENCE_TAGLEN;
10510 for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10511 if (i < tagLen && isrefchar(tag[i]))
10512 refPtr->tag[i] = tag[i];
10513 else
10514 refPtr->tag[i] = '_';
10515 }
10516 refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0';
10517 return refObjPtr;
10518 }
10519
10520 Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr)
10521 {
10522 if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR)
10523 return NULL;
10524 return objPtr->internalRep.refValue.refPtr;
10525 }
10526
10527 int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr)
10528 {
10529 Jim_Reference *refPtr;
10530
10531 if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10532 return JIM_ERR;
10533 Jim_IncrRefCount(cmdNamePtr);
10534 if (refPtr->finalizerCmdNamePtr)
10535 Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10536 refPtr->finalizerCmdNamePtr = cmdNamePtr;
10537 return JIM_OK;
10538 }
10539
10540 int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr)
10541 {
10542 Jim_Reference *refPtr;
10543
10544 if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10545 return JIM_ERR;
10546 *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr;
10547 return JIM_OK;
10548 }
10549
10550
10551
10552 static const Jim_HashTableType JimRefMarkHashTableType = {
10553 JimReferencesHTHashFunction,
10554 JimReferencesHTKeyDup,
10555 NULL,
10556 JimReferencesHTKeyCompare,
10557 JimReferencesHTKeyDestructor,
10558 NULL
10559 };
10560
10561
10562 int Jim_Collect(Jim_Interp *interp)
10563 {
10564 int collected = 0;
10565 return collected;
10566 }
10567
10568 #define JIM_COLLECT_ID_PERIOD 5000
10569 #define JIM_COLLECT_TIME_PERIOD 300
10570
10571 void Jim_CollectIfNeeded(Jim_Interp *interp)
10572 {
10573 unsigned long elapsedId;
10574 int elapsedTime;
10575
10576 elapsedId = interp->referenceNextId - interp->lastCollectId;
10577 elapsedTime = time(NULL) - interp->lastCollectTime;
10578
10579
10580 if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) {
10581 Jim_Collect(interp);
10582 }
10583 }
10584 #endif
10585
10586 int Jim_IsBigEndian(void)
10587 {
10588 union {
10589 unsigned short s;
@@ -10425,11 +10630,11 @@
10630 Jim_IncrRefCount(i->nullScriptObj);
10631 Jim_IncrRefCount(i->errorProc);
10632 Jim_IncrRefCount(i->trueObj);
10633 Jim_IncrRefCount(i->falseObj);
10634
10635
10636 Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
10637 Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
10638
10639 Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim");
10640 Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
@@ -10447,11 +10652,11 @@
10652 {
10653 Jim_CallFrame *cf, *cfx;
10654
10655 Jim_Obj *objPtr, *nextObjPtr;
10656
10657
10658 for (cf = i->framePtr; cf; cf = cfx) {
10659 cfx = cf->parent;
10660 JimFreeCallFrame(i, cf, JIM_FCF_FULL);
10661 }
10662
@@ -10500,27 +10705,27 @@
10705 printf("-------------------------------------\n\n");
10706 JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
10707 }
10708 #endif
10709
10710
10711 objPtr = i->freeList;
10712 while (objPtr) {
10713 nextObjPtr = objPtr->nextObjPtr;
10714 Jim_Free(objPtr);
10715 objPtr = nextObjPtr;
10716 }
10717
10718
10719 for (cf = i->freeFramesList; cf; cf = cfx) {
10720 cfx = cf->next;
10721 if (cf->vars.table)
10722 Jim_FreeHashTable(&cf->vars);
10723 Jim_Free(cf);
10724 }
10725
10726
10727 Jim_Free(i);
10728 }
10729
10730 Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
10731 {
@@ -10541,25 +10746,25 @@
10746 else {
10747 if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
10748 level = -1;
10749 }
10750 else {
10751
10752 level = interp->framePtr->level - level;
10753 }
10754 }
10755 }
10756 else {
10757 str = "1";
10758 level = interp->framePtr->level - 1;
10759 }
10760
10761 if (level == 0) {
10762 return interp->topFramePtr;
10763 }
10764 if (level > 0) {
10765
10766 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10767 if (framePtr->level == level) {
10768 return framePtr;
10769 }
10770 }
@@ -10574,19 +10779,19 @@
10779 long level;
10780 Jim_CallFrame *framePtr;
10781
10782 if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
10783 if (level <= 0) {
10784
10785 level = interp->framePtr->level + level;
10786 }
10787
10788 if (level == 0) {
10789 return interp->topFramePtr;
10790 }
10791
10792
10793 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10794 if (framePtr->level == level) {
10795 return framePtr;
10796 }
10797 }
@@ -10605,11 +10810,11 @@
10810
10811 static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
10812 {
10813 int len;
10814
10815
10816 Jim_IncrRefCount(stackTraceObj);
10817 Jim_DecrRefCount(interp, interp->stackTrace);
10818 interp->stackTrace = stackTraceObj;
10819 interp->errorFlag = 1;
10820
@@ -10626,32 +10831,32 @@
10831 {
10832 if (strcmp(procname, "unknown") == 0) {
10833 procname = "";
10834 }
10835 if (!*procname && !Jim_Length(fileNameObj)) {
10836
10837 return;
10838 }
10839
10840 if (Jim_IsShared(interp->stackTrace)) {
10841 Jim_DecrRefCount(interp, interp->stackTrace);
10842 interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
10843 Jim_IncrRefCount(interp->stackTrace);
10844 }
10845
10846
10847 if (!*procname && Jim_Length(fileNameObj)) {
10848
10849 int len = Jim_ListLength(interp, interp->stackTrace);
10850
10851 if (len >= 3) {
10852 Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
10853 if (Jim_Length(objPtr)) {
10854
10855 objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
10856 if (Jim_Length(objPtr) == 0) {
10857
10858 ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
10859 ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
10860 return;
10861 }
10862 }
@@ -10753,18 +10958,18 @@
10958 {
10959 jim_wide wideValue;
10960 const char *str;
10961
10962 if (objPtr->typePtr == &coercedDoubleObjType) {
10963
10964 objPtr->typePtr = &intObjType;
10965 return JIM_OK;
10966 }
10967
10968
10969 str = Jim_String(objPtr);
10970
10971 if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
10972 if (flags & JIM_ERRMSG) {
10973 Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
10974 }
10975 return JIM_ERR;
@@ -10771,11 +10976,11 @@
10976 }
10977 if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
10978 Jim_SetResultString(interp, "Integer value too big to be represented", -1);
10979 return JIM_ERR;
10980 }
10981
10982 Jim_FreeIntRep(interp, objPtr);
10983 objPtr->typePtr = &intObjType;
10984 objPtr->internalRep.wideValue = wideValue;
10985 return JIM_OK;
10986 }
@@ -10870,17 +11075,17 @@
11075 {
11076 char buf[JIM_DOUBLE_SPACE + 1];
11077 int i;
11078 int len = sprintf(buf, "%.12g", value);
11079
11080
11081 for (i = 0; i < len; i++) {
11082 if (buf[i] == '.' || buf[i] == 'e') {
11083 #if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
11084 char *e = strchr(buf, 'e');
11085 if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
11086
11087 e += 2;
11088 memmove(e, e + 1, len - (e - buf));
11089 }
11090 #endif
11091 break;
@@ -10902,38 +11107,38 @@
11107 const char *str;
11108
11109 str = Jim_String(objPtr);
11110
11111 #ifdef HAVE_LONG_LONG
11112
11113 #define MIN_INT_IN_DOUBLE -(1LL << 53)
11114 #define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
11115
11116 if (objPtr->typePtr == &intObjType
11117 && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
11118 && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
11119
11120
11121 objPtr->typePtr = &coercedDoubleObjType;
11122 return JIM_OK;
11123 }
11124 else
11125 #endif
11126 if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
11127
11128 Jim_FreeIntRep(interp, objPtr);
11129 objPtr->typePtr = &coercedDoubleObjType;
11130 objPtr->internalRep.wideValue = wideValue;
11131 return JIM_OK;
11132 }
11133 else {
11134
11135 if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
11136 Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
11137 return JIM_ERR;
11138 }
11139
11140 Jim_FreeIntRep(interp, objPtr);
11141 }
11142 objPtr->typePtr = &doubleObjType;
11143 objPtr->internalRep.doubleValue = doubleValue;
11144 return JIM_OK;
@@ -10966,50 +11171,10 @@
11171 objPtr->bytes = NULL;
11172 objPtr->internalRep.doubleValue = doubleValue;
11173 return objPtr;
11174 }
11175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11176 static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
11177 static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
11178 static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
11179 static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
11180 static void UpdateStringOfList(struct Jim_Obj *objPtr);
@@ -11056,11 +11221,11 @@
11221 #define JIM_ELESTR_QUOTE 2
11222 static unsigned char ListElementQuotingType(const char *s, int len)
11223 {
11224 int i, level, blevel, trySimple = 1;
11225
11226
11227 if (len == 0)
11228 return JIM_ELESTR_BRACE;
11229 if (s[0] == '"' || s[0] == '{') {
11230 trySimple = 0;
11231 goto testbrace;
@@ -11078,20 +11243,20 @@
11243 case '\n':
11244 case '\t':
11245 case '\f':
11246 case '\v':
11247 trySimple = 0;
11248
11249 case '{':
11250 case '}':
11251 goto testbrace;
11252 }
11253 }
11254 return JIM_ELESTR_SIMPLE;
11255
11256 testbrace:
11257
11258 if (s[len - 1] == '\\')
11259 return JIM_ELESTR_QUOTE;
11260 level = 0;
11261 blevel = 0;
11262 for (i = 0; i < len; i++) {
@@ -11207,11 +11372,11 @@
11372 int i, bufLen, realLength;
11373 const char *strRep;
11374 char *p;
11375 unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
11376
11377
11378 if (objc > STATIC_QUOTING_LEN) {
11379 quotingType = Jim_Alloc(objc);
11380 }
11381 else {
11382 quotingType = staticQuoting;
@@ -11226,25 +11391,25 @@
11391 case JIM_ELESTR_SIMPLE:
11392 if (i != 0 || strRep[0] != '#') {
11393 bufLen += len;
11394 break;
11395 }
11396
11397 quotingType[i] = JIM_ELESTR_BRACE;
11398
11399 case JIM_ELESTR_BRACE:
11400 bufLen += len + 2;
11401 break;
11402 case JIM_ELESTR_QUOTE:
11403 bufLen += len * 2;
11404 break;
11405 }
11406 bufLen++;
11407 }
11408 bufLen++;
11409
11410
11411 p = objPtr->bytes = Jim_Alloc(bufLen + 1);
11412 realLength = 0;
11413 for (i = 0; i < objc; i++) {
11414 int len, qlen;
11415
@@ -11271,17 +11436,17 @@
11436 qlen = BackslashQuoteString(strRep, len, p);
11437 p += qlen;
11438 realLength += qlen;
11439 break;
11440 }
11441
11442 if (i + 1 != objc) {
11443 *p++ = ' ';
11444 realLength++;
11445 }
11446 }
11447 *p = '\0';
11448 objPtr->length = realLength;
11449
11450 if (quotingType != staticQuoting) {
11451 Jim_Free(quotingType);
11452 }
@@ -11312,21 +11477,21 @@
11477 listObjPtrPtr = JimDictPairs(objPtr, &len);
11478 for (i = 0; i < len; i++) {
11479 Jim_IncrRefCount(listObjPtrPtr[i]);
11480 }
11481
11482
11483 Jim_FreeIntRep(interp, objPtr);
11484 objPtr->typePtr = &listObjType;
11485 objPtr->internalRep.listValue.len = len;
11486 objPtr->internalRep.listValue.maxLen = len;
11487 objPtr->internalRep.listValue.ele = listObjPtrPtr;
11488
11489 return JIM_OK;
11490 }
11491
11492
11493 if (objPtr->typePtr == &sourceObjType) {
11494 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
11495 linenr = objPtr->internalRep.sourceValue.lineNumber;
11496 }
11497 else {
@@ -11333,20 +11498,20 @@
11498 fileNameObj = interp->emptyObj;
11499 linenr = 1;
11500 }
11501 Jim_IncrRefCount(fileNameObj);
11502
11503
11504 str = Jim_GetString(objPtr, &strLen);
11505
11506 Jim_FreeIntRep(interp, objPtr);
11507 objPtr->typePtr = &listObjType;
11508 objPtr->internalRep.listValue.len = 0;
11509 objPtr->internalRep.listValue.maxLen = 0;
11510 objPtr->internalRep.listValue.ele = NULL;
11511
11512
11513 if (strLen) {
11514 JimParserInit(&parser, str, strLen, linenr);
11515 while (!parser.eof) {
11516 Jim_Obj *elementPtr;
11517
@@ -11476,11 +11641,11 @@
11641 Jim_Obj *compare_script;
11642 int rc;
11643
11644 jim_wide ret = 0;
11645
11646
11647 compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
11648 Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
11649 Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
11650
11651 rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11498,23 +11663,23 @@
11663 int dst = 0;
11664 Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
11665
11666 for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
11667 if (comp(&ele[dst], &ele[src]) == 0) {
11668
11669 Jim_DecrRefCount(sort_info->interp, ele[dst]);
11670 }
11671 else {
11672
11673 dst++;
11674 }
11675 ele[dst] = ele[src];
11676 }
11677
11678 ele[++dst] = ele[src];
11679
11680
11681 listObjPtr->internalRep.listValue.len = dst;
11682 }
11683
11684
11685 static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11528,11 +11693,11 @@
11693 int rc;
11694
11695 JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
11696 SetListFromAny(interp, listObjPtr);
11697
11698
11699 prev_info = sort_info;
11700 sort_info = info;
11701
11702 vector = listObjPtr->internalRep.listValue.ele;
11703 len = listObjPtr->internalRep.listValue.len;
@@ -11551,17 +11716,17 @@
11716 break;
11717 case JIM_LSORT_COMMAND:
11718 fn = ListSortCommand;
11719 break;
11720 default:
11721 fn = NULL;
11722 JimPanic((1, "ListSort called with invalid sort type"));
11723 return -1;
11724 }
11725
11726 if (info->indexed) {
11727
11728 info->subfn = fn;
11729 fn = ListSortIndexHelper;
11730 }
11731
11732 if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11585,11 +11750,11 @@
11750 int i;
11751 Jim_Obj **point;
11752
11753 if (requiredLen > listPtr->internalRep.listValue.maxLen) {
11754 if (requiredLen < 2) {
11755
11756 requiredLen = 4;
11757 }
11758 else {
11759 requiredLen *= 2;
11760 }
@@ -11771,34 +11936,34 @@
11936 for (i = 0; i < objc; i++)
11937 ListAppendList(objPtr, objv[i]);
11938 return objPtr;
11939 }
11940 else {
11941
11942 int len = 0, objLen;
11943 char *bytes, *p;
11944
11945
11946 for (i = 0; i < objc; i++) {
11947 len += Jim_Length(objv[i]);
11948 }
11949 if (objc)
11950 len += objc - 1;
11951
11952 p = bytes = Jim_Alloc(len + 1);
11953 for (i = 0; i < objc; i++) {
11954 const char *s = Jim_GetString(objv[i], &objLen);
11955
11956
11957 while (objLen && isspace(UCHAR(*s))) {
11958 s++;
11959 objLen--;
11960 len--;
11961 }
11962
11963 while (objLen && isspace(UCHAR(s[objLen - 1]))) {
11964
11965 if (objLen > 1 && s[objLen - 2] == '\\') {
11966 break;
11967 }
11968 objLen--;
11969 len--;
@@ -11825,11 +11990,11 @@
11990 int len, rangeLen;
11991
11992 if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
11993 Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
11994 return NULL;
11995 len = Jim_ListLength(interp, listObjPtr);
11996 first = JimRelToAbsIndex(len, first);
11997 last = JimRelToAbsIndex(len, last);
11998 JimRelToAbsRange(len, &first, &last, &rangeLen);
11999 if (first == 0 && last == len) {
12000 return listObjPtr;
@@ -11865,16 +12030,16 @@
12030 {
12031 Jim_DecrRefCount(interp, (Jim_Obj *)val);
12032 }
12033
12034 static const Jim_HashTableType JimDictHashTableType = {
12035 JimObjectHTHashFunction,
12036 JimObjectHTKeyValDup,
12037 JimObjectHTKeyValDup,
12038 JimObjectHTKeyCompare,
12039 JimObjectHTKeyValDestructor,
12040 JimObjectHTKeyValDestructor
12041 };
12042
12043 static const Jim_ObjType dictObjType = {
12044 "dict",
12045 FreeDictInternalRep,
@@ -11895,17 +12060,17 @@
12060 {
12061 Jim_HashTable *ht, *dupHt;
12062 Jim_HashTableIterator htiter;
12063 Jim_HashEntry *he;
12064
12065
12066 ht = srcPtr->internalRep.ptr;
12067 dupHt = Jim_Alloc(sizeof(*dupHt));
12068 Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
12069 if (ht->size != 0)
12070 Jim_ExpandHashTable(dupHt, ht->size);
12071
12072 JimInitHashTableIterator(ht, &htiter);
12073 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
12074 Jim_AddHashEntry(dupHt, he->key, he->u.val);
12075 }
12076
@@ -11921,11 +12086,11 @@
12086 Jim_Obj **objv;
12087 int i;
12088
12089 ht = dictPtr->internalRep.ptr;
12090
12091
12092 objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
12093 JimInitHashTableIterator(ht, &htiter);
12094 i = 0;
12095 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
12096 objv[i++] = Jim_GetHashEntryKey(he);
@@ -11935,15 +12100,15 @@
12100 return objv;
12101 }
12102
12103 static void UpdateStringOfDict(struct Jim_Obj *objPtr)
12104 {
12105
12106 int len;
12107 Jim_Obj **objv = JimDictPairs(objPtr, &len);
12108
12109
12110 JimMakeListStringRep(objPtr, objv, len);
12111
12112 Jim_Free(objv);
12113 }
12114
@@ -11957,18 +12122,18 @@
12122
12123 if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
12124 Jim_String(objPtr);
12125 }
12126
12127
12128 listlen = Jim_ListLength(interp, objPtr);
12129 if (listlen % 2) {
12130 Jim_SetResultString(interp, "missing value to go with key", -1);
12131 return JIM_ERR;
12132 }
12133 else {
12134
12135 Jim_HashTable *ht;
12136 int i;
12137
12138 ht = Jim_Alloc(sizeof(*ht));
12139 Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -11993,11 +12158,11 @@
12158 static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
12159 Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
12160 {
12161 Jim_HashTable *ht = objPtr->internalRep.ptr;
12162
12163 if (valueObjPtr == NULL) {
12164 return Jim_DeleteHashEntry(ht, keyObjPtr);
12165 }
12166 Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
12167 return JIM_OK;
12168 }
@@ -12093,11 +12258,11 @@
12258 int shared, i;
12259
12260 varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
12261 if (objPtr == NULL) {
12262 if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
12263
12264 return JIM_ERR;
12265 }
12266 varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
12267 if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
12268 Jim_FreeNewObj(interp, varObjPtr);
@@ -12107,26 +12272,26 @@
12272 if ((shared = Jim_IsShared(objPtr)))
12273 varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
12274 for (i = 0; i < keyc; i++) {
12275 dictObjPtr = objPtr;
12276
12277
12278 if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
12279 goto err;
12280 }
12281
12282 if (i == keyc - 1) {
12283
12284 if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
12285 if (newObjPtr || (flags & JIM_MUSTEXIST)) {
12286 goto err;
12287 }
12288 }
12289 break;
12290 }
12291
12292
12293 Jim_InvalidateStringRep(dictObjPtr);
12294 if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
12295 newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
12296 if (Jim_IsShared(objPtr)) {
12297 objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12139,11 +12304,11 @@
12304 }
12305 objPtr = Jim_NewDictObj(interp, NULL, 0);
12306 DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
12307 }
12308 }
12309
12310 Jim_InvalidateStringRep(objPtr);
12311 Jim_InvalidateStringRep(varObjPtr);
12312 if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
12313 goto err;
12314 }
@@ -12176,11 +12341,11 @@
12341 char buf[JIM_INTEGER_SPACE + 1];
12342 if (objPtr->internalRep.intValue >= 0) {
12343 sprintf(buf, "%d", objPtr->internalRep.intValue);
12344 }
12345 else {
12346
12347 sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
12348 }
12349 JimSetStringBytes(objPtr, buf);
12350 }
12351 }
@@ -12189,14 +12354,14 @@
12354 {
12355 int idx, end = 0;
12356 const char *str;
12357 char *endptr;
12358
12359
12360 str = Jim_String(objPtr);
12361
12362
12363 if (strncmp(str, "end", 3) == 0) {
12364 end = 1;
12365 str += 3;
12366 idx = 0;
12367 }
@@ -12207,21 +12372,21 @@
12372 goto badindex;
12373 }
12374 str = endptr;
12375 }
12376
12377
12378 if (*str == '+' || *str == '-') {
12379 int sign = (*str == '+' ? 1 : -1);
12380
12381 idx += sign * jim_strtol(++str, &endptr);
12382 if (str == endptr || *endptr) {
12383 goto badindex;
12384 }
12385 str = endptr;
12386 }
12387
12388 while (isspace(UCHAR(*str))) {
12389 str++;
12390 }
12391 if (*str) {
12392 goto badindex;
@@ -12229,19 +12394,19 @@
12394 if (end) {
12395 if (idx > 0) {
12396 idx = INT_MAX;
12397 }
12398 else {
12399
12400 idx--;
12401 }
12402 }
12403 else if (idx < 0) {
12404 idx = -INT_MAX;
12405 }
12406
12407
12408 Jim_FreeIntRep(interp, objPtr);
12409 objPtr->typePtr = &indexObjType;
12410 objPtr->internalRep.intValue = idx;
12411 return JIM_OK;
12412
@@ -12251,11 +12416,11 @@
12416 return JIM_ERR;
12417 }
12418
12419 int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
12420 {
12421
12422 if (objPtr->typePtr == &intObjType) {
12423 jim_wide val = JimWideValue(objPtr);
12424
12425 if (val < 0)
12426 *indexPtr = -INT_MAX;
@@ -12308,18 +12473,18 @@
12473 static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
12474 {
12475 int returnCode;
12476 jim_wide wideValue;
12477
12478
12479 if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
12480 returnCode = (int)wideValue;
12481 else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
12482 Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
12483 return JIM_ERR;
12484 }
12485
12486 Jim_FreeIntRep(interp, objPtr);
12487 objPtr->typePtr = &returnCodeObjType;
12488 objPtr->internalRep.intValue = returnCode;
12489 return JIM_OK;
12490 }
@@ -12333,20 +12498,19 @@
12498 }
12499
12500 static int JimParseExprOperator(struct JimParserCtx *pc);
12501 static int JimParseExprNumber(struct JimParserCtx *pc);
12502 static int JimParseExprIrrational(struct JimParserCtx *pc);
 
12503
12504
12505
12506
12507 enum
12508 {
12509
12510
12511 JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
12512 JIM_EXPROP_DIV,
12513 JIM_EXPROP_MOD,
12514 JIM_EXPROP_SUB,
12515 JIM_EXPROP_ADD,
12516 JIM_EXPROP_LSHIFT,
@@ -12357,67 +12521,66 @@
12521 JIM_EXPROP_GT,
12522 JIM_EXPROP_LTE,
12523 JIM_EXPROP_GTE,
12524 JIM_EXPROP_NUMEQ,
12525 JIM_EXPROP_NUMNE,
12526 JIM_EXPROP_BITAND,
12527 JIM_EXPROP_BITXOR,
12528 JIM_EXPROP_BITOR,
12529
12530
12531 JIM_EXPROP_LOGICAND,
12532 JIM_EXPROP_LOGICAND_LEFT,
12533 JIM_EXPROP_LOGICAND_RIGHT,
12534
12535
12536 JIM_EXPROP_LOGICOR,
12537 JIM_EXPROP_LOGICOR_LEFT,
12538 JIM_EXPROP_LOGICOR_RIGHT,
12539
12540
12541
12542 JIM_EXPROP_TERNARY,
12543 JIM_EXPROP_TERNARY_LEFT,
12544 JIM_EXPROP_TERNARY_RIGHT,
12545
12546
12547 JIM_EXPROP_COLON,
12548 JIM_EXPROP_COLON_LEFT,
12549 JIM_EXPROP_COLON_RIGHT,
12550
12551 JIM_EXPROP_POW,
12552
12553
12554 JIM_EXPROP_STREQ,
12555 JIM_EXPROP_STRNE,
12556 JIM_EXPROP_STRIN,
12557 JIM_EXPROP_STRNI,
12558
12559
12560 JIM_EXPROP_NOT,
12561 JIM_EXPROP_BITNOT,
12562 JIM_EXPROP_UNARYMINUS,
12563 JIM_EXPROP_UNARYPLUS,
12564
12565
12566 JIM_EXPROP_FUNC_FIRST,
12567 JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
12568 JIM_EXPROP_FUNC_WIDE,
12569 JIM_EXPROP_FUNC_ABS,
12570 JIM_EXPROP_FUNC_DOUBLE,
12571 JIM_EXPROP_FUNC_ROUND,
12572 JIM_EXPROP_FUNC_RAND,
12573 JIM_EXPROP_FUNC_SRAND,
12574
12575
12576 JIM_EXPROP_FUNC_SIN,
12577 JIM_EXPROP_FUNC_COS,
12578 JIM_EXPROP_FUNC_TAN,
12579 JIM_EXPROP_FUNC_ASIN,
12580 JIM_EXPROP_FUNC_ACOS,
12581 JIM_EXPROP_FUNC_ATAN,
 
12582 JIM_EXPROP_FUNC_SINH,
12583 JIM_EXPROP_FUNC_COSH,
12584 JIM_EXPROP_FUNC_TANH,
12585 JIM_EXPROP_FUNC_CEIL,
12586 JIM_EXPROP_FUNC_FLOOR,
@@ -12424,12 +12587,10 @@
12587 JIM_EXPROP_FUNC_EXP,
12588 JIM_EXPROP_FUNC_LOG,
12589 JIM_EXPROP_FUNC_LOG10,
12590 JIM_EXPROP_FUNC_SQRT,
12591 JIM_EXPROP_FUNC_POW,
 
 
12592 };
12593
12594 struct JimExprState
12595 {
12596 Jim_Obj **stack;
@@ -12506,15 +12667,11 @@
12667 case JIM_EXPROP_UNARYPLUS:
12668 dC = dA;
12669 intresult = 0;
12670 break;
12671 case JIM_EXPROP_FUNC_ABS:
 
 
 
12672 dC = dA >= 0 ? dA : -dA;
 
12673 intresult = 0;
12674 break;
12675 case JIM_EXPROP_UNARYMINUS:
12676 dC = -dA;
12677 intresult = 0;
@@ -12702,16 +12859,16 @@
12859 }
12860 }
12861 break;
12862 case JIM_EXPROP_ROTL:
12863 case JIM_EXPROP_ROTR:{
12864
12865 unsigned long uA = (unsigned long)wA;
12866 unsigned long uB = (unsigned long)wB;
12867 const unsigned int S = sizeof(unsigned long) * 8;
12868
12869
12870 uB %= S;
12871
12872 if (e->opcode == JIM_EXPROP_ROTR) {
12873 uB = S - uB;
12874 }
@@ -12733,10 +12890,11 @@
12890
12891
12892
12893 static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
12894 {
12895 int intresult = 1;
12896 int rc = JIM_OK;
12897 double dA, dB, dC = 0;
12898 jim_wide wA, wB, wC = 0;
12899
12900 Jim_Obj *B = ExprPop(e);
@@ -12744,36 +12902,30 @@
12902
12903 if ((A->typePtr != &doubleObjType || A->bytes) &&
12904 (B->typePtr != &doubleObjType || B->bytes) &&
12905 JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
12906
12907
12908
12909 switch (e->opcode) {
12910 case JIM_EXPROP_POW:
12911 case JIM_EXPROP_FUNC_POW:
 
 
 
 
 
12912 wC = JimPowWide(wA, wB);
12913 break;
12914 case JIM_EXPROP_ADD:
12915 wC = wA + wB;
12916 break;
12917 case JIM_EXPROP_SUB:
12918 wC = wA - wB;
12919 break;
12920 case JIM_EXPROP_MUL:
12921 wC = wA * wB;
12922 break;
12923 case JIM_EXPROP_DIV:
12924 if (wB == 0) {
12925 Jim_SetResultString(interp, "Division by zero", -1);
12926 rc = JIM_ERR;
 
12927 }
12928 else {
12929 if (wB < 0) {
12930 wB = -wB;
12931 wA = -wA;
@@ -12780,67 +12932,55 @@
12932 }
12933 wC = wA / wB;
12934 if (wA % wB < 0) {
12935 wC--;
12936 }
12937 }
12938 break;
12939 case JIM_EXPROP_LT:
12940 wC = wA < wB;
12941 break;
12942 case JIM_EXPROP_GT:
12943 wC = wA > wB;
12944 break;
12945 case JIM_EXPROP_LTE:
12946 wC = wA <= wB;
12947 break;
12948 case JIM_EXPROP_GTE:
12949 wC = wA >= wB;
12950 break;
12951 case JIM_EXPROP_NUMEQ:
12952 wC = wA == wB;
12953 break;
12954 case JIM_EXPROP_NUMNE:
12955 wC = wA != wB;
12956 break;
12957 default:
12958 abort();
12959 }
12960 }
12961 else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12962 intresult = 0;
12963 switch (e->opcode) {
12964 case JIM_EXPROP_POW:
12965 case JIM_EXPROP_FUNC_POW:
12966 #ifdef JIM_MATH_FUNCTIONS
12967 dC = pow(dA, dB);
12968 #else
12969 Jim_SetResultString(interp, "unsupported", -1);
12970 rc = JIM_ERR;
12971 #endif
12972 break;
12973 case JIM_EXPROP_ADD:
12974 dC = dA + dB;
12975 break;
12976 case JIM_EXPROP_SUB:
12977 dC = dA - dB;
12978 break;
12979 case JIM_EXPROP_MUL:
12980 dC = dA * dB;
12981 break;
 
 
 
 
 
 
 
 
 
 
 
 
12982 case JIM_EXPROP_DIV:
12983 if (dB == 0) {
12984 #ifdef INFINITY
12985 dC = dA < 0 ? -INFINITY : INFINITY;
12986 #else
@@ -12848,70 +12988,83 @@
12988 #endif
12989 }
12990 else {
12991 dC = dA / dB;
12992 }
12993 break;
12994 case JIM_EXPROP_LT:
12995 wC = dA < dB;
12996 intresult = 1;
12997 break;
12998 case JIM_EXPROP_GT:
12999 wC = dA > dB;
13000 intresult = 1;
13001 break;
13002 case JIM_EXPROP_LTE:
13003 wC = dA <= dB;
13004 intresult = 1;
13005 break;
13006 case JIM_EXPROP_GTE:
13007 wC = dA >= dB;
13008 intresult = 1;
13009 break;
13010 case JIM_EXPROP_NUMEQ:
13011 wC = dA == dB;
13012 intresult = 1;
13013 break;
13014 case JIM_EXPROP_NUMNE:
13015 wC = dA != dB;
13016 intresult = 1;
13017 break;
13018 default:
13019 abort();
13020 }
13021 }
13022 else {
13023
13024
13025
 
13026 int i = Jim_StringCompareObj(interp, A, B, 0);
13027
13028 switch (e->opcode) {
13029 case JIM_EXPROP_LT:
13030 wC = i < 0;
13031 break;
13032 case JIM_EXPROP_GT:
13033 wC = i > 0;
13034 break;
13035 case JIM_EXPROP_LTE:
13036 wC = i <= 0;
13037 break;
13038 case JIM_EXPROP_GTE:
13039 wC = i >= 0;
13040 break;
13041 case JIM_EXPROP_NUMEQ:
13042 wC = i == 0;
13043 break;
13044 case JIM_EXPROP_NUMNE:
13045 wC = i != 0;
13046 break;
13047 default:
13048 rc = JIM_ERR;
13049 break;
13050 }
13051 }
13052
13053 if (rc == JIM_OK) {
13054 if (intresult) {
13055 ExprPush(e, Jim_NewIntObj(interp, wC));
13056 }
13057 else {
13058 ExprPush(e, Jim_NewDoubleObj(interp, dC));
13059 }
13060 }
13061
13062 Jim_DecrRefCount(interp, A);
13063 Jim_DecrRefCount(interp, B);
13064
13065 return rc;
 
 
 
 
 
 
13066 }
13067
13068 static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
13069 {
13070 int listlen;
@@ -12960,21 +13113,17 @@
13113
13114 static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
13115 {
13116 long l;
13117 double d;
 
13118
13119 if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
13120 return l != 0;
13121 }
13122 if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
13123 return d != 0;
13124 }
 
 
 
13125 return -1;
13126 }
13127
13128 static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
13129 {
@@ -12982,21 +13131,21 @@
13131 Jim_Obj *A = ExprPop(e);
13132 int rc = JIM_OK;
13133
13134 switch (ExprBool(interp, A)) {
13135 case 0:
13136
13137 e->skip = JimWideValue(skip);
13138 ExprPush(e, Jim_NewIntObj(interp, 0));
13139 break;
13140
13141 case 1:
13142
13143 break;
13144
13145 case -1:
13146
13147 rc = JIM_ERR;
13148 }
13149 Jim_DecrRefCount(interp, A);
13150 Jim_DecrRefCount(interp, skip);
13151
@@ -13009,21 +13158,21 @@
13158 Jim_Obj *A = ExprPop(e);
13159 int rc = JIM_OK;
13160
13161 switch (ExprBool(interp, A)) {
13162 case 0:
13163
13164 break;
13165
13166 case 1:
13167
13168 e->skip = JimWideValue(skip);
13169 ExprPush(e, Jim_NewIntObj(interp, 1));
13170 break;
13171
13172 case -1:
13173
13174 rc = JIM_ERR;
13175 break;
13176 }
13177 Jim_DecrRefCount(interp, A);
13178 Jim_DecrRefCount(interp, skip);
@@ -13044,11 +13193,11 @@
13193 case 1:
13194 ExprPush(e, Jim_NewIntObj(interp, 1));
13195 break;
13196
13197 case -1:
13198
13199 rc = JIM_ERR;
13200 break;
13201 }
13202 Jim_DecrRefCount(interp, A);
13203
@@ -13059,27 +13208,27 @@
13208 {
13209 Jim_Obj *skip = ExprPop(e);
13210 Jim_Obj *A = ExprPop(e);
13211 int rc = JIM_OK;
13212
13213
13214 ExprPush(e, A);
13215
13216 switch (ExprBool(interp, A)) {
13217 case 0:
13218
13219 e->skip = JimWideValue(skip);
13220
13221 ExprPush(e, Jim_NewIntObj(interp, 0));
13222 break;
13223
13224 case 1:
13225
13226 break;
13227
13228 case -1:
13229
13230 rc = JIM_ERR;
13231 break;
13232 }
13233 Jim_DecrRefCount(interp, A);
13234 Jim_DecrRefCount(interp, skip);
@@ -13091,15 +13240,15 @@
13240 {
13241 Jim_Obj *skip = ExprPop(e);
13242 Jim_Obj *B = ExprPop(e);
13243 Jim_Obj *A = ExprPop(e);
13244
13245
13246 if (ExprBool(interp, A)) {
13247
13248 e->skip = JimWideValue(skip);
13249
13250 ExprPush(e, B);
13251 }
13252
13253 Jim_DecrRefCount(interp, skip);
13254 Jim_DecrRefCount(interp, A);
@@ -13115,16 +13264,15 @@
13264 enum
13265 {
13266 LAZY_NONE,
13267 LAZY_OP,
13268 LAZY_LEFT,
13269 LAZY_RIGHT
 
13270 };
13271
13272 #define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1}
13273 #define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1}
13274
13275 static const struct Jim_ExprOperator Jim_ExprOperators[] = {
13276 OPRINIT("*", 110, 2, JimExprOpBin),
13277 OPRINIT("/", 110, 2, JimExprOpBin),
13278 OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13148,28 +13296,27 @@
13296
13297 OPRINIT("&", 50, 2, JimExprOpIntBin),
13298 OPRINIT("^", 49, 2, JimExprOpIntBin),
13299 OPRINIT("|", 48, 2, JimExprOpIntBin),
13300
13301 OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP),
13302 OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13303 OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13304
13305 OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP),
13306 OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13307 OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13308
13309 OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP),
13310 OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13311 OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13312
13313 OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP),
13314 OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13315 OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13316
13317 OPRINIT("**", 250, 2, JimExprOpBin),
 
13318
13319 OPRINIT("eq", 60, 2, JimExprOpStrBin),
13320 OPRINIT("ne", 60, 2, JimExprOpStrBin),
13321
13322 OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13195,11 +13342,10 @@
13342 OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
13343 OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
13344 OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
13345 OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
13346 OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
 
13347 OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
13348 OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
13349 OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
13350 OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
13351 OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13206,12 +13352,10 @@
13352 OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
13353 OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
13354 OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
13355 OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
13356 OPRINIT("pow", 200, 2, JimExprOpBin),
 
 
13357 #endif
13358 };
13359 #undef OPRINIT
13360 #undef OPRINIT_LAZY
13361
@@ -13218,20 +13362,20 @@
13362 #define JIM_EXPR_OPERATORS_NUM \
13363 (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
13364
13365 static int JimParseExpression(struct JimParserCtx *pc)
13366 {
13367
13368 while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
13369 if (*pc->p == '\n') {
13370 pc->linenr++;
13371 }
13372 pc->p++;
13373 pc->len--;
13374 }
13375
13376
13377 pc->tline = pc->linenr;
13378 pc->tstart = pc->p;
13379
13380 if (pc->len == 0) {
13381 pc->tend = pc->p;
@@ -13257,11 +13401,11 @@
13401 return JimParseCmd(pc);
13402 case '$':
13403 if (JimParseVar(pc) == JIM_ERR)
13404 return JimParseExprOperator(pc);
13405 else {
13406
13407 if (pc->tt == JIM_TT_EXPRSUGAR) {
13408 return JIM_ERR;
13409 }
13410 return JIM_OK;
13411 }
@@ -13286,18 +13430,10 @@
13430 case 'N':
13431 case 'I':
13432 case 'n':
13433 case 'i':
13434 if (JimParseExprIrrational(pc) == JIM_ERR)
 
 
 
 
 
 
 
 
13435 return JimParseExprOperator(pc);
13436 break;
13437 default:
13438 return JimParseExprOperator(pc);
13439 break;
@@ -13307,21 +13443,21 @@
13443
13444 static int JimParseExprNumber(struct JimParserCtx *pc)
13445 {
13446 char *end;
13447
13448
13449 pc->tt = JIM_TT_EXPR_INT;
13450
13451 jim_strtoull(pc->p, (char **)&pc->p);
13452
13453 if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
13454 if (strtod(pc->tstart, &end)) { }
13455 if (end == pc->tstart)
13456 return JIM_ERR;
13457 if (end > pc->p) {
13458
13459 pc->tt = JIM_TT_EXPR_DOUBLE;
13460 pc->p = end;
13461 }
13462 }
13463 pc->tend = pc->p - 1;
@@ -13346,37 +13482,16 @@
13482 }
13483 }
13484 return JIM_ERR;
13485 }
13486
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13487 static int JimParseExprOperator(struct JimParserCtx *pc)
13488 {
13489 int i;
13490 int bestIdx = -1, bestLen = 0;
13491
13492
13493 for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
13494 const char * const opname = Jim_ExprOperators[i].name;
13495 const int oplen = Jim_ExprOperators[i].namelen;
13496
13497 if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13390,11 +13505,11 @@
13505 }
13506 if (bestIdx == -1) {
13507 return JIM_ERR;
13508 }
13509
13510
13511 if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
13512 const char *p = pc->p + bestLen;
13513 int len = pc->len - bestLen;
13514
13515 while (len && isspace(UCHAR(*p))) {
@@ -13424,20 +13539,14 @@
13539
13540 const char *jim_tt_name(int type)
13541 {
13542 static const char * const tt_names[JIM_TT_EXPR_OP] =
13543 { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
13544 "DBL", "$()" };
13545 if (type < JIM_TT_EXPR_OP) {
13546 return tt_names[type];
13547 }
 
 
 
 
 
 
13548 else {
13549 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
13550 static char buf[20];
13551
13552 if (op->name) {
@@ -13461,13 +13570,13 @@
13570 };
13571
13572
13573 typedef struct ExprByteCode
13574 {
13575 ScriptToken *token;
13576 int len;
13577 int inUse;
13578 } ExprByteCode;
13579
13580 static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
13581 {
13582 int i;
@@ -13495,29 +13604,26 @@
13604 static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
13605 {
13606 JIM_NOTUSED(interp);
13607 JIM_NOTUSED(srcPtr);
13608
13609
13610 dupPtr->typePtr = NULL;
13611 }
13612
13613
13614 static int ExprCheckCorrectness(ExprByteCode * expr)
13615 {
13616 int i;
13617 int stacklen = 0;
13618 int ternary = 0;
 
 
13619
13620 for (i = 0; i < expr->len; i++) {
13621 ScriptToken *t = &expr->token[i];
13622 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
 
13623
13624 stacklen -= op->arity;
 
13625 if (stacklen < 0) {
13626 break;
13627 }
13628 if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
13629 ternary++;
@@ -13524,47 +13630,26 @@
13630 }
13631 else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
13632 ternary--;
13633 }
13634
13635
13636 stacklen++;
13637 }
13638 if (stacklen != 1 || ternary != 0) {
13639 return JIM_ERR;
13640 }
13641 return JIM_OK;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13642 }
13643
13644 static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
13645 {
13646 int i;
13647
13648 int leftindex, arity, offset;
13649
13650
13651 leftindex = expr->len - 1;
13652
13653 arity = 1;
13654 while (arity) {
13655 ScriptToken *tt = &expr->token[leftindex];
@@ -13577,11 +13662,11 @@
13662 return JIM_ERR;
13663 }
13664 }
13665 leftindex++;
13666
13667
13668 memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
13669 sizeof(*expr->token) * (expr->len - leftindex));
13670 expr->len += 2;
13671 offset = (expr->len - leftindex) - 1;
13672
@@ -13589,16 +13674,16 @@
13674 expr->token[leftindex + 1].objPtr = interp->emptyObj;
13675
13676 expr->token[leftindex].type = JIM_TT_EXPR_INT;
13677 expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
13678
13679
13680 expr->token[expr->len].objPtr = interp->emptyObj;
13681 expr->token[expr->len].type = t->type + 2;
13682 expr->len++;
13683
13684
13685 for (i = leftindex - 1; i > 0; i--) {
13686 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
13687 if (op->lazy == LAZY_LEFT) {
13688 if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
13689 JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13644,11 +13729,11 @@
13729 return right_index;
13730 }
13731 right_index--;
13732 }
13733
13734
13735 return -1;
13736 }
13737
13738 static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
13739 {
@@ -13686,11 +13771,11 @@
13771
13772 if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
13773 continue;
13774 }
13775
13776
13777 if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
13778 continue;
13779 }
13780
13781 tmp = expr->token[prev_right_index];
@@ -13699,25 +13784,25 @@
13784 }
13785 expr->token[i] = tmp;
13786
13787 JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
13788
13789
13790 i++;
13791 }
13792 }
13793
13794 static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj)
13795 {
13796 Jim_Stack stack;
13797 ExprByteCode *expr;
13798 int ok = 1;
13799 int i;
13800 int prevtt = JIM_TT_NONE;
13801 int have_ternary = 0;
13802
13803
13804 int count = tokenlist->count - 1;
13805
13806 expr = Jim_Alloc(sizeof(*expr));
13807 expr->inUse = 1;
13808 expr->len = 0;
@@ -13728,11 +13813,11 @@
13813 ParseToken *t = &tokenlist->list[i];
13814 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13815
13816 if (op->lazy == LAZY_OP) {
13817 count += 2;
13818
13819 if (t->type == JIM_EXPROP_TERNARY) {
13820 have_ternary = 1;
13821 }
13822 }
13823 }
@@ -13740,128 +13825,128 @@
13825 expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
13826
13827 for (i = 0; i < tokenlist->count && ok; i++) {
13828 ParseToken *t = &tokenlist->list[i];
13829
13830
13831 struct ScriptToken *token = &expr->token[expr->len];
13832
13833 if (t->type == JIM_TT_EOL) {
13834 break;
13835 }
13836
13837 switch (t->type) {
13838 case JIM_TT_STR:
13839 case JIM_TT_ESC:
13840 case JIM_TT_VAR:
13841 case JIM_TT_DICTSUGAR:
13842 case JIM_TT_EXPRSUGAR:
13843 case JIM_TT_CMD:
13844 token->type = t->type;
13845 strexpr:
13846 token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13847 if (t->type == JIM_TT_CMD) {
13848
13849 JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13850 }
13851 expr->len++;
13852 break;
13853
13854 case JIM_TT_EXPR_INT:
13855 case JIM_TT_EXPR_DOUBLE:
13856 {
13857 char *endptr;
13858 if (t->type == JIM_TT_EXPR_INT) {
13859 token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13860 }
13861 else {
13862 token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13863 }
13864 if (endptr != t->token + t->len) {
13865
13866 Jim_FreeNewObj(interp, token->objPtr);
13867 token->type = JIM_TT_STR;
13868 goto strexpr;
13869 }
13870 token->type = t->type;
13871 expr->len++;
13872 }
13873 break;
13874
13875 case JIM_TT_SUBEXPR_START:
13876 Jim_StackPush(&stack, t);
13877 prevtt = JIM_TT_NONE;
13878 continue;
13879
13880 case JIM_TT_SUBEXPR_COMMA:
13881
13882 continue;
13883
13884 case JIM_TT_SUBEXPR_END:
13885 ok = 0;
13886 while (Jim_StackLen(&stack)) {
13887 ParseToken *tt = Jim_StackPop(&stack);
13888
13889 if (tt->type == JIM_TT_SUBEXPR_START) {
13890 ok = 1;
13891 break;
13892 }
13893
13894 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13895 goto err;
13896 }
13897 }
13898 if (!ok) {
13899 Jim_SetResultString(interp, "Unexpected close parenthesis", -1);
13900 goto err;
13901 }
13902 break;
13903
13904
13905 default:{
13906
13907 const struct Jim_ExprOperator *op;
13908 ParseToken *tt;
13909
13910
13911 if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) {
13912 if (t->type == JIM_EXPROP_SUB) {
13913 t->type = JIM_EXPROP_UNARYMINUS;
13914 }
13915 else if (t->type == JIM_EXPROP_ADD) {
13916 t->type = JIM_EXPROP_UNARYPLUS;
13917 }
13918 }
13919
13920 op = JimExprOperatorInfoByOpcode(t->type);
13921
13922
13923 while ((tt = Jim_StackPeek(&stack)) != NULL) {
13924 const struct Jim_ExprOperator *tt_op =
13925 JimExprOperatorInfoByOpcode(tt->type);
13926
13927
13928
13929 if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13930 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13931 ok = 0;
13932 goto err;
13933 }
13934 Jim_StackPop(&stack);
13935 }
13936 else {
13937 break;
13938 }
13939 }
13940 Jim_StackPush(&stack, t);
13941 break;
13942 }
13943 }
13944 prevtt = t->type;
13945 }
13946
13947
13948 while (Jim_StackLen(&stack)) {
13949 ParseToken *tt = Jim_StackPop(&stack);
13950
13951 if (tt->type == JIM_TT_SUBEXPR_START) {
13952 ok = 0;
@@ -13877,11 +13962,11 @@
13962 if (have_ternary) {
13963 ExprTernaryReorderExpression(interp, expr);
13964 }
13965
13966 err:
13967
13968 Jim_FreeStack(&stack);
13969
13970 for (i = 0; i < expr->len; i++) {
13971 Jim_IncrRefCount(expr->token[i].objPtr);
13972 }
@@ -13904,11 +13989,11 @@
13989 ParseTokenList tokenlist;
13990 int line;
13991 Jim_Obj *fileNameObj;
13992 int rc = JIM_ERR;
13993
13994
13995 if (objPtr->typePtr == &sourceObjType) {
13996 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
13997 line = objPtr->internalRep.sourceValue.lineNumber;
13998 }
13999 else {
@@ -13917,17 +14002,18 @@
14002 }
14003 Jim_IncrRefCount(fileNameObj);
14004
14005 exprText = Jim_GetString(objPtr, &exprTextLen);
14006
14007
14008 ScriptTokenListInit(&tokenlist);
14009
14010 JimParserInit(&parser, exprText, exprTextLen, line);
14011 while (!parser.eof) {
14012 if (JimParseExpression(&parser) != JIM_OK) {
14013 ScriptTokenListFree(&tokenlist);
14014 invalidexpr:
14015 Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
14016 expr = NULL;
14017 goto err;
14018 }
14019
@@ -13950,14 +14036,14 @@
14036 ScriptTokenListFree(&tokenlist);
14037 Jim_DecrRefCount(interp, fileNameObj);
14038 return JIM_ERR;
14039 }
14040
14041
14042 expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj);
14043
14044
 
 
14045 ScriptTokenListFree(&tokenlist);
14046
14047 if (!expr) {
14048 goto err;
14049 }
@@ -13973,22 +14059,20 @@
14059 printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
14060 }
14061 }
14062 #endif
14063
14064
14065 if (ExprCheckCorrectness(expr) != JIM_OK) {
 
14066 ExprFreeByteCode(interp, expr);
14067 goto invalidexpr;
 
14068 }
14069
14070 rc = JIM_OK;
14071
14072 err:
14073
14074 Jim_DecrRefCount(interp, fileNameObj);
14075 Jim_FreeIntRep(interp, objPtr);
14076 Jim_SetIntRepPtr(objPtr, expr);
14077 objPtr->typePtr = &exprObjType;
14078 return rc;
@@ -14028,11 +14112,11 @@
14112 int retcode = JIM_OK;
14113 struct JimExprState e;
14114
14115 expr = JimGetExpression(interp, exprObjPtr);
14116 if (!expr) {
14117 return JIM_ERR;
14118 }
14119
14120 #ifdef JIM_OPTIMIZATION
14121 {
14122 Jim_Obj *objPtr;
@@ -14101,27 +14185,26 @@
14185 noopt:
14186 #endif
14187
14188 expr->inUse++;
14189
14190
14191
14192 if (expr->len > JIM_EE_STATICSTACK_LEN)
14193 e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
14194 else
14195 e.stack = staticStack;
14196
14197 e.stacklen = 0;
14198
14199
14200 for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
14201 Jim_Obj *objPtr;
14202
14203 switch (expr->token[i].type) {
14204 case JIM_TT_EXPR_INT:
14205 case JIM_TT_EXPR_DOUBLE:
 
14206 case JIM_TT_STR:
14207 ExprPush(&e, expr->token[i].objPtr);
14208 break;
14209
14210 case JIM_TT_VAR:
@@ -14157,16 +14240,16 @@
14240 ExprPush(&e, Jim_GetResult(interp));
14241 }
14242 break;
14243
14244 default:{
14245
14246 e.skip = 0;
14247 e.opcode = expr->token[i].type;
14248
14249 retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
14250
14251 i += e.skip;
14252 continue;
14253 }
14254 }
14255 }
@@ -14190,27 +14273,20 @@
14273 int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
14274 {
14275 int retcode;
14276 jim_wide wideValue;
14277 double doubleValue;
 
14278 Jim_Obj *exprResultPtr;
14279
14280 retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
14281 if (retcode != JIM_OK)
14282 return retcode;
14283
14284 if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
14285 if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
14286 Jim_DecrRefCount(interp, exprResultPtr);
14287 return JIM_ERR;
 
 
 
 
 
 
14288 }
14289 else {
14290 Jim_DecrRefCount(interp, exprResultPtr);
14291 *boolPtr = doubleValue != 0;
14292 return JIM_OK;
@@ -14225,29 +14301,29 @@
14301
14302
14303
14304 typedef struct ScanFmtPartDescr
14305 {
14306 char *arg;
14307 char *prefix;
14308 size_t width;
14309 int pos;
14310 char type;
14311 char modifier;
14312 } ScanFmtPartDescr;
14313
14314
14315 typedef struct ScanFmtStringObj
14316 {
14317 jim_wide size;
14318 char *stringRep;
14319 size_t count;
14320 size_t convCount;
14321 size_t maxPos;
14322 const char *error;
14323 char *scratch;
14324 ScanFmtPartDescr descr[1];
14325 } ScanFmtStringObj;
14326
14327
14328 static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
14329 static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14294,22 +14370,22 @@
14370 int maxFmtLen = objPtr->length;
14371 const char *fmtEnd = fmt + maxFmtLen;
14372 int curr;
14373
14374 Jim_FreeIntRep(interp, objPtr);
14375
14376 for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
14377 if (fmt[i] == '%')
14378 ++maxCount;
14379
14380 approxSize = sizeof(ScanFmtStringObj)
14381 +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14382 +maxFmtLen * sizeof(char) + 3 + 1
14383 + maxFmtLen * sizeof(char) + 1
14384 + maxFmtLen * sizeof(char)
14385 +(maxCount + 1) * sizeof(char)
14386 +1;
14387 fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
14388 memset(fmtObj, 0, approxSize);
14389 fmtObj->size = approxSize;
14390 fmtObj->maxPos = 0;
14391 fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14321,12 +14397,12 @@
14397 for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
14398 int width = 0, skip;
14399 ScanFmtPartDescr *descr = &fmtObj->descr[curr];
14400
14401 fmtObj->count++;
14402 descr->width = 0;
14403
14404 if (*fmt != '%' || fmt[1] == '%') {
14405 descr->type = 0;
14406 descr->prefix = &buffer[i];
14407 for (; fmt < fmtEnd; ++fmt) {
14408 if (*fmt == '%') {
@@ -14336,65 +14412,65 @@
14412 }
14413 buffer[i++] = *fmt;
14414 }
14415 buffer[i++] = 0;
14416 }
14417
14418 ++fmt;
14419
14420 if (fmt >= fmtEnd)
14421 goto done;
14422 descr->pos = 0;
14423 if (*fmt == '*') {
14424 descr->pos = -1;
14425 ++fmt;
14426 }
14427 else
14428 fmtObj->convCount++;
14429
14430 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14431 fmt += skip;
14432
14433 if (descr->pos != -1 && *fmt == '$') {
14434 int prev;
14435
14436 ++fmt;
14437 descr->pos = width;
14438 width = 0;
14439
14440 if ((lastPos == 0 && descr->pos > 0)
14441 || (lastPos > 0 && descr->pos == 0)) {
14442 fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
14443 return JIM_ERR;
14444 }
14445
14446 for (prev = 0; prev < curr; ++prev) {
14447 if (fmtObj->descr[prev].pos == -1)
14448 continue;
14449 if (fmtObj->descr[prev].pos == descr->pos) {
14450 fmtObj->error =
14451 "variable is assigned by multiple \"%n$\" conversion specifiers";
14452 return JIM_ERR;
14453 }
14454 }
14455
14456 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14457 descr->width = width;
14458 fmt += skip;
14459 }
14460 if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
14461 fmtObj->maxPos = descr->pos;
14462 }
14463 else {
14464
14465 descr->width = width;
14466 }
14467 }
14468
14469 if (lastPos == -1)
14470 lastPos = descr->pos;
14471
14472 if (*fmt == '[') {
14473 int swapped = 1, beg = i, end, j;
14474
14475 descr->type = '[';
14476 descr->arg = &buffer[i];
@@ -14409,11 +14485,11 @@
14485 fmtObj->error = "unmatched [ in format string";
14486 return JIM_ERR;
14487 }
14488 end = i;
14489 buffer[i++] = 0;
14490
14491 while (swapped) {
14492 swapped = 0;
14493 for (j = beg + 1; j < end - 1; ++j) {
14494 if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
14495 char tmp = buffer[j - 1];
@@ -14424,11 +14500,11 @@
14500 }
14501 }
14502 }
14503 }
14504 else {
14505
14506 if (strchr("hlL", *fmt) != 0)
14507 descr->modifier = tolower((int)*fmt++);
14508
14509 descr->type = *fmt;
14510 if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14467,11 +14543,11 @@
14543 while (*str) {
14544 int c;
14545 int n;
14546
14547 if (!sdescr && isspace(UCHAR(*str)))
14548 break;
14549
14550 n = utf8_tounicode(str, &c);
14551 if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
14552 break;
14553 while (n--)
@@ -14490,89 +14566,89 @@
14566 size_t scanned = 0;
14567 size_t anchor = pos;
14568 int i;
14569 Jim_Obj *tmpObj = NULL;
14570
14571
14572 *valObjPtr = 0;
14573 if (descr->prefix) {
14574 for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
14575
14576 if (isspace(UCHAR(descr->prefix[i])))
14577 while (pos < strLen && isspace(UCHAR(str[pos])))
14578 ++pos;
14579 else if (descr->prefix[i] != str[pos])
14580 break;
14581 else
14582 ++pos;
14583 }
14584 if (pos >= strLen) {
14585 return -1;
14586 }
14587 else if (descr->prefix[i] != 0)
14588 return 0;
14589 }
14590
14591 if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
14592 while (isspace(UCHAR(str[pos])))
14593 ++pos;
14594
14595 scanned = pos - anchor;
14596
14597
14598 if (descr->type == 'n') {
14599
14600 *valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
14601 }
14602 else if (pos >= strLen) {
14603
14604 return -1;
14605 }
14606 else if (descr->type == 'c') {
14607 int c;
14608 scanned += utf8_tounicode(&str[pos], &c);
14609 *valObjPtr = Jim_NewIntObj(interp, c);
14610 return scanned;
14611 }
14612 else {
14613
14614 if (descr->width > 0) {
14615 size_t sLen = utf8_strlen(&str[pos], strLen - pos);
14616 size_t tLen = descr->width > sLen ? sLen : descr->width;
14617
14618 tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
14619 tok = tmpObj->bytes;
14620 }
14621 else {
14622
14623 tok = &str[pos];
14624 }
14625 switch (descr->type) {
14626 case 'd':
14627 case 'o':
14628 case 'x':
14629 case 'u':
14630 case 'i':{
14631 char *endp;
14632 jim_wide w;
14633
14634 int base = descr->type == 'o' ? 8
14635 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
14636
14637
14638 if (base == 0) {
14639 w = jim_strtoull(tok, &endp);
14640 }
14641 else {
14642 w = strtoull(tok, &endp, base);
14643 }
14644
14645 if (endp != tok) {
14646
14647 *valObjPtr = Jim_NewIntObj(interp, w);
14648
14649
14650 scanned += endp - tok;
14651 }
14652 else {
14653 scanned = *tok ? 0 : -1;
14654 }
@@ -14589,13 +14665,13 @@
14665 case 'g':{
14666 char *endp;
14667 double value = strtod(tok, &endp);
14668
14669 if (endp != tok) {
14670
14671 *valObjPtr = Jim_NewDoubleObj(interp, value);
14672
14673 scanned += endp - tok;
14674 }
14675 else {
14676 scanned = *tok ? 0 : -1;
14677 }
@@ -14620,65 +14696,65 @@
14696 Jim_Obj **resultVec = 0;
14697 int resultc;
14698 Jim_Obj *emptyStr = 0;
14699 ScanFmtStringObj *fmtObj;
14700
14701
14702 JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
14703
14704 fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
14705
14706 if (fmtObj->error != 0) {
14707 if (flags & JIM_ERRMSG)
14708 Jim_SetResultString(interp, fmtObj->error, -1);
14709 return 0;
14710 }
14711
14712 emptyStr = Jim_NewEmptyStringObj(interp);
14713 Jim_IncrRefCount(emptyStr);
14714
14715 resultList = Jim_NewListObj(interp, NULL, 0);
14716 if (fmtObj->maxPos > 0) {
14717 for (i = 0; i < fmtObj->maxPos; ++i)
14718 Jim_ListAppendElement(interp, resultList, emptyStr);
14719 JimListGetElements(interp, resultList, &resultc, &resultVec);
14720 }
14721
14722 for (i = 0, pos = 0; i < fmtObj->count; ++i) {
14723 ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
14724 Jim_Obj *value = 0;
14725
14726
14727 if (descr->type == 0)
14728 continue;
14729
14730 if (scanned > 0)
14731 scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
14732
14733 if (scanned == -1 && i == 0)
14734 goto eof;
14735
14736 pos += scanned;
14737
14738
14739 if (value == 0)
14740 value = Jim_NewEmptyStringObj(interp);
14741
14742 if (descr->pos == -1) {
14743 Jim_FreeNewObj(interp, value);
14744 }
14745 else if (descr->pos == 0)
14746
14747 Jim_ListAppendElement(interp, resultList, value);
14748 else if (resultVec[descr->pos - 1] == emptyStr) {
14749
14750 Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
14751 Jim_IncrRefCount(value);
14752 resultVec[descr->pos - 1] = value;
14753 }
14754 else {
14755
14756 Jim_FreeNewObj(interp, value);
14757 goto err;
14758 }
14759 }
14760 Jim_DecrRefCount(interp, emptyStr);
@@ -14716,15 +14792,15 @@
14792 {
14793 Jim_PrngState *prng;
14794 unsigned char *destByte = (unsigned char *)dest;
14795 unsigned int si, sj, x;
14796
14797
14798 if (interp->prngState == NULL)
14799 JimPrngInit(interp);
14800 prng = interp->prngState;
14801
14802 for (x = 0; x < len; x++) {
14803 prng->i = (prng->i + 1) & 0xff;
14804 si = prng->sbox[prng->i];
14805 prng->j = (prng->j + si) & 0xff;
14806 sj = prng->sbox[prng->j];
@@ -14738,19 +14814,19 @@
14814 static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
14815 {
14816 int i;
14817 Jim_PrngState *prng;
14818
14819
14820 if (interp->prngState == NULL)
14821 JimPrngInit(interp);
14822 prng = interp->prngState;
14823
14824
14825 for (i = 0; i < 256; i++)
14826 prng->sbox[i] = i;
14827
14828 for (i = 0; i < seedLen; i++) {
14829 unsigned char t;
14830
14831 t = prng->sbox[i & 0xFF];
14832 prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14777,11 +14853,11 @@
14853 if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
14854 return JIM_ERR;
14855 }
14856 intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
14857 if (!intObjPtr) {
14858
14859 wideValue = 0;
14860 }
14861 else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
14862 return JIM_ERR;
14863 }
@@ -14791,26 +14867,26 @@
14867 Jim_FreeNewObj(interp, intObjPtr);
14868 return JIM_ERR;
14869 }
14870 }
14871 else {
14872
14873 Jim_InvalidateStringRep(intObjPtr);
14874 JimWideValue(intObjPtr) = wideValue + increment;
14875
14876 if (argv[1]->typePtr != &variableObjType) {
14877
14878 Jim_SetVariable(interp, argv[1], intObjPtr);
14879 }
14880 }
14881 Jim_SetResult(interp, intObjPtr);
14882 return JIM_OK;
14883 }
14884
14885
14886 #define JIM_EVAL_SARGV_LEN 8
14887 #define JIM_EVAL_SINTV_LEN 8
14888
14889
14890 static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
14891 {
14892 int retcode;
@@ -14818,16 +14894,16 @@
14894 if (interp->unknown_called > 50) {
14895 return JIM_ERR;
14896 }
14897
14898
14899
14900 if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
14901 return JIM_ERR;
14902
14903 interp->unknown_called++;
14904
14905 retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
14906 interp->unknown_called--;
14907
14908 return retcode;
14909 }
@@ -14845,11 +14921,11 @@
14921 }
14922 printf("\n");
14923 #endif
14924
14925 if (interp->framePtr->tailcallCmd) {
14926
14927 cmdPtr = interp->framePtr->tailcallCmd;
14928 interp->framePtr->tailcallCmd = NULL;
14929 }
14930 else {
14931 cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14864,11 +14940,11 @@
14940 retcode = JIM_ERR;
14941 goto out;
14942 }
14943 interp->evalDepth++;
14944
14945
14946 Jim_SetEmptyResult(interp);
14947 if (cmdPtr->isproc) {
14948 retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
14949 }
14950 else {
@@ -14885,17 +14961,17 @@
14961
14962 int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
14963 {
14964 int i, retcode;
14965
14966
14967 for (i = 0; i < objc; i++)
14968 Jim_IncrRefCount(objv[i]);
14969
14970 retcode = JimInvokeCommand(interp, objc, objv);
14971
14972
14973 for (i = 0; i < objc; i++)
14974 Jim_DecrRefCount(interp, objv[i]);
14975
14976 return retcode;
14977 }
@@ -14913,25 +14989,25 @@
14989 }
14990
14991 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
14992 {
14993 if (!interp->errorFlag) {
14994
14995 interp->errorFlag = 1;
14996 Jim_IncrRefCount(script->fileNameObj);
14997 Jim_DecrRefCount(interp, interp->errorFileNameObj);
14998 interp->errorFileNameObj = script->fileNameObj;
14999 interp->errorLine = script->linenr;
15000
15001 JimResetStackTrace(interp);
15002
15003 interp->addStackTrace++;
15004 }
15005
15006
15007 if (interp->addStackTrace > 0) {
15008
15009
15010 JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
15011
15012 if (Jim_Length(script->fileNameObj)) {
15013 interp->addStackTrace = 0;
@@ -14966,14 +15042,14 @@
15042 case JIM_OK:
15043 case JIM_RETURN:
15044 objPtr = interp->result;
15045 break;
15046 case JIM_BREAK:
15047
15048 return JIM_BREAK;
15049 case JIM_CONTINUE:
15050
15051 return JIM_CONTINUE;
15052 default:
15053 return JIM_ERR;
15054 }
15055 break;
@@ -15008,23 +15084,23 @@
15084 case JIM_OK:
15085 case JIM_RETURN:
15086 break;
15087 case JIM_BREAK:
15088 if (flags & JIM_SUBST_FLAG) {
15089
15090 tokens = i;
15091 continue;
15092 }
15093
15094
15095 case JIM_CONTINUE:
15096 if (flags & JIM_SUBST_FLAG) {
15097 intv[i] = NULL;
15098 continue;
15099 }
15100
15101
15102 default:
15103 while (i--) {
15104 Jim_DecrRefCount(interp, intv[i]);
15105 }
15106 if (intv != sintv) {
@@ -15035,28 +15111,28 @@
15111 Jim_IncrRefCount(intv[i]);
15112 Jim_String(intv[i]);
15113 totlen += intv[i]->length;
15114 }
15115
15116
15117 if (tokens == 1 && intv[0] && intv == sintv) {
15118 Jim_DecrRefCount(interp, intv[0]);
15119 return intv[0];
15120 }
15121
15122 objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
15123
15124 if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
15125 && token[2].type == JIM_TT_VAR) {
15126
15127 objPtr->typePtr = &interpolatedObjType;
15128 objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
15129 objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
15130 Jim_IncrRefCount(intv[2]);
15131 }
15132 else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
15133
15134 JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
15135 }
15136
15137
15138 s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -15067,11 +15143,11 @@
15143 s += intv[i]->length;
15144 Jim_DecrRefCount(interp, intv[i]);
15145 }
15146 }
15147 objPtr->bytes[totlen] = '\0';
15148
15149 if (intv != sintv) {
15150 Jim_Free(intv);
15151 }
15152
15153 return objPtr;
@@ -15111,11 +15187,11 @@
15187
15188 if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
15189 return JimEvalObjList(interp, scriptObjPtr);
15190 }
15191
15192 Jim_IncrRefCount(scriptObjPtr);
15193 script = JimGetScript(interp, scriptObjPtr);
15194 if (!JimScriptValid(interp, script)) {
15195 Jim_DecrRefCount(interp, scriptObjPtr);
15196 return JIM_ERR;
15197 }
@@ -15147,11 +15223,11 @@
15223 }
15224 #endif
15225
15226 script->inUse++;
15227
15228
15229 prevScriptObj = interp->currentScriptObj;
15230 interp->currentScriptObj = scriptObjPtr;
15231
15232 interp->errorFlag = 0;
15233 argv = sargv;
@@ -15158,19 +15234,19 @@
15234
15235 for (i = 0; i < script->len && retcode == JIM_OK; ) {
15236 int argc;
15237 int j;
15238
15239
15240 argc = token[i].objPtr->internalRep.scriptLineValue.argc;
15241 script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
15242
15243
15244 if (argc > JIM_EVAL_SARGV_LEN)
15245 argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
15246
15247
15248 i++;
15249
15250 for (j = 0; j < argc; j++) {
15251 long wordtokens = 1;
15252 int expand = 0;
@@ -15226,11 +15302,11 @@
15302
15303 if (!expand) {
15304 argv[j] = wordObjPtr;
15305 }
15306 else {
15307
15308 int len = Jim_ListLength(interp, wordObjPtr);
15309 int newargc = argc + len - 1;
15310 int k;
15311
15312 if (len > 1) {
@@ -15239,39 +15315,39 @@
15315 argv = Jim_Alloc(sizeof(*argv) * newargc);
15316 memcpy(argv, sargv, sizeof(*argv) * j);
15317 }
15318 }
15319 else {
15320
15321 argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
15322 }
15323 }
15324
15325
15326 for (k = 0; k < len; k++) {
15327 argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
15328 Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
15329 }
15330
15331 Jim_DecrRefCount(interp, wordObjPtr);
15332
15333
15334 j--;
15335 argc += len - 1;
15336 }
15337 }
15338
15339 if (retcode == JIM_OK && argc) {
15340
15341 retcode = JimInvokeCommand(interp, argc, argv);
15342
15343 if (Jim_CheckSignal(interp)) {
15344 retcode = JIM_SIGNAL;
15345 }
15346 }
15347
15348
15349 while (j-- > 0) {
15350 Jim_DecrRefCount(interp, argv[j]);
15351 }
15352
15353 if (argv != sargv) {
@@ -15278,21 +15354,21 @@
15354 Jim_Free(argv);
15355 argv = sargv;
15356 }
15357 }
15358
15359
15360 if (retcode == JIM_ERR) {
15361 JimAddErrorToStack(interp, script);
15362 }
15363
15364 else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
15365
15366 interp->addStackTrace = 0;
15367 }
15368
15369
15370 interp->currentScriptObj = prevScriptObj;
15371
15372 Jim_FreeIntRep(interp, scriptObjPtr);
15373 scriptObjPtr->typePtr = &scriptObjType;
15374 Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15302,14 +15378,14 @@
15378 }
15379
15380 static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
15381 {
15382 int retcode;
15383
15384 const char *varname = Jim_String(argNameObj);
15385 if (*varname == '&') {
15386
15387 Jim_Obj *objPtr;
15388 Jim_CallFrame *savedCallFrame = interp->framePtr;
15389
15390 interp->framePtr = interp->framePtr->parent;
15391 objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15316,11 +15392,11 @@
15392 interp->framePtr = savedCallFrame;
15393 if (!objPtr) {
15394 return JIM_ERR;
15395 }
15396
15397
15398 objPtr = Jim_NewStringObj(interp, varname + 1, -1);
15399 Jim_IncrRefCount(objPtr);
15400 retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
15401 Jim_DecrRefCount(interp, objPtr);
15402 }
@@ -15330,26 +15406,26 @@
15406 return retcode;
15407 }
15408
15409 static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
15410 {
15411
15412 Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
15413 int i;
15414
15415 for (i = 0; i < cmd->u.proc.argListLen; i++) {
15416 Jim_AppendString(interp, argmsg, " ", 1);
15417
15418 if (i == cmd->u.proc.argsPos) {
15419 if (cmd->u.proc.arglist[i].defaultObjPtr) {
15420
15421 Jim_AppendString(interp, argmsg, "?", 1);
15422 Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
15423 Jim_AppendString(interp, argmsg, " ...?", -1);
15424 }
15425 else {
15426
15427 Jim_AppendString(interp, argmsg, "?arg...?", -1);
15428 }
15429 }
15430 else {
15431 if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15374,11 +15450,11 @@
15450 int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
15451 {
15452 Jim_CallFrame *callFramePtr;
15453 int retcode;
15454
15455
15456 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
15457 callFramePtr->argv = &interp->emptyObj;
15458 callFramePtr->argc = 0;
15459 callFramePtr->procArgsObjPtr = NULL;
15460 callFramePtr->procBodyObjPtr = scriptObj;
@@ -15386,21 +15462,21 @@
15462 callFramePtr->fileNameObj = interp->emptyObj;
15463 callFramePtr->line = 0;
15464 Jim_IncrRefCount(scriptObj);
15465 interp->framePtr = callFramePtr;
15466
15467
15468 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15469 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15470 retcode = JIM_ERR;
15471 }
15472 else {
15473
15474 retcode = Jim_EvalObj(interp, scriptObj);
15475 }
15476
15477
15478 interp->framePtr = interp->framePtr->parent;
15479 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15480
15481 return retcode;
15482 }
@@ -15410,62 +15486,62 @@
15486 {
15487 Jim_CallFrame *callFramePtr;
15488 int i, d, retcode, optargs;
15489 ScriptObj *script;
15490
15491
15492 if (argc - 1 < cmd->u.proc.reqArity ||
15493 (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
15494 JimSetProcWrongArgs(interp, argv[0], cmd);
15495 return JIM_ERR;
15496 }
15497
15498 if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15499
15500 return JIM_OK;
15501 }
15502
15503
15504 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15505 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15506 return JIM_ERR;
15507 }
15508
15509
15510 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
15511 callFramePtr->argv = argv;
15512 callFramePtr->argc = argc;
15513 callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
15514 callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
15515 callFramePtr->staticVars = cmd->u.proc.staticVars;
15516
15517
15518 script = JimGetScript(interp, interp->currentScriptObj);
15519 callFramePtr->fileNameObj = script->fileNameObj;
15520 callFramePtr->line = script->linenr;
15521
15522 Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
15523 Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
15524 interp->framePtr = callFramePtr;
15525
15526
15527 optargs = (argc - 1 - cmd->u.proc.reqArity);
15528
15529
15530 i = 1;
15531 for (d = 0; d < cmd->u.proc.argListLen; d++) {
15532 Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
15533 if (d == cmd->u.proc.argsPos) {
15534
15535 Jim_Obj *listObjPtr;
15536 int argsLen = 0;
15537 if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
15538 argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
15539 }
15540 listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
15541
15542
15543 if (cmd->u.proc.arglist[d].defaultObjPtr) {
15544 nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
15545 }
15546 retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
15547 if (retcode != JIM_OK) {
@@ -15474,33 +15550,33 @@
15550
15551 i += argsLen;
15552 continue;
15553 }
15554
15555
15556 if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
15557 retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
15558 }
15559 else {
15560
15561 retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
15562 }
15563 if (retcode != JIM_OK) {
15564 goto badargset;
15565 }
15566 }
15567
15568
15569 retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
15570
15571 badargset:
15572
15573
15574 interp->framePtr = interp->framePtr->parent;
15575 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15576
15577
15578 if (interp->framePtr->tailcallObj) {
15579 do {
15580 Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
15581
15582 interp->framePtr->tailcallObj = NULL;
@@ -15512,18 +15588,18 @@
15588 }
15589 }
15590 Jim_DecrRefCount(interp, tailcallObj);
15591 } while (interp->framePtr->tailcallObj);
15592
15593
15594 if (interp->framePtr->tailcallCmd) {
15595 JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
15596 interp->framePtr->tailcallCmd = NULL;
15597 }
15598 }
15599
15600
15601 if (retcode == JIM_RETURN) {
15602 if (--interp->returnLevel <= 0) {
15603 retcode = interp->returnCode;
15604 interp->returnCode = JIM_OK;
15605 interp->returnLevel = 0;
@@ -15635,20 +15711,20 @@
15711 prevScriptObj = interp->currentScriptObj;
15712 interp->currentScriptObj = scriptObjPtr;
15713
15714 retcode = Jim_EvalObj(interp, scriptObjPtr);
15715
15716
15717 if (retcode == JIM_RETURN) {
15718 if (--interp->returnLevel <= 0) {
15719 retcode = interp->returnCode;
15720 interp->returnCode = JIM_OK;
15721 interp->returnLevel = 0;
15722 }
15723 }
15724 if (retcode == JIM_ERR) {
15725
15726 interp->addStackTrace++;
15727 }
15728
15729 interp->currentScriptObj = prevScriptObj;
15730
@@ -15674,11 +15750,11 @@
15750 }
15751 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15752 if (JimParseVar(pc) == JIM_OK) {
15753 return;
15754 }
15755
15756 pc->tstart = pc->p;
15757 flags |= JIM_SUBST_NOVAR;
15758 }
15759 while (pc->len) {
15760 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15705,32 +15781,32 @@
15781 const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
15782 struct JimParserCtx parser;
15783 struct ScriptObj *script = Jim_Alloc(sizeof(*script));
15784 ParseTokenList tokenlist;
15785
15786
15787 ScriptTokenListInit(&tokenlist);
15788
15789 JimParserInit(&parser, scriptText, scriptTextLen, 1);
15790 while (1) {
15791 JimParseSubst(&parser, flags);
15792 if (parser.eof) {
15793
15794 break;
15795 }
15796 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
15797 parser.tline);
15798 }
15799
15800
15801 script->inUse = 1;
15802 script->substFlags = flags;
15803 script->fileNameObj = interp->emptyObj;
15804 Jim_IncrRefCount(script->fileNameObj);
15805 SubstObjAddTokens(interp, script, &tokenlist);
15806
15807
15808 ScriptTokenListFree(&tokenlist);
15809
15810 #ifdef DEBUG_SHOW_SUBST
15811 {
15812 int i;
@@ -15741,11 +15817,11 @@
15817 Jim_String(script->token[i].objPtr));
15818 }
15819 }
15820 #endif
15821
15822
15823 Jim_FreeIntRep(interp, objPtr);
15824 Jim_SetIntRepPtr(objPtr, script);
15825 objPtr->typePtr = &scriptObjType;
15826 return JIM_OK;
15827 }
@@ -15759,11 +15835,11 @@
15835
15836 int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
15837 {
15838 ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
15839
15840 Jim_IncrRefCount(substObjPtr);
15841 script->inUse++;
15842
15843 *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
15844
15845 script->inUse--;
@@ -15775,15 +15851,11 @@
15851 }
15852
15853 void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
15854 {
15855 Jim_Obj *objPtr;
15856 Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
 
 
 
 
15857
15858 if (*msg) {
15859 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
15860 }
15861 Jim_IncrRefCount(listObjPtr);
@@ -15804,11 +15876,11 @@
15876 JimHashtableIteratorCallbackType *callback, int type)
15877 {
15878 Jim_HashEntry *he;
15879 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
15880
15881
15882 if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
15883 he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
15884 if (he) {
15885 callback(interp, listObjPtr, he, type);
15886 }
@@ -15835,11 +15907,11 @@
15907 {
15908 Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
15909 Jim_Obj *objPtr;
15910
15911 if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
15912
15913 return;
15914 }
15915
15916 objPtr = Jim_NewStringObj(interp, he->key, -1);
15917 Jim_IncrRefCount(objPtr);
@@ -15895,11 +15967,11 @@
15967
15968 targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
15969 if (targetCallFrame == NULL) {
15970 return JIM_ERR;
15971 }
15972
15973 if (targetCallFrame == interp->topFramePtr) {
15974 Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
15975 return JIM_ERR;
15976 }
15977 if (info_level_cmd) {
@@ -16082,11 +16154,11 @@
16154 if (!objPtr)
16155 return JIM_ERR;
16156 Jim_SetResult(interp, objPtr);
16157 return JIM_OK;
16158 }
16159
16160 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
16161 return JIM_ERR;
16162 Jim_SetResult(interp, argv[2]);
16163 return JIM_OK;
16164 }
@@ -16125,11 +16197,11 @@
16197 if (argc != 3) {
16198 Jim_WrongNumArgs(interp, 1, argv, "condition body");
16199 return JIM_ERR;
16200 }
16201
16202
16203 while (1) {
16204 int boolean, retval;
16205
16206 if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
16207 return retval;
@@ -16165,11 +16237,11 @@
16237 if (argc != 5) {
16238 Jim_WrongNumArgs(interp, 1, argv, "start test next body");
16239 return JIM_ERR;
16240 }
16241
16242
16243 if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
16244 return retval;
16245 }
16246
16247 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16181,19 +16253,19 @@
16253 ExprByteCode *expr;
16254 jim_wide stop, currentVal;
16255 Jim_Obj *objPtr;
16256 int cmpOffset;
16257
16258
16259 expr = JimGetExpression(interp, argv[2]);
16260 incrScript = JimGetScript(interp, argv[3]);
16261
16262
16263 if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
16264 goto evalstart;
16265 }
16266
16267 if (incrScript->token[1].type != JIM_TT_ESC ||
16268 expr->token[0].type != JIM_TT_VAR ||
16269 (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
16270 goto evalstart;
16271 }
@@ -16206,48 +16278,48 @@
16278 }
16279 else {
16280 goto evalstart;
16281 }
16282
16283
16284 if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
16285 goto evalstart;
16286 }
16287
16288
16289 if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
16290 goto evalstart;
16291 }
16292
16293
16294 if (expr->token[1].type == JIM_TT_EXPR_INT) {
16295 if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
16296 goto evalstart;
16297 }
16298 }
16299 else {
16300 stopVarNamePtr = expr->token[1].objPtr;
16301 Jim_IncrRefCount(stopVarNamePtr);
16302
16303 stop = 0;
16304 }
16305
16306
16307 varNamePtr = expr->token[0].objPtr;
16308 Jim_IncrRefCount(varNamePtr);
16309
16310 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
16311 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &currentVal) != JIM_OK) {
16312 goto testcond;
16313 }
16314
16315
16316 while (retval == JIM_OK) {
16317
16318
16319
16320
 
 
16321 if (stopVarNamePtr) {
16322 objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
16323 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
16324 goto testcond;
16325 }
@@ -16255,18 +16327,18 @@
16327
16328 if (currentVal >= stop + cmpOffset) {
16329 break;
16330 }
16331
16332
16333 retval = Jim_EvalObj(interp, argv[4]);
16334 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16335 retval = JIM_OK;
16336
16337 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
16338
16339
16340 if (objPtr == NULL) {
16341 retval = JIM_ERR;
16342 goto out;
16343 }
16344 if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16286,25 +16358,25 @@
16358 }
16359 evalstart:
16360 #endif
16361
16362 while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
16363
16364 retval = Jim_EvalObj(interp, argv[4]);
16365
16366 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16367
16368 evalnext:
16369 retval = Jim_EvalObj(interp, argv[3]);
16370 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16371
16372 testcond:
16373 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
16374 }
16375 }
16376 }
16377 out:
16378 if (stopVarNamePtr) {
16379 Jim_DecrRefCount(interp, stopVarNamePtr);
16380 }
16381 if (varNamePtr) {
16382 Jim_DecrRefCount(interp, varNamePtr);
@@ -16346,11 +16418,11 @@
16418 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16419 Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
16420
16421 retval = JIM_OK;
16422
16423
16424 i += incr;
16425
16426 if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
16427 if (argv[1]->typePtr != &variableObjType) {
16428 if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16411,21 +16483,21 @@
16483
16484 static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
16485 {
16486 int result = JIM_OK;
16487 int i, numargs;
16488 Jim_ListIter twoiters[2];
16489 Jim_ListIter *iters;
16490 Jim_Obj *script;
16491 Jim_Obj *resultObj;
16492
16493 if (argc < 4 || argc % 2 != 0) {
16494 Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
16495 return JIM_ERR;
16496 }
16497 script = argv[argc - 1];
16498 numargs = (argc - 1 - 1);
16499
16500 if (numargs == 2) {
16501 iters = twoiters;
16502 }
16503 else {
@@ -16449,34 +16521,34 @@
16521 resultObj = interp->emptyObj;
16522 }
16523 Jim_IncrRefCount(resultObj);
16524
16525 while (1) {
16526
16527 for (i = 0; i < numargs; i += 2) {
16528 if (!JimListIterDone(interp, &iters[i + 1])) {
16529 break;
16530 }
16531 }
16532 if (i == numargs) {
16533
16534 break;
16535 }
16536
16537
16538 for (i = 0; i < numargs; i += 2) {
16539 Jim_Obj *varName;
16540
16541
16542 JimListIterInit(&iters[i], argv[i + 1]);
16543 while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
16544 Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
16545 if (!valObj) {
16546
16547 valObj = interp->emptyObj;
16548 }
16549
16550 Jim_IncrRefCount(valObj);
16551 result = Jim_SetVariable(interp, varName, valObj);
16552 Jim_DecrRefCount(interp, valObj);
16553 if (result != JIM_OK) {
16554 goto err;
@@ -16558,41 +16630,41 @@
16630 {
16631 int boolean, retval, current = 1, falsebody = 0;
16632
16633 if (argc >= 3) {
16634 while (1) {
16635
16636 if (current >= argc)
16637 goto err;
16638 if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
16639 != JIM_OK)
16640 return retval;
16641
16642 if (current >= argc)
16643 goto err;
16644 if (Jim_CompareStringImmediate(interp, argv[current], "then"))
16645 current++;
16646
16647 if (current >= argc)
16648 goto err;
16649 if (boolean)
16650 return Jim_EvalObj(interp, argv[current]);
16651
16652 if (++current >= argc) {
16653 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
16654 return JIM_OK;
16655 }
16656 falsebody = current++;
16657 if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
16658
16659 if (current != argc - 1)
16660 goto err;
16661 return Jim_EvalObj(interp, argv[current]);
16662 }
16663 else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
16664 continue;
16665
16666 else if (falsebody != argc - 1)
16667 goto err;
16668 return Jim_EvalObj(interp, argv[falsebody]);
16669 }
16670 return JIM_OK;
@@ -16700,21 +16772,21 @@
16772 if (Jim_StringMatchObj(interp, patObj, strObj, 0))
16773 script = caseList[i + 1];
16774 break;
16775 case SWITCH_RE:
16776 command = Jim_NewStringObj(interp, "regexp", -1);
16777
16778 case SWITCH_CMD:{
16779 int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
16780
16781 if (argc - opt == 1) {
16782 Jim_Obj **vector;
16783
16784 JimListGetElements(interp, argv[opt], &patCount, &vector);
16785 caseList = vector;
16786 }
16787
16788 if (rc < 0) {
16789 return -rc;
16790 }
16791 if (rc)
16792 script = caseList[i + 1];
@@ -16848,11 +16920,11 @@
16920 case OPT_COMMAND:
16921 if (i >= argc - 2) {
16922 goto wrongargs;
16923 }
16924 commandObj = argv[++i];
16925
16926 case OPT_EXACT:
16927 case OPT_GLOB:
16928 case OPT_REGEXP:
16929 opt_match = option;
16930 break;
@@ -16896,17 +16968,17 @@
16968 goto done;
16969 }
16970 break;
16971 }
16972
16973
16974 if (!eq && opt_bool && opt_not && !opt_all) {
16975 continue;
16976 }
16977
16978 if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
16979
16980 Jim_Obj *resultObj;
16981
16982 if (opt_bool) {
16983 resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
16984 }
@@ -16929,11 +17001,11 @@
17001
17002 if (opt_all) {
17003 Jim_SetResult(interp, listObjPtr);
17004 }
17005 else {
17006
17007 if (opt_bool) {
17008 Jim_SetResultBool(interp, opt_not);
17009 }
17010 else if (!opt_inline) {
17011 Jim_SetResultInt(interp, -1);
@@ -16958,11 +17030,11 @@
17030 Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
17031 return JIM_ERR;
17032 }
17033 listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
17034 if (!listObjPtr) {
17035
17036 listObjPtr = Jim_NewListObj(interp, NULL, 0);
17037 new_obj = 1;
17038 }
17039 else if (Jim_IsShared(listObjPtr)) {
17040 listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
@@ -17031,31 +17103,31 @@
17103 first = JimRelToAbsIndex(len, first);
17104 last = JimRelToAbsIndex(len, last);
17105 JimRelToAbsRange(len, &first, &last, &rangeLen);
17106
17107
17108
17109 if (first < len) {
17110
17111 }
17112 else if (len == 0) {
17113
17114 first = 0;
17115 }
17116 else {
17117 Jim_SetResultString(interp, "list doesn't contain element ", -1);
17118 Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
17119 return JIM_ERR;
17120 }
17121
17122
17123 newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
17124
17125
17126 ListInsertElements(newListObj, -1, argc - 4, argv + 4);
17127
17128
17129 ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
17130
17131 Jim_SetResult(interp, newListObj);
17132 return JIM_OK;
17133 }
@@ -17066,11 +17138,11 @@
17138 if (argc < 3) {
17139 Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
17140 return JIM_ERR;
17141 }
17142 else if (argc == 3) {
17143
17144 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
17145 return JIM_ERR;
17146 Jim_SetResult(interp, argv[2]);
17147 return JIM_OK;
17148 }
@@ -17181,11 +17253,11 @@
17253 }
17254 else {
17255 int new_obj = 0;
17256 stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
17257 if (!stringObjPtr) {
17258
17259 stringObjPtr = Jim_NewEmptyStringObj(interp);
17260 new_obj = 1;
17261 }
17262 else if (Jim_IsShared(stringObjPtr)) {
17263 new_obj = 1;
@@ -17230,11 +17302,11 @@
17302 else {
17303 rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
17304 }
17305
17306 if (rc == JIM_ERR) {
17307
17308 interp->addStackTrace++;
17309 }
17310 return rc;
17311 }
17312
@@ -17244,14 +17316,14 @@
17316 if (argc >= 2) {
17317 int retcode;
17318 Jim_CallFrame *savedCallFrame, *targetCallFrame;
17319 const char *str;
17320
17321
17322 savedCallFrame = interp->framePtr;
17323
17324
17325 str = Jim_String(argv[1]);
17326 if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
17327 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17328 argc--;
17329 argv++;
@@ -17264,11 +17336,11 @@
17336 }
17337 if (argc < 2) {
17338 Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
17339 return JIM_ERR;
17340 }
17341
17342 interp->framePtr = targetCallFrame;
17343 if (argc == 2) {
17344 retcode = Jim_EvalObj(interp, argv[1]);
17345 }
17346 else {
@@ -17366,15 +17438,15 @@
17438 if (i != argc - 1 && i != argc) {
17439 Jim_WrongNumArgs(interp, 1, argv,
17440 "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
17441 }
17442
17443
17444 if (stackTraceObj && returnCode == JIM_ERR) {
17445 JimSetStackTrace(interp, stackTraceObj);
17446 }
17447
17448 if (errorCodeObj && returnCode == JIM_ERR) {
17449 Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
17450 }
17451 interp->returnCode = returnCode;
17452 interp->returnLevel = level;
@@ -17391,31 +17463,31 @@
17463 if (interp->framePtr->level == 0) {
17464 Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
17465 return JIM_ERR;
17466 }
17467 else if (argc >= 2) {
17468
17469 Jim_CallFrame *cf = interp->framePtr->parent;
17470
17471 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17472 if (cmdPtr == NULL) {
17473 return JIM_ERR;
17474 }
17475
17476 JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
17477
17478
17479 JimIncrCmdRefCount(cmdPtr);
17480 cf->tailcallCmd = cmdPtr;
17481
17482
17483 JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
17484
17485 cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
17486 Jim_IncrRefCount(cf->tailcallObj);
17487
17488
17489 return JIM_EVAL;
17490 }
17491 return JIM_OK;
17492 }
17493
@@ -17422,11 +17494,11 @@
17494 static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17495 {
17496 Jim_Obj *cmdList;
17497 Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
17498
17499
17500 cmdList = Jim_DuplicateObj(interp, prefixListObj);
17501 Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
17502
17503 return JimEvalObjList(interp, cmdList);
17504 }
@@ -17480,22 +17552,22 @@
17552 else {
17553 cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
17554 }
17555
17556 if (cmd) {
17557
17558 Jim_Obj *qualifiedCmdNameObj;
17559 const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
17560
17561 JimCreateCommand(interp, cmdname, cmd);
17562
17563
17564 JimUpdateProcNamespace(interp, cmd, cmdname);
17565
17566 JimFreeQualifiedName(interp, qualifiedCmdNameObj);
17567
17568
17569 Jim_SetResult(interp, argv[1]);
17570 return JIM_OK;
17571 }
17572 return JIM_ERR;
17573 }
@@ -17508,17 +17580,17 @@
17580 if (argc < 2) {
17581 Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
17582 return JIM_ERR;
17583 }
17584
17585
17586 interp->local++;
17587 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17588 interp->local--;
17589
17590
17591
17592 if (retcode == 0) {
17593 Jim_Obj *cmdNameObj = Jim_GetResult(interp);
17594
17595 if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
17596 return JIM_ERR;
@@ -17547,18 +17619,18 @@
17619 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17620 if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
17621 Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
17622 return JIM_ERR;
17623 }
17624
17625 cmdPtr->u.proc.upcall++;
17626 JimIncrCmdRefCount(cmdPtr);
17627
17628
17629 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17630
17631
17632 cmdPtr->u.proc.upcall--;
17633 JimDecrCmdRefCount(interp, cmdPtr);
17634
17635 return retcode;
17636 }
@@ -17585,11 +17657,11 @@
17657 return JIM_ERR;
17658 }
17659
17660 if (len == 3) {
17661 #ifdef jim_ext_namespace
17662
17663 nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
17664 #else
17665 Jim_SetResultString(interp, "namespaces not enabled", -1);
17666 return JIM_ERR;
17667 #endif
@@ -17598,11 +17670,11 @@
17670 bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
17671
17672 cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
17673
17674 if (cmd) {
17675
17676 nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
17677 nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
17678 Jim_IncrRefCount(nargv[0]);
17679 memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
17680 ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17628,11 +17700,11 @@
17700 static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17701 {
17702 int i;
17703 Jim_CallFrame *targetCallFrame;
17704
17705
17706 if (argc > 3 && (argc % 2 == 0)) {
17707 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17708 argc--;
17709 argv++;
17710 }
@@ -17641,17 +17713,17 @@
17713 }
17714 if (targetCallFrame == NULL) {
17715 return JIM_ERR;
17716 }
17717
17718
17719 if (argc < 3) {
17720 Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
17721 return JIM_ERR;
17722 }
17723
17724
17725 for (i = 1; i < argc; i += 2) {
17726 if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
17727 return JIM_ERR;
17728 }
17729 return JIM_OK;
@@ -17664,15 +17736,15 @@
17736
17737 if (argc < 2) {
17738 Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
17739 return JIM_ERR;
17740 }
17741
17742 if (interp->framePtr->level == 0)
17743 return JIM_OK;
17744 for (i = 1; i < argc; i++) {
17745
17746 const char *name = Jim_String(argv[i]);
17747 if (name[0] != ':' || name[1] != ':') {
17748 if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
17749 return JIM_ERR;
17750 }
@@ -17695,21 +17767,21 @@
17767 }
17768
17769 str = Jim_String(objPtr);
17770 strLen = Jim_Utf8Length(interp, objPtr);
17771
17772
17773 resultObjPtr = Jim_NewStringObj(interp, "", 0);
17774 while (strLen) {
17775 for (i = 0; i < numMaps; i += 2) {
17776 Jim_Obj *objPtr;
17777 const char *k;
17778 int kl;
17779
17780 objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17781 k = Jim_String(objPtr);
17782 kl = Jim_Utf8Length(interp, objPtr);
17783
17784 if (strLen >= kl && kl) {
17785 int rc;
17786 rc = JimStringCompareLen(str, k, kl, nocase);
17787 if (rc == 0) {
@@ -17722,11 +17794,11 @@
17794 strLen -= kl;
17795 break;
17796 }
17797 }
17798 }
17799 if (i == numMaps) {
17800 int c;
17801 if (noMatchStart == NULL)
17802 noMatchStart = str;
17803 str += utf8_tounicode(str, &c);
17804 strLen--;
@@ -17787,11 +17859,11 @@
17859 return JIM_OK;
17860
17861 case OPT_CAT:{
17862 Jim_Obj *objPtr;
17863 if (argc == 3) {
17864
17865 objPtr = argv[2];
17866 }
17867 else {
17868 int i;
17869
@@ -17806,11 +17878,11 @@
17878 }
17879
17880 case OPT_COMPARE:
17881 case OPT_EQUAL:
17882 {
17883
17884 long opt_length = -1;
17885 int n = argc - 4;
17886 int i = 2;
17887 while (n > 0) {
17888 int subopt;
@@ -17819,16 +17891,16 @@
17891 badcompareargs:
17892 Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
17893 return JIM_ERR;
17894 }
17895 if (subopt == 0) {
17896
17897 opt_case = 0;
17898 n--;
17899 }
17900 else {
17901
17902 if (n < 2) {
17903 goto badcompareargs;
17904 }
17905 if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
17906 return JIM_ERR;
@@ -17839,11 +17911,11 @@
17911 if (n) {
17912 goto badcompareargs;
17913 }
17914 argv += argc - 2;
17915 if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17916
17917 Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
17918 }
17919 else {
17920 if (opt_length >= 0) {
17921 n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -17953,10 +18025,11 @@
18025 }
18026
18027 case OPT_REVERSE:{
18028 char *buf, *p;
18029 const char *str;
18030 int len;
18031 int i;
18032
18033 if (argc != 3) {
18034 Jim_WrongNumArgs(interp, 2, argv, "string");
18035 return JIM_ERR;
@@ -17996,11 +18069,11 @@
18069 }
18070 if (idx < 0 || idx >= len || str == NULL) {
18071 Jim_SetResultString(interp, "", 0);
18072 }
18073 else if (len == Jim_Length(argv[2])) {
18074
18075 Jim_SetResultString(interp, str + idx, 1);
18076 }
18077 else {
18078 int c;
18079 int i = utf8_index(str, idx);
@@ -18150,11 +18223,11 @@
18223 {
18224 int exitCode = 0;
18225 int i;
18226 int sig = 0;
18227
18228
18229 jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
18230 static const int max_ignore_code = sizeof(ignore_mask) * 8;
18231
18232 Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
18233
@@ -18161,11 +18234,11 @@
18234 for (i = 1; i < argc - 1; i++) {
18235 const char *arg = Jim_String(argv[i]);
18236 jim_wide option;
18237 int ignore;
18238
18239
18240 if (strcmp(arg, "--") == 0) {
18241 i++;
18242 break;
18243 }
18244 if (*arg != '-') {
@@ -18212,28 +18285,28 @@
18285 sig++;
18286 }
18287
18288 interp->signal_level += sig;
18289 if (Jim_CheckSignal(interp)) {
18290
18291 exitCode = JIM_SIGNAL;
18292 }
18293 else {
18294 exitCode = Jim_EvalObj(interp, argv[0]);
18295
18296 interp->errorFlag = 0;
18297 }
18298 interp->signal_level -= sig;
18299
18300
18301 if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
18302
18303 return exitCode;
18304 }
18305
18306 if (sig && exitCode == JIM_SIGNAL) {
18307
18308 if (interp->signal_set_result) {
18309 interp->signal_set_result(interp, interp->sigmask);
18310 }
18311 else {
18312 Jim_SetResultInt(interp, interp->sigmask);
@@ -18272,10 +18345,125 @@
18345 }
18346 Jim_SetResultInt(interp, exitCode);
18347 return JIM_OK;
18348 }
18349
18350 #ifdef JIM_REFERENCES
18351
18352
18353 static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18354 {
18355 if (argc != 3 && argc != 4) {
18356 Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?");
18357 return JIM_ERR;
18358 }
18359 if (argc == 3) {
18360 Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL));
18361 }
18362 else {
18363 Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3]));
18364 }
18365 return JIM_OK;
18366 }
18367
18368
18369 static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18370 {
18371 Jim_Reference *refPtr;
18372
18373 if (argc != 2) {
18374 Jim_WrongNumArgs(interp, 1, argv, "reference");
18375 return JIM_ERR;
18376 }
18377 if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18378 return JIM_ERR;
18379 Jim_SetResult(interp, refPtr->objPtr);
18380 return JIM_OK;
18381 }
18382
18383
18384 static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18385 {
18386 Jim_Reference *refPtr;
18387
18388 if (argc != 3) {
18389 Jim_WrongNumArgs(interp, 1, argv, "reference newValue");
18390 return JIM_ERR;
18391 }
18392 if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18393 return JIM_ERR;
18394 Jim_IncrRefCount(argv[2]);
18395 Jim_DecrRefCount(interp, refPtr->objPtr);
18396 refPtr->objPtr = argv[2];
18397 Jim_SetResult(interp, argv[2]);
18398 return JIM_OK;
18399 }
18400
18401
18402 static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18403 {
18404 if (argc != 1) {
18405 Jim_WrongNumArgs(interp, 1, argv, "");
18406 return JIM_ERR;
18407 }
18408 Jim_SetResultInt(interp, Jim_Collect(interp));
18409
18410
18411 while (interp->freeList) {
18412 Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr;
18413 Jim_Free(interp->freeList);
18414 interp->freeList = nextObjPtr;
18415 }
18416
18417 return JIM_OK;
18418 }
18419
18420
18421 static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18422 {
18423 if (argc != 2 && argc != 3) {
18424 Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?");
18425 return JIM_ERR;
18426 }
18427 if (argc == 2) {
18428 Jim_Obj *cmdNamePtr;
18429
18430 if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK)
18431 return JIM_ERR;
18432 if (cmdNamePtr != NULL)
18433 Jim_SetResult(interp, cmdNamePtr);
18434 }
18435 else {
18436 if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK)
18437 return JIM_ERR;
18438 Jim_SetResult(interp, argv[2]);
18439 }
18440 return JIM_OK;
18441 }
18442
18443
18444 static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18445 {
18446 Jim_Obj *listObjPtr;
18447 Jim_HashTableIterator htiter;
18448 Jim_HashEntry *he;
18449
18450 listObjPtr = Jim_NewListObj(interp, NULL, 0);
18451
18452 JimInitHashTableIterator(&interp->references, &htiter);
18453 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18454 char buf[JIM_REFERENCE_SPACE + 1];
18455 Jim_Reference *refPtr = Jim_GetHashEntryVal(he);
18456 const unsigned long *refId = he->key;
18457
18458 JimFormatReference(buf, refPtr, *refId);
18459 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
18460 }
18461 Jim_SetResult(interp, listObjPtr);
18462 return JIM_OK;
18463 }
18464 #endif
18465
18466
18467 static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18468 {
18469 if (argc != 3) {
@@ -18306,11 +18494,11 @@
18494 JimDictMatchCallbackType *callback, int type)
18495 {
18496 Jim_HashEntry *he;
18497 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
18498
18499
18500 Jim_HashTableIterator htiter;
18501 JimInitHashTableIterator(ht, &htiter);
18502 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18503 if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
18504 callback(interp, listObjPtr, he, type);
@@ -18356,11 +18544,11 @@
18544 return JIM_ERR;
18545 }
18546
18547 ht = (Jim_HashTable *)objPtr->internalRep.ptr;
18548
18549
18550 printf("%d entries in table, %d buckets\n", ht->used, ht->size);
18551
18552 for (i = 0; i < ht->size; i++) {
18553 Jim_HashEntry *he = ht->table[i];
18554
@@ -18480,16 +18668,16 @@
18668 return JIM_OK;
18669 }
18670 if (Jim_DictSize(interp, argv[2]) < 0) {
18671 return JIM_ERR;
18672 }
18673
18674 break;
18675
18676 case OPT_UPDATE:
18677 if (argc < 6 || argc % 2) {
18678
18679 argc = 2;
18680 }
18681 break;
18682
18683 case OPT_CREATE:
@@ -18506,11 +18694,11 @@
18694 Jim_WrongNumArgs(interp, 2, argv, "dictionary");
18695 return JIM_ERR;
18696 }
18697 return Jim_DictInfo(interp, argv[2]);
18698 }
18699
18700 return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
18701 }
18702
18703
18704 static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18576,11 +18764,11 @@
18764
18765 #ifdef jim_ext_namespace
18766 int nons = 0;
18767
18768 if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18769
18770 argc--;
18771 argv++;
18772 nons = 1;
18773 }
18774 #endif
@@ -18592,11 +18780,11 @@
18780 if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
18781 != JIM_OK) {
18782 return JIM_ERR;
18783 }
18784
18785
18786 switch (cmd) {
18787 case INFO_EXISTS:
18788 if (argc != 3) {
18789 Jim_WrongNumArgs(interp, 2, argv, "varName");
18790 return JIM_ERR;
@@ -18621,21 +18809,21 @@
18809 Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
18810 return JIM_OK;
18811 }
18812
18813 case INFO_CHANNELS:
18814 mode++;
18815 #ifndef jim_ext_aio
18816 Jim_SetResultString(interp, "aio not enabled", -1);
18817 return JIM_ERR;
18818 #endif
18819
18820 case INFO_PROCS:
18821 mode++;
18822
18823 case INFO_COMMANDS:
18824
18825 if (argc != 2 && argc != 3) {
18826 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18827 return JIM_ERR;
18828 }
18829 #ifdef jim_ext_namespace
@@ -18647,17 +18835,17 @@
18835 #endif
18836 Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
18837 break;
18838
18839 case INFO_VARS:
18840 mode++;
18841
18842 case INFO_LOCALS:
18843 mode++;
18844
18845 case INFO_GLOBALS:
18846
18847 if (argc != 2 && argc != 3) {
18848 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18849 return JIM_ERR;
18850 }
18851 #ifdef jim_ext_namespace
@@ -18763,12 +18951,13 @@
18951 case INFO_ARGS:
18952 Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
18953 break;
18954 case INFO_STATICS:
18955 if (cmdPtr->u.proc.staticVars) {
18956 int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
18957 Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
18958 NULL, JimVariablesMatch, mode));
18959 }
18960 break;
18961 }
18962 break;
18963 }
@@ -18796,15 +18985,15 @@
18985 }
18986 }
18987 break;
18988
18989 case INFO_HOSTNAME:
18990
18991 return Jim_Eval(interp, "os.gethostname");
18992
18993 case INFO_NAMEOFEXECUTABLE:
18994
18995 return Jim_Eval(interp, "{info nameofexecutable}");
18996
18997 case INFO_RETURNCODES:
18998 if (argc == 2) {
18999 int i;
@@ -18881,11 +19070,11 @@
19070
19071 if (option == OPT_VAR) {
19072 result = Jim_GetVariable(interp, objPtr, 0) != NULL;
19073 }
19074 else {
19075
19076 Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
19077
19078 if (cmd) {
19079 switch (option) {
19080 case OPT_COMMAND:
@@ -18924,11 +19113,11 @@
19113 if (len == 0) {
19114 return JIM_OK;
19115 }
19116 strLen = Jim_Utf8Length(interp, argv[1]);
19117
19118
19119 if (argc == 2) {
19120 splitChars = " \n\t\r";
19121 splitLen = 4;
19122 }
19123 else {
@@ -18937,11 +19126,11 @@
19126 }
19127
19128 noMatchStart = str;
19129 resObjPtr = Jim_NewListObj(interp, NULL, 0);
19130
19131
19132 if (splitLen) {
19133 Jim_Obj *objPtr;
19134 while (strLen--) {
19135 const char *sc = splitChars;
19136 int scLen = splitLen;
@@ -18966,11 +19155,11 @@
19155 #define NUM_COMMON (128 - 9)
19156 while (strLen--) {
19157 int n = utf8_tounicode(str, &c);
19158 #ifdef JIM_OPTIMIZATION
19159 if (c >= 9 && c < 128) {
19160
19161 c -= 9;
19162 if (!commonObj) {
19163 commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
19164 memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
19165 }
@@ -19000,11 +19189,11 @@
19189
19190 if (argc != 2 && argc != 3) {
19191 Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
19192 return JIM_ERR;
19193 }
19194
19195 if (argc == 2) {
19196 joinStr = " ";
19197 joinStrLen = 1;
19198 }
19199 else {
@@ -19279,13 +19468,13 @@
19468 return -1;
19469 else if (step < 0 && end > start)
19470 return -1;
19471 len = end - start;
19472 if (len < 0)
19473 len = -len;
19474 if (step < 0)
19475 step = -step;
19476 len = 1 + ((len - 1) / step);
19477 if (len > INT_MAX)
19478 len = INT_MAX;
19479 return (int)((len < 0) ? -1 : len);
19480 }
@@ -19499,11 +19688,11 @@
19688
19689 *indexPtr = -1;
19690
19691 for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
19692 if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
19693
19694 *indexPtr = i;
19695 return JIM_OK;
19696 }
19697 if (flags & JIM_ENUM_ABBREV) {
19698 if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19517,11 +19706,11 @@
19706 match = i;
19707 }
19708 }
19709 }
19710
19711
19712 if (match >= 0) {
19713 *indexPtr = match;
19714 return JIM_OK;
19715 }
19716
@@ -19554,11 +19743,11 @@
19743 return objPtr->typePtr == &listObjType;
19744 }
19745
19746 void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
19747 {
19748
19749 int len = strlen(format);
19750 int extra = 0;
19751 int n = 0;
19752 const char *params[5];
19753 char *buf;
@@ -19619,11 +19808,11 @@
19808 #include <string.h>
19809
19810
19811 static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19812 {
19813
19814 return JIM_OK;
19815 }
19816
19817 static const jim_subcmd_type dummy_subcmd = {
19818 "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19698,43 +19887,43 @@
19887 return 0;
19888 }
19889
19890 cmd = argv[1];
19891
19892
19893 if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
19894 if (argc == 2) {
19895
19896 show_cmd_usage(interp, command_table, argc, argv);
19897 return &dummy_subcmd;
19898 }
19899 help = 1;
19900
19901
19902 cmd = argv[2];
19903 }
19904
19905
19906 if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
19907
19908 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
19909 add_commands(interp, command_table, " ");
19910 return &dummy_subcmd;
19911 }
19912
19913 cmdstr = Jim_GetString(cmd, &cmdlen);
19914
19915 for (ct = command_table; ct->cmd; ct++) {
19916 if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
19917
19918 break;
19919 }
19920 if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
19921 if (partial) {
19922
19923 if (help) {
19924
19925 show_cmd_usage(interp, command_table, argc, argv);
19926 return &dummy_subcmd;
19927 }
19928 bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
19929 return 0;
@@ -19742,44 +19931,44 @@
19931 partial = ct;
19932 }
19933 continue;
19934 }
19935
19936
19937 if (partial && !ct->cmd) {
19938 ct = partial;
19939 }
19940
19941 if (!ct->cmd) {
19942
19943 if (help) {
19944
19945 show_cmd_usage(interp, command_table, argc, argv);
19946 return &dummy_subcmd;
19947 }
19948 bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
19949 return 0;
19950 }
19951
19952 if (help) {
19953 Jim_SetResultString(interp, "Usage: ", -1);
19954
19955 add_cmd_usage(interp, ct, argv[0]);
19956 return &dummy_subcmd;
19957 }
19958
19959
19960 if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
19961 Jim_SetResultString(interp, "wrong # args: should be \"", -1);
19962
19963 add_cmd_usage(interp, ct, argv[0]);
19964 Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
19965
19966 return 0;
19967 }
19968
19969
19970 return ct;
19971 }
19972
19973 int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
19974 {
@@ -19830,11 +20019,11 @@
20019 *p++ = 0xe0 | ((uc & 0xf000) >> 12);
20020 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
20021 *p = 0x80 | (uc & 0x3f);
20022 return 3;
20023 }
20024
20025 else {
20026 *p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
20027 *p++ = 0x80 | ((uc & 0x3f000) >> 12);
20028 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
20029 *p = 0x80 | (uc & 0x3f);
@@ -20021,11 +20210,11 @@
20210 if (ch == 'h') {
20211 useShort = 1;
20212 format += step;
20213 step = utf8_tounicode(format, &ch);
20214 } else if (ch == 'l') {
20215
20216 format += step;
20217 step = utf8_tounicode(format, &ch);
20218 if (ch == 'l') {
20219 format += step;
20220 step = utf8_tounicode(format, &ch);
@@ -20048,11 +20237,11 @@
20237 goto errorMsg;
20238 case 's': {
20239 formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
20240 formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
20241 if (gotPrecision && (precision < formatted_chars)) {
20242
20243 formatted_chars = precision;
20244 formatted_bytes = utf8_index(formatted_buf, precision);
20245 }
20246 break;
20247 }
@@ -20060,11 +20249,11 @@
20249 jim_wide code;
20250
20251 if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
20252 goto error;
20253 }
20254
20255 formatted_bytes = utf8_getchars(spec, code);
20256 formatted_buf = spec;
20257 formatted_chars = 1;
20258 break;
20259 }
@@ -20078,11 +20267,11 @@
20267 goto error;
20268 }
20269 length = sizeof(w) * 8;
20270
20271
20272
20273 if (num_buffer_size < length + 1) {
20274 num_buffer_size = length + 1;
20275 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20276 }
20277
@@ -20106,29 +20295,29 @@
20295 case 'E':
20296 case 'f':
20297 case 'g':
20298 case 'G':
20299 doubleType = 1;
20300
20301 case 'd':
20302 case 'u':
20303 case 'o':
20304 case 'x':
20305 case 'X': {
20306 jim_wide w;
20307 double d;
20308 int length;
20309
20310
20311 if (width) {
20312 p += sprintf(p, "%ld", width);
20313 }
20314 if (gotPrecision) {
20315 p += sprintf(p, ".%ld", precision);
20316 }
20317
20318
20319 if (doubleType) {
20320 if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
20321 goto error;
20322 }
20323 length = MAX_FLOAT_WIDTH;
@@ -20155,19 +20344,19 @@
20344 }
20345
20346 *p++ = (char) ch;
20347 *p = '\0';
20348
20349
20350 if (width > length) {
20351 length = width;
20352 }
20353 if (gotPrecision) {
20354 length += precision;
20355 }
20356
20357
20358 if (num_buffer_size < length + 1) {
20359 num_buffer_size = length + 1;
20360 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20361 }
20362
@@ -20181,11 +20370,11 @@
20370 formatted_buf = num_buffer;
20371 break;
20372 }
20373
20374 default: {
20375
20376 spec[0] = ch;
20377 spec[1] = '\0';
20378 Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
20379 goto error;
20380 }
@@ -20233,37 +20422,37 @@
20422
20423 #define REG_MAX_PAREN 100
20424
20425
20426
20427 #define END 0
20428 #define BOL 1
20429 #define EOL 2
20430 #define ANY 3
20431 #define ANYOF 4
20432 #define ANYBUT 5
20433 #define BRANCH 6
20434 #define BACK 7
20435 #define EXACTLY 8
20436 #define NOTHING 9
20437 #define REP 10
20438 #define REPMIN 11
20439 #define REPX 12
20440 #define REPXMIN 13
20441 #define BOLX 14
20442 #define EOLX 15
20443 #define WORDA 16
20444 #define WORDZ 17
20445
20446 #define OPENNC 1000
20447 #define OPEN 1001
20448
20449
20450
20451
20452 #define CLOSENC 2000
20453 #define CLOSE 2001
20454 #define CLOSE_END (CLOSE+REG_MAX_PAREN)
20455
20456 #define REG_MAGIC 0xFADED00D
20457
20458
@@ -20276,18 +20465,18 @@
20465
20466 #define FAIL(R,M) { (R)->err = (M); return (M); }
20467 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
20468 #define META "^$.[()|?{+*"
20469
20470 #define HASWIDTH 1
20471 #define SIMPLE 2
20472 #define SPSTART 4
20473 #define WORST 0
20474
20475 #define MAX_REP_COUNT 1000000
20476
20477 static int reg(regex_t *preg, int paren , int *flagp );
20478 static int regpiece(regex_t *preg, int *flagp );
20479 static int regbranch(regex_t *preg, int *flagp );
20480 static int regatom(regex_t *preg, int *flagp );
20481 static int regnode(regex_t *preg, int op );
20482 static int regnext(regex_t *preg, int p );
@@ -20331,15 +20520,15 @@
20520 memset(preg, 0, sizeof(*preg));
20521
20522 if (exp == NULL)
20523 FAIL(preg, REG_ERR_NULL_ARGUMENT);
20524
20525
20526 preg->cflags = cflags;
20527 preg->regparse = exp;
20528
20529
20530 preg->proglen = (strlen(exp) + 1) * 5;
20531 preg->program = malloc(preg->proglen * sizeof(int));
20532 if (preg->program == NULL)
20533 FAIL(preg, REG_ERR_NOMEM);
20534
@@ -20346,24 +20535,24 @@
20535 regc(preg, REG_MAGIC);
20536 if (reg(preg, 0, &flags) == 0) {
20537 return preg->err;
20538 }
20539
20540
20541 if (preg->re_nsub >= REG_MAX_PAREN)
20542 FAIL(preg,REG_ERR_TOO_BIG);
20543
20544
20545 preg->regstart = 0;
20546 preg->reganch = 0;
20547 preg->regmust = 0;
20548 preg->regmlen = 0;
20549 scan = 1;
20550 if (OP(preg, regnext(preg, scan)) == END) {
20551 scan = OPERAND(scan);
20552
20553
20554 if (OP(preg, scan) == EXACTLY) {
20555 preg->regstart = preg->program[OPERAND(scan)];
20556 }
20557 else if (OP(preg, scan) == BOL)
20558 preg->reganch++;
@@ -20390,24 +20579,24 @@
20579 #endif
20580
20581 return 0;
20582 }
20583
20584 static int reg(regex_t *preg, int paren , int *flagp )
20585 {
20586 int ret;
20587 int br;
20588 int ender;
20589 int parno = 0;
20590 int flags;
20591
20592 *flagp = HASWIDTH;
20593
20594
20595 if (paren) {
20596 if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
20597
20598 preg->regparse += 2;
20599 parno = -1;
20600 }
20601 else {
20602 parno = ++preg->re_nsub;
@@ -20414,16 +20603,16 @@
20603 }
20604 ret = regnode(preg, OPEN+parno);
20605 } else
20606 ret = 0;
20607
20608
20609 br = regbranch(preg, &flags);
20610 if (br == 0)
20611 return 0;
20612 if (ret != 0)
20613 regtail(preg, ret, br);
20614 else
20615 ret = br;
20616 if (!(flags&HASWIDTH))
20617 *flagp &= ~HASWIDTH;
20618 *flagp |= flags&SPSTART;
@@ -20430,25 +20619,25 @@
20619 while (*preg->regparse == '|') {
20620 preg->regparse++;
20621 br = regbranch(preg, &flags);
20622 if (br == 0)
20623 return 0;
20624 regtail(preg, ret, br);
20625 if (!(flags&HASWIDTH))
20626 *flagp &= ~HASWIDTH;
20627 *flagp |= flags&SPSTART;
20628 }
20629
20630
20631 ender = regnode(preg, (paren) ? CLOSE+parno : END);
20632 regtail(preg, ret, ender);
20633
20634
20635 for (br = ret; br != 0; br = regnext(preg, br))
20636 regoptail(preg, br, ender);
20637
20638
20639 if (paren && *preg->regparse++ != ')') {
20640 preg->err = REG_ERR_UNMATCHED_PAREN;
20641 return 0;
20642 } else if (!paren && *preg->regparse != '\0') {
20643 if (*preg->regparse == ')') {
@@ -20468,11 +20657,11 @@
20657 int ret;
20658 int chain;
20659 int latest;
20660 int flags;
20661
20662 *flagp = WORST;
20663
20664 ret = regnode(preg, BRANCH);
20665 chain = 0;
20666 while (*preg->regparse != '\0' && *preg->regparse != ')' &&
20667 *preg->regparse != '|') {
@@ -20486,11 +20675,11 @@
20675 else {
20676 regtail(preg, chain, latest);
20677 }
20678 chain = latest;
20679 }
20680 if (chain == 0)
20681 (void) regnode(preg, NOTHING);
20682
20683 return(ret);
20684 }
20685
@@ -20516,11 +20705,11 @@
20705 if (!(flags&HASWIDTH) && op != '?') {
20706 preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
20707 return 0;
20708 }
20709
20710
20711 if (op == '{') {
20712 char *end;
20713
20714 min = strtoul(preg->regparse + 1, &end, 10);
20715 if (end == preg->regparse + 1) {
@@ -20588,11 +20777,11 @@
20777 static void reg_addrange(regex_t *preg, int lower, int upper)
20778 {
20779 if (lower > upper) {
20780 reg_addrange(preg, upper, lower);
20781 }
20782
20783 regc(preg, upper - lower + 1);
20784 regc(preg, lower);
20785 }
20786
20787 static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20656,17 +20845,17 @@
20845 case 'r': *ch = '\r'; break;
20846 case 't': *ch = '\t'; break;
20847 case 'v': *ch = '\v'; break;
20848 case 'u':
20849 if (*s == '{') {
20850
20851 n = parse_hex(s + 1, 6, ch);
20852 if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
20853 s += n + 2;
20854 }
20855 else {
20856
20857 *ch = 'u';
20858 }
20859 }
20860 else if ((n = parse_hex(s, 4, ch)) > 0) {
20861 s += n;
@@ -20697,15 +20886,15 @@
20886 int nocase = (preg->cflags & REG_ICASE);
20887
20888 int ch;
20889 int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
20890
20891 *flagp = WORST;
20892
20893 preg->regparse += n;
20894 switch (ch) {
20895
20896 case '^':
20897 ret = regnode(preg, BOL);
20898 break;
20899 case '$':
20900 ret = regnode(preg, EOL);
@@ -20715,24 +20904,24 @@
20904 *flagp |= HASWIDTH|SIMPLE;
20905 break;
20906 case '[': {
20907 const char *pattern = preg->regparse;
20908
20909 if (*pattern == '^') {
20910 ret = regnode(preg, ANYBUT);
20911 pattern++;
20912 } else
20913 ret = regnode(preg, ANYOF);
20914
20915
20916 if (*pattern == ']' || *pattern == '-') {
20917 reg_addrange(preg, *pattern, *pattern);
20918 pattern++;
20919 }
20920
20921 while (*pattern && *pattern != ']') {
20922
20923 int start;
20924 int end;
20925
20926 pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
20927 if (start == '\\') {
@@ -20741,11 +20930,11 @@
20930 preg->err = REG_ERR_NULL_CHAR;
20931 return 0;
20932 }
20933 }
20934 if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
20935
20936 pattern += utf8_tounicode(pattern, &end);
20937 pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
20938 if (end == '\\') {
20939 pattern += reg_decode_escape(pattern, &end);
20940 if (end == 0) {
@@ -20768,22 +20957,22 @@
20957 CC_NUM
20958 };
20959 int i;
20960
20961 for (i = 0; i < CC_NUM; i++) {
20962 int n = strlen(character_class[i]);
20963 if (strncmp(pattern, character_class[i], n) == 0) {
20964
20965 pattern += n + 1;
20966 break;
20967 }
20968 }
20969 if (i != CC_NUM) {
20970 switch (i) {
20971 case CC_ALNUM:
20972 reg_addrange(preg, '0', '9');
20973
20974 case CC_ALPHA:
20975 if ((preg->cflags & REG_ICASE) == 0) {
20976 reg_addrange(preg, 'a', 'z');
20977 }
20978 reg_addrange(preg, 'A', 'Z');
@@ -20801,11 +20990,11 @@
20990 reg_addrange(preg, 'a', 'z');
20991 break;
20992 case CC_XDIGIT:
20993 reg_addrange(preg, 'a', 'f');
20994 reg_addrange(preg, 'A', 'F');
20995
20996 case CC_DIGIT:
20997 reg_addrange(preg, '0', '9');
20998 break;
20999 case CC_CNTRL:
21000 reg_addrange(preg, 0, 31);
@@ -20825,11 +21014,11 @@
21014 break;
21015 }
21016 continue;
21017 }
21018 }
21019
21020 reg_addrange(preg, start, start);
21021 }
21022 regc(preg, '\0');
21023
21024 if (*pattern) {
@@ -20848,11 +21037,11 @@
21037 break;
21038 case '\0':
21039 case '|':
21040 case ')':
21041 preg->err = REG_ERR_INTERNAL;
21042 return 0;
21043 case '?':
21044 case '+':
21045 case '*':
21046 case '{':
21047 preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
@@ -20901,34 +21090,34 @@
21090 ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT);
21091 reg_addrange_str(preg," \t\r\n\f\v");
21092 regc(preg, '\0');
21093 *flagp |= HASWIDTH|SIMPLE;
21094 break;
21095
21096 default:
21097
21098
21099 preg->regparse--;
21100 goto de_fault;
21101 }
21102 break;
21103 de_fault:
21104 default: {
21105 int added = 0;
21106
21107
21108 preg->regparse -= n;
21109
21110 ret = regnode(preg, EXACTLY);
21111
21112
21113
21114 while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
21115 n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
21116 if (ch == '\\' && preg->regparse[n]) {
21117 if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) {
21118
21119 break;
21120 }
21121 n += reg_decode_escape(preg->regparse + n, &ch);
21122 if (ch == 0) {
21123 preg->err = REG_ERR_NULL_CHAR;
@@ -20936,23 +21125,23 @@
21125 }
21126 }
21127
21128
21129 if (ISMULT(preg->regparse[n])) {
21130
21131 if (added) {
21132
21133 break;
21134 }
21135
21136 regc(preg, ch);
21137 added++;
21138 preg->regparse += n;
21139 break;
21140 }
21141
21142
21143 regc(preg, ch);
21144 added++;
21145 preg->regparse += n;
21146 }
21147 regc(preg, '\0');
@@ -20979,15 +21168,15 @@
21168
21169 static int regnode(regex_t *preg, int op)
21170 {
21171 reg_grow(preg, 2);
21172
21173
21174 preg->program[preg->p++] = op;
21175 preg->program[preg->p++] = 0;
21176
21177
21178 return preg->p - 2;
21179 }
21180
21181 static void regc(regex_t *preg, int b )
21182 {
@@ -20997,13 +21186,13 @@
21186
21187 static int reginsert(regex_t *preg, int op, int size, int opnd )
21188 {
21189 reg_grow(preg, size);
21190
21191
21192 memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
21193
21194 memset(preg->program + opnd, 0, sizeof(int) * size);
21195
21196 preg->program[opnd] = op;
21197
21198 preg->p += size;
@@ -21015,11 +21204,11 @@
21204 {
21205 int scan;
21206 int temp;
21207 int offset;
21208
21209
21210 scan = p;
21211 for (;;) {
21212 temp = regnext(preg, scan);
21213 if (temp == 0)
21214 break;
@@ -21035,11 +21224,11 @@
21224 }
21225
21226
21227 static void regoptail(regex_t *preg, int p, int val )
21228 {
21229
21230 if (p != 0 && OP(preg, p) == BRANCH) {
21231 regtail(preg, OPERAND(p), val);
21232 }
21233 }
21234
@@ -21051,16 +21240,16 @@
21240 int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
21241 {
21242 const char *s;
21243 int scan;
21244
21245
21246 if (preg == NULL || preg->program == NULL || string == NULL) {
21247 return REG_ERR_NULL_ARGUMENT;
21248 }
21249
21250
21251 if (*preg->program != REG_MAGIC) {
21252 return REG_ERR_CORRUPTED;
21253 }
21254
21255 #ifdef DEBUG
@@ -21069,51 +21258,51 @@
21258 #endif
21259
21260 preg->eflags = eflags;
21261 preg->pmatch = pmatch;
21262 preg->nmatch = nmatch;
21263 preg->start = string;
21264
21265
21266 for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
21267 int op = OP(preg, scan);
21268 if (op == END)
21269 break;
21270 if (op == REPX || op == REPXMIN)
21271 preg->program[scan + 4] = 0;
21272 }
21273
21274
21275 if (preg->regmust != 0) {
21276 s = string;
21277 while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
21278 if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
21279 break;
21280 }
21281 s++;
21282 }
21283 if (s == NULL)
21284 return REG_NOMATCH;
21285 }
21286
21287
21288 preg->regbol = string;
21289
21290
21291 if (preg->reganch) {
21292 if (eflags & REG_NOTBOL) {
21293
21294 goto nextline;
21295 }
21296 while (1) {
21297 if (regtry(preg, string)) {
21298 return REG_NOERROR;
21299 }
21300 if (*string) {
21301 nextline:
21302 if (preg->cflags & REG_NEWLINE) {
21303
21304 string = strchr(string, '\n');
21305 if (string) {
21306 preg->regbol = ++string;
21307 continue;
21308 }
@@ -21121,22 +21310,22 @@
21310 }
21311 return REG_NOMATCH;
21312 }
21313 }
21314
21315
21316 s = string;
21317 if (preg->regstart != '\0') {
21318
21319 while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
21320 if (regtry(preg, s))
21321 return REG_NOERROR;
21322 s++;
21323 }
21324 }
21325 else
21326
21327 while (1) {
21328 if (regtry(preg, s))
21329 return REG_NOERROR;
21330 if (*s == '\0') {
21331 break;
@@ -21145,15 +21334,15 @@
21334 int c;
21335 s += utf8_tounicode(s, &c);
21336 }
21337 }
21338
21339
21340 return REG_NOMATCH;
21341 }
21342
21343
21344 static int regtry( regex_t *preg, const char *string )
21345 {
21346 int i;
21347
21348 preg->reginput = string;
@@ -21190,11 +21379,11 @@
21379 }
21380
21381 static int reg_range_find(const int *range, int c)
21382 {
21383 while (*range) {
21384
21385 if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
21386 return 1;
21387 }
21388 range += 2;
21389 }
@@ -21202,11 +21391,11 @@
21391 }
21392
21393 static const char *str_find(const char *string, int c, int nocase)
21394 {
21395 if (nocase) {
21396
21397 c = utf8_upper(c);
21398 }
21399 while (*string) {
21400 int ch;
21401 int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21246,15 +21435,15 @@
21435 no = regrepeat(preg, scan + 5, max);
21436 if (no < min) {
21437 return 0;
21438 }
21439 if (matchmin) {
21440
21441 max = no;
21442 no = min;
21443 }
21444
21445 while (1) {
21446 if (matchmin) {
21447 if (no > max) {
21448 break;
21449 }
@@ -21264,22 +21453,22 @@
21453 break;
21454 }
21455 }
21456 preg->reginput = save + utf8_index(save, no);
21457 reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21458
21459 if (reg_iseol(preg, nextch) || c == nextch) {
21460 if (regmatch(preg, next)) {
21461 return(1);
21462 }
21463 }
21464 if (matchmin) {
21465
21466 no++;
21467 }
21468 else {
21469
21470 no--;
21471 }
21472 }
21473 return(0);
21474 }
@@ -21289,13 +21478,13 @@
21478 int *scanpt = preg->program + scan;
21479
21480 int max = scanpt[2];
21481 int min = scanpt[3];
21482
21483
21484 if (scanpt[4] < min) {
21485
21486 scanpt[4]++;
21487 if (regmatch(preg, scan + 5)) {
21488 return 1;
21489 }
21490 scanpt[4]--;
@@ -21304,39 +21493,39 @@
21493 if (scanpt[4] > max) {
21494 return 0;
21495 }
21496
21497 if (matchmin) {
21498
21499 if (regmatch(preg, regnext(preg, scan))) {
21500 return 1;
21501 }
21502
21503 scanpt[4]++;
21504 if (regmatch(preg, scan + 5)) {
21505 return 1;
21506 }
21507 scanpt[4]--;
21508 return 0;
21509 }
21510
21511 if (scanpt[4] < max) {
21512 scanpt[4]++;
21513 if (regmatch(preg, scan + 5)) {
21514 return 1;
21515 }
21516 scanpt[4]--;
21517 }
21518
21519 return regmatch(preg, regnext(preg, scan));
21520 }
21521
21522
21523 static int regmatch(regex_t *preg, int prog)
21524 {
21525 int scan;
21526 int next;
21527 const char *save;
21528
21529 scan = prog;
21530
21531 #ifdef DEBUG
@@ -21346,11 +21535,11 @@
21535 while (scan != 0) {
21536 int n;
21537 int c;
21538 #ifdef DEBUG
21539 if (regnarrate) {
21540 fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
21541 }
21542 #endif
21543 next = regnext(preg, scan);
21544 n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21545
@@ -21357,49 +21546,49 @@
21546 switch (OP(preg, scan)) {
21547 case BOLX:
21548 if ((preg->eflags & REG_NOTBOL)) {
21549 return(0);
21550 }
21551
21552 case BOL:
21553 if (preg->reginput != preg->regbol) {
21554 return(0);
21555 }
21556 break;
21557 case EOLX:
21558 if (c != 0) {
21559
21560 return 0;
21561 }
21562 break;
21563 case EOL:
21564 if (!reg_iseol(preg, c)) {
21565 return(0);
21566 }
21567 break;
21568 case WORDA:
21569
21570 if ((!isalnum(UCHAR(c))) && c != '_')
21571 return(0);
21572
21573 if (preg->reginput > preg->regbol &&
21574 (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
21575 return(0);
21576 break;
21577 case WORDZ:
21578
21579 if (preg->reginput > preg->regbol) {
21580
21581 if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
21582 c = preg->reginput[-1];
21583
21584 if (isalnum(UCHAR(c)) || c == '_') {
21585 break;
21586 }
21587 }
21588 }
21589
21590 return(0);
21591
21592 case ANY:
21593 if (reg_iseol(preg, c))
21594 return 0;
@@ -21435,12 +21624,12 @@
21624 case NOTHING:
21625 break;
21626 case BACK:
21627 break;
21628 case BRANCH:
21629 if (OP(preg, next) != BRANCH)
21630 next = OPERAND(scan);
21631 else {
21632 do {
21633 save = preg->reginput;
21634 if (regmatch(preg, OPERAND(scan))) {
21635 return(1);
@@ -21447,11 +21636,11 @@
21636 }
21637 preg->reginput = save;
21638 scan = regnext(preg, scan);
21639 } while (scan != 0 && OP(preg, scan) == BRANCH);
21640 return(0);
21641
21642 }
21643 break;
21644 case REP:
21645 case REPMIN:
21646 return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21459,11 +21648,11 @@
21648 case REPX:
21649 case REPXMIN:
21650 return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
21651
21652 case END:
21653 return 1;
21654
21655 case OPENNC:
21656 case CLOSENC:
21657 return regmatch(preg, next);
21658
@@ -21506,11 +21695,11 @@
21695
21696 scan = preg->reginput;
21697 opnd = OPERAND(p);
21698 switch (OP(preg, p)) {
21699 case ANY:
21700
21701 while (!reg_iseol(preg, *scan) && count < max) {
21702 count++;
21703 scan++;
21704 }
21705 break;
@@ -21542,13 +21731,13 @@
21731 }
21732 count++;
21733 scan += n;
21734 }
21735 break;
21736 default:
21737 preg->err = REG_ERR_INTERNAL;
21738 count = 0;
21739 break;
21740 }
21741 preg->reginput = scan;
21742
21743 return(count);
@@ -21569,11 +21758,11 @@
21758 return(p+offset);
21759 }
21760
21761 static int regopsize(regex_t *preg, int p )
21762 {
21763
21764 switch (OP(preg, p)) {
21765 case REP:
21766 case REPMIN:
21767 case REPX:
21768 case REPXMIN:
@@ -21690,26 +21879,26 @@
21879 {
21880 DIR *dir = 0;
21881
21882 if (name && name[0]) {
21883 size_t base_length = strlen(name);
21884 const char *all =
21885 strchr("/\\", name[base_length - 1]) ? "*" : "/*";
21886
21887 if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
21888 (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
21889 strcat(strcpy(dir->name, name), all);
21890
21891 if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
21892 dir->result.d_name = 0;
21893 else {
21894 Jim_Free(dir->name);
21895 Jim_Free(dir);
21896 dir = 0;
21897 }
21898 }
21899 else {
21900 Jim_Free(dir);
21901 dir = 0;
21902 errno = ENOMEM;
21903 }
21904 }
@@ -21727,11 +21916,11 @@
21916 if (dir->handle != -1)
21917 result = _findclose(dir->handle);
21918 Jim_Free(dir->name);
21919 Jim_Free(dir);
21920 }
21921 if (result == -1)
21922 errno = EBADF;
21923 return result;
21924 }
21925
21926 struct dirent *readdir(DIR * dir)
@@ -21810,11 +21999,11 @@
21999 }
22000
22001 void Jim_HistoryShow(void)
22002 {
22003 #ifdef USE_LINENOISE
22004
22005 int i;
22006 int len;
22007 char **history = linenoiseHistory(&len);
22008 for (i = 0; i < len; i++) {
22009 printf("%4d %s\n", i + 1, history[i]);
@@ -21876,11 +22065,11 @@
22065 Jim_DecrRefCount(interp, scriptObjPtr);
22066 retcode = JIM_OK;
22067 goto out;
22068 }
22069 if (Jim_Length(scriptObjPtr) != 0) {
22070
22071 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
22072 }
22073 Jim_AppendString(interp, scriptObjPtr, line, -1);
22074 free(line);
22075 if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
@@ -21888,11 +22077,11 @@
22077
22078 snprintf(prompt, sizeof(prompt), "%c> ", state);
22079 }
22080 #ifdef USE_LINENOISE
22081 if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
22082
22083 Jim_HistoryShow();
22084 Jim_DecrRefCount(interp, scriptObjPtr);
22085 continue;
22086 }
22087
@@ -21931,11 +22120,11 @@
22120 static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
22121 {
22122 int n;
22123 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
22124
22125
22126 for (n = 0; n < argc; n++) {
22127 Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
22128
22129 Jim_ListAppendElement(interp, listObj, obj);
22130 }
@@ -21971,47 +22160,47 @@
22160 {
22161 int retcode;
22162 Jim_Interp *interp;
22163 char *const orig_argv0 = argv[0];
22164
22165
22166 if (argc > 1 && strcmp(argv[1], "--version") == 0) {
22167 printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
22168 return 0;
22169 }
22170 else if (argc > 1 && strcmp(argv[1], "--help") == 0) {
22171 usage(argv[0]);
22172 return 0;
22173 }
22174
22175
22176 interp = Jim_CreateInterp();
22177 Jim_RegisterCoreCommands(interp);
22178
22179
22180 if (Jim_InitStaticExtensions(interp) != JIM_OK) {
22181 JimPrintErrorMessage(interp);
22182 }
22183
22184 Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0);
22185 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
22186 retcode = Jim_initjimshInit(interp);
22187
22188 if (argc == 1) {
22189
22190 if (retcode == JIM_ERR) {
22191 JimPrintErrorMessage(interp);
22192 }
22193 if (retcode != JIM_EXIT) {
22194 JimSetArgv(interp, 0, NULL);
22195 retcode = Jim_InteractivePrompt(interp);
22196 }
22197 }
22198 else {
22199
22200 if (argc > 2 && strcmp(argv[1], "-e") == 0) {
22201
22202 JimSetArgv(interp, argc - 3, argv + 3);
22203 retcode = Jim_Eval(interp, argv[2]);
22204 if (retcode != JIM_ERR) {
22205 printf("%s\n", Jim_String(Jim_GetResult(interp)));
22206 }
22207
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,7 +1,8 @@
1
-# For this project, disable the pager for --help
2
-set useropts(nopager) 1
1
+# For this project, disable the pager for --help and --ref
2
+# The user can still enable by using --nopager=0 or --disable-nopager
3
+dict set autosetup(optdefault) nopager 1
34
45
# Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
56
# Returns a dictionary of the contents of the tclConfig.sh file, or
67
# empty if not found
78
proc parse-tclconfig-sh {args} {
89
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,7 +1,8 @@
1 # For this project, disable the pager for --help
2 set useropts(nopager) 1
 
3
4 # Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
5 # Returns a dictionary of the contents of the tclConfig.sh file, or
6 # empty if not found
7 proc parse-tclconfig-sh {args} {
8
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -1,7 +1,8 @@
1 # For this project, disable the pager for --help and --ref
2 # The user can still enable by using --nopager=0 or --disable-nopager
3 dict set autosetup(optdefault) nopager 1
4
5 # Searches for a usable Tcl (prefer 8.6, 8.5, 8.4) in the given paths
6 # Returns a dictionary of the contents of the tclConfig.sh file, or
7 # empty if not found
8 proc parse-tclconfig-sh {args} {
9
--- autosetup/pkg-config.tcl
+++ autosetup/pkg-config.tcl
@@ -35,12 +35,16 @@
3535
set found 0
3636
3737
define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
3838
msg-checking "Checking for pkg-config..."
3939
40
- try {
41
- set version [exec [get-define PKG_CONFIG] --version]
40
+ if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
41
+ msg-result "[get-define PKG_CONFIG] (not found)"
42
+ if {$required} {
43
+ user-error "No usable pkg-config"
44
+ }
45
+ } else {
4246
msg-result $version
4347
define PKG_CONFIG_VERSION $version
4448
4549
set found 1
4650
@@ -70,16 +74,10 @@
7074
set env(PKG_CONFIG_DIR) ""
7175
# Do we need to try /usr/local as well or instead?
7276
set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig
7377
set env(PKG_CONFIG_SYSROOT_DIR) $sysroot
7478
}
75
-
76
- } on error msg {
77
- msg-result "[get-define PKG_CONFIG] (not found)"
78
- if {$required} {
79
- user-error "No usable pkg-config"
80
- }
8179
}
8280
define HAVE_PKG_CONFIG $found
8381
return $found
8482
}
8583
@@ -107,25 +105,23 @@
107105
if {!$ok} {
108106
msg-result "no pkg-config"
109107
return 0
110108
}
111109
112
- try {
113
- set version [exec [get-define PKG_CONFIG] --modversion "$module $args"]
114
- msg-result $version
115
- set prefix [feature-define-name $module PKG_]
116
- define HAVE_${prefix}
117
- define ${prefix}_VERSION $version
118
- define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
119
- define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
120
- define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
121
- return 1
122
- } on error msg {
110
+ if {[catch {exec [get-define PKG_CONFIG] --modversion "$module $args"} version]} {
123111
msg-result "not found"
124
- configlog "pkg-config --modversion $module $args: $msg"
112
+ configlog "pkg-config --modversion $module $args: $version"
125113
return 0
126114
}
115
+ msg-result $version
116
+ set prefix [feature-define-name $module PKG_]
117
+ define HAVE_${prefix}
118
+ define ${prefix}_VERSION $version
119
+ define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
120
+ define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
121
+ define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
122
+ return 1
127123
}
128124
129125
# @pkg-config-get module setting
130126
#
131127
# Convenience access to the results of pkg-config
132128
--- autosetup/pkg-config.tcl
+++ autosetup/pkg-config.tcl
@@ -35,12 +35,16 @@
35 set found 0
36
37 define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
38 msg-checking "Checking for pkg-config..."
39
40 try {
41 set version [exec [get-define PKG_CONFIG] --version]
 
 
 
 
42 msg-result $version
43 define PKG_CONFIG_VERSION $version
44
45 set found 1
46
@@ -70,16 +74,10 @@
70 set env(PKG_CONFIG_DIR) ""
71 # Do we need to try /usr/local as well or instead?
72 set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig
73 set env(PKG_CONFIG_SYSROOT_DIR) $sysroot
74 }
75
76 } on error msg {
77 msg-result "[get-define PKG_CONFIG] (not found)"
78 if {$required} {
79 user-error "No usable pkg-config"
80 }
81 }
82 define HAVE_PKG_CONFIG $found
83 return $found
84 }
85
@@ -107,25 +105,23 @@
107 if {!$ok} {
108 msg-result "no pkg-config"
109 return 0
110 }
111
112 try {
113 set version [exec [get-define PKG_CONFIG] --modversion "$module $args"]
114 msg-result $version
115 set prefix [feature-define-name $module PKG_]
116 define HAVE_${prefix}
117 define ${prefix}_VERSION $version
118 define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
119 define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
120 define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
121 return 1
122 } on error msg {
123 msg-result "not found"
124 configlog "pkg-config --modversion $module $args: $msg"
125 return 0
126 }
 
 
 
 
 
 
 
 
127 }
128
129 # @pkg-config-get module setting
130 #
131 # Convenience access to the results of pkg-config
132
--- autosetup/pkg-config.tcl
+++ autosetup/pkg-config.tcl
@@ -35,12 +35,16 @@
35 set found 0
36
37 define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
38 msg-checking "Checking for pkg-config..."
39
40 if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
41 msg-result "[get-define PKG_CONFIG] (not found)"
42 if {$required} {
43 user-error "No usable pkg-config"
44 }
45 } else {
46 msg-result $version
47 define PKG_CONFIG_VERSION $version
48
49 set found 1
50
@@ -70,16 +74,10 @@
74 set env(PKG_CONFIG_DIR) ""
75 # Do we need to try /usr/local as well or instead?
76 set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig
77 set env(PKG_CONFIG_SYSROOT_DIR) $sysroot
78 }
 
 
 
 
 
 
79 }
80 define HAVE_PKG_CONFIG $found
81 return $found
82 }
83
@@ -107,25 +105,23 @@
105 if {!$ok} {
106 msg-result "no pkg-config"
107 return 0
108 }
109
110 if {[catch {exec [get-define PKG_CONFIG] --modversion "$module $args"} version]} {
 
 
 
 
 
 
 
 
 
 
111 msg-result "not found"
112 configlog "pkg-config --modversion $module $args: $version"
113 return 0
114 }
115 msg-result $version
116 set prefix [feature-define-name $module PKG_]
117 define HAVE_${prefix}
118 define ${prefix}_VERSION $version
119 define ${prefix}_LIBS [exec pkg-config --libs-only-l $module]
120 define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module]
121 define ${prefix}_CFLAGS [exec pkg-config --cflags $module]
122 return 1
123 }
124
125 # @pkg-config-get module setting
126 #
127 # Convenience access to the results of pkg-config
128
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -7,17 +7,30 @@
77
# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT
88
#
99
# It also support the 'feature' naming convention, where searching
1010
# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H
1111
#
12
-module-options {
12
+# It defines the following variables, based on --prefix unless overridden by the user:
13
+#
14
+## datadir
15
+## sysconfdir
16
+## sharedstatedir
17
+## localstatedir
18
+## infodir
19
+## mandir
20
+## includedir
21
+
22
+# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
23
+set defaultprefix [get-define defaultprefix /usr/local]
24
+
25
+module-options [subst -noc -nob {
1326
host:host-alias => {a complete or partial cpu-vendor-opsys for the system where
1427
the application will run (defaults to the same value as --build)}
1528
build:build-alias => {a complete or partial cpu-vendor-opsys for the system
1629
where the application will be built (defaults to the
1730
result of running config.guess)}
18
- prefix:dir => {the target directory for the build (defaults to /usr/local)}
31
+ prefix:dir => {the target directory for the build (defaults to '$defaultprefix')}
1932
2033
# These (hidden) options are supported for autoconf/automake compatibility
2134
exec-prefix:
2235
bindir:
2336
sbindir:
@@ -30,11 +43,11 @@
3043
sysconfdir:
3144
sharedstatedir:
3245
localstatedir:
3346
maintainer-mode=0
3447
dependency-tracking=0
35
-}
48
+}]
3649
3750
# Returns 1 if exists, or 0 if not
3851
#
3952
proc check-feature {name code} {
4053
msg-checking "Checking for $name..."
@@ -106,11 +119,11 @@
106119
# If $outfile is blank/omitted, $template should end with ".in" which
107120
# is removed to create the output file name.
108121
#
109122
# Each pattern of the form @define@ is replaced with the corresponding
110123
# define, if it exists, or left unchanged if not.
111
-#
124
+#
112125
# The special value @srcdir@ is substituted with the relative
113126
# path to the source directory from the directory where the output
114127
# file is created, while the special value @top_srcdir@ is substituted
115128
# with the relative path to the top level source directory.
116129
#
@@ -217,12 +230,11 @@
217230
define host [config_sub $host]
218231
set cross $host-
219232
}
220233
define cross [get-env CROSS $cross]
221234
222
-# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
223
-set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
235
+set prefix [opt-val prefix $defaultprefix]
224236
225237
# These are for compatibility with autoconf
226238
define target [get-define host]
227239
define prefix $prefix
228240
define builddir $autosetup(builddir)
229241
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -7,17 +7,30 @@
7 # such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT
8 #
9 # It also support the 'feature' naming convention, where searching
10 # for a feature such as sys/type.h defines HAVE_SYS_TYPES_H
11 #
12 module-options {
 
 
 
 
 
 
 
 
 
 
 
 
 
13 host:host-alias => {a complete or partial cpu-vendor-opsys for the system where
14 the application will run (defaults to the same value as --build)}
15 build:build-alias => {a complete or partial cpu-vendor-opsys for the system
16 where the application will be built (defaults to the
17 result of running config.guess)}
18 prefix:dir => {the target directory for the build (defaults to /usr/local)}
19
20 # These (hidden) options are supported for autoconf/automake compatibility
21 exec-prefix:
22 bindir:
23 sbindir:
@@ -30,11 +43,11 @@
30 sysconfdir:
31 sharedstatedir:
32 localstatedir:
33 maintainer-mode=0
34 dependency-tracking=0
35 }
36
37 # Returns 1 if exists, or 0 if not
38 #
39 proc check-feature {name code} {
40 msg-checking "Checking for $name..."
@@ -106,11 +119,11 @@
106 # If $outfile is blank/omitted, $template should end with ".in" which
107 # is removed to create the output file name.
108 #
109 # Each pattern of the form @define@ is replaced with the corresponding
110 # define, if it exists, or left unchanged if not.
111 #
112 # The special value @srcdir@ is substituted with the relative
113 # path to the source directory from the directory where the output
114 # file is created, while the special value @top_srcdir@ is substituted
115 # with the relative path to the top level source directory.
116 #
@@ -217,12 +230,11 @@
217 define host [config_sub $host]
218 set cross $host-
219 }
220 define cross [get-env CROSS $cross]
221
222 # Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
223 set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
224
225 # These are for compatibility with autoconf
226 define target [get-define host]
227 define prefix $prefix
228 define builddir $autosetup(builddir)
229
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -7,17 +7,30 @@
7 # such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT
8 #
9 # It also support the 'feature' naming convention, where searching
10 # for a feature such as sys/type.h defines HAVE_SYS_TYPES_H
11 #
12 # It defines the following variables, based on --prefix unless overridden by the user:
13 #
14 ## datadir
15 ## sysconfdir
16 ## sharedstatedir
17 ## localstatedir
18 ## infodir
19 ## mandir
20 ## includedir
21
22 # Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
23 set defaultprefix [get-define defaultprefix /usr/local]
24
25 module-options [subst -noc -nob {
26 host:host-alias => {a complete or partial cpu-vendor-opsys for the system where
27 the application will run (defaults to the same value as --build)}
28 build:build-alias => {a complete or partial cpu-vendor-opsys for the system
29 where the application will be built (defaults to the
30 result of running config.guess)}
31 prefix:dir => {the target directory for the build (defaults to '$defaultprefix')}
32
33 # These (hidden) options are supported for autoconf/automake compatibility
34 exec-prefix:
35 bindir:
36 sbindir:
@@ -30,11 +43,11 @@
43 sysconfdir:
44 sharedstatedir:
45 localstatedir:
46 maintainer-mode=0
47 dependency-tracking=0
48 }]
49
50 # Returns 1 if exists, or 0 if not
51 #
52 proc check-feature {name code} {
53 msg-checking "Checking for $name..."
@@ -106,11 +119,11 @@
119 # If $outfile is blank/omitted, $template should end with ".in" which
120 # is removed to create the output file name.
121 #
122 # Each pattern of the form @define@ is replaced with the corresponding
123 # define, if it exists, or left unchanged if not.
124 #
125 # The special value @srcdir@ is substituted with the relative
126 # path to the source directory from the directory where the output
127 # file is created, while the special value @top_srcdir@ is substituted
128 # with the relative path to the top level source directory.
129 #
@@ -217,12 +230,11 @@
230 define host [config_sub $host]
231 set cross $host-
232 }
233 define cross [get-env CROSS $cross]
234
235 set prefix [opt-val prefix $defaultprefix]
 
236
237 # These are for compatibility with autoconf
238 define target [get-define host]
239 define prefix $prefix
240 define builddir $autosetup(builddir)
241

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button