Fossil SCM

Update autosetup to (roughly) 0.6.6 and Jim Tcl to (roughly) 0.77.

mistachkin 2016-09-23 01:49 trunk merge
Commit 762ef68dfbe3116c8f28d914cbac6c46e4a152ad
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1
-This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/
1
+This is autosetup v0.6.6. See http://msteveb.github.com/autosetup/
22
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1 This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/
2
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1 This is autosetup v0.6.6. See http://msteveb.github.com/autosetup/
2
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -3,11 +3,11 @@
33
# All rights reserved
44
# vim:se syntax=tcl:
55
# \
66
dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@"
77
8
-set autosetup(version) 0.6.5
8
+set autosetup(version) 0.6.6
99
1010
# Can be set to 1 to debug early-init problems
1111
set autosetup(debug) 0
1212
1313
##################################################################
@@ -133,18 +133,26 @@
133133
if {[opt-val {manual ref reference}] ne ""} {
134134
use help
135135
autosetup_reference [opt-val {manual ref reference}]
136136
}
137137
138
- if {[opt-val init] ne ""} {
139
- use init
140
- autosetup_init [opt-val init]
141
- }
142
-
138
+ # Allow combining --install and --init
139
+ set earlyexit 0
143140
if {[opt-val install] ne ""} {
144141
use install
145142
autosetup_install [opt-val install]
143
+ incr earlyexit
144
+ }
145
+
146
+ if {[opt-val init] ne ""} {
147
+ use init
148
+ autosetup_init [opt-val init]
149
+ incr earlyexit
150
+ }
151
+
152
+ if {$earlyexit} {
153
+ exit 0
146154
}
147155
148156
if {![file exists $autosetup(autodef)]} {
149157
# Check for invalid option first
150158
options {}
@@ -161,15 +169,17 @@
161169
}
162170
}
163171
164172
autosetup_add_dep $autosetup(autodef)
165173
166
- set cmd [file-normalize $autosetup(exe)]
174
+ define CONFIGURE_OPTS ""
167175
foreach arg $autosetup(argv) {
168
- append cmd " [quote-if-needed $arg]"
176
+ define-append CONFIGURE_OPTS [quote-if-needed $arg]
169177
}
170
- define AUTOREMAKE $cmd
178
+ define AUTOREMAKE [file-normalize $autosetup(exe)]
179
+ define-append AUTOREMAKE [get-define CONFIGURE_OPTS]
180
+
171181
172182
# Log how we were invoked
173183
configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
174184
175185
# Note that auto.def is *not* loaded in the global scope
@@ -192,10 +202,12 @@
192202
193203
# @opt-bool option ...
194204
#
195205
# Check each of the named, boolean options and return 1 if any of them have
196206
# 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
197209
#
198210
proc opt-bool {args} {
199211
option-check-names {*}$args
200212
opt_bool ::useropts {*}$args
201213
}
@@ -398,11 +410,11 @@
398410
#
399411
## name:[=]value => "Description of this option"
400412
#
401413
# If the name:value form is used, the value must be provided with the option (as --name=myvalue).
402414
# If the name:=value form is used, the value is optional and the given value is used as the default
403
-# if is not provided.
415
+# if it is not provided.
404416
#
405417
# Undocumented options are also supported by omitting the "=> description.
406418
# These options are not displayed with --help and can be useful for internal options or as aliases.
407419
#
408420
# For example, --disable-lfs is an alias for --disable=largefile:
@@ -458,10 +470,19 @@
458470
#
459471
proc define {name {value 1}} {
460472
set ::define($name) $value
461473
#dputs "$name <= $value"
462474
}
475
+
476
+# @undefine name
477
+#
478
+# Undefine the named variable
479
+#
480
+proc undefine {name} {
481
+ unset -nocomplain ::define($name)
482
+ #dputs "$name <= <undef>"
483
+}
463484
464485
# @define-append name value ...
465486
#
466487
# Appends the given value(s) to the given 'defined' variable.
467488
# If the variable is not defined or empty, it is set to $value.
@@ -546,11 +567,11 @@
546567
}
547568
548569
# @readfile filename ?default=""?
549570
#
550571
# Return the contents of the file, without the trailing newline.
551
-# If the doesn't exist or can't be read, returns $default.
572
+# If the file doesn't exist or can't be read, returns $default.
552573
#
553574
proc readfile {filename {default_value ""}} {
554575
set result $default_value
555576
catch {
556577
set f [open $filename]
@@ -1077,10 +1098,11 @@
10771098
# Simple getopt module
10781099
10791100
# Parse everything out of the argv list which looks like an option
10801101
# Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
10811102
# Everything which doesn't look like an option, or is after --, is left unchanged
1103
+#
10821104
proc getopt {argvname} {
10831105
upvar $argvname argv
10841106
set nargv {}
10851107
10861108
for {set i 0} {$i < [llength $argv]} {incr i} {
@@ -1141,11 +1163,12 @@
11411163
set args [lindex $args 0]
11421164
}
11431165
11441166
foreach o $args {
11451167
if {[info exists opts($o)]} {
1146
- if {"1" in $opts($o) || "yes" in $opts($o)} {
1168
+ # For boolean options, the last value wins
1169
+ if {[lindex $opts($o) end] in {"1" "yes"}} {
11471170
return 1
11481171
}
11491172
}
11501173
}
11511174
return 0
@@ -1340,22 +1363,20 @@
13401363
foreach type [lsort [dict keys $::autosetup(inittypes)]] {
13411364
lassign [dict get $::autosetup(inittypes) $type] desc
13421365
# XXX: Use the options-show code to wrap the description
13431366
puts [format "%-10s %s" $type $desc]
13441367
}
1345
- exit 0
1368
+ return
13461369
}
13471370
lassign [dict get $::autosetup(inittypes) $type] desc script
13481371
13491372
puts "Initialising $type: $desc\n"
13501373
13511374
# All initialisations happens in the top level srcdir
13521375
cd $::autosetup(srcdir)
13531376
13541377
uplevel #0 $script
1355
-
1356
- exit 0
13571378
}
13581379
13591380
proc autosetup_add_init_type {type desc script} {
13601381
dict set ::autosetup(inittypes) $type [list $desc $script]
13611382
}
@@ -1393,11 +1414,11 @@
13931414
cd $dir
13941415
file mkdir autosetup
13951416
13961417
set f [open autosetup/autosetup w]
13971418
1398
- set publicmodules $::autosetup(libdir)/default.auto
1419
+ set publicmodules [glob $::autosetup(libdir)/*.auto]
13991420
14001421
# First the main script, but only up until "CUT HERE"
14011422
set in [open $::autosetup(dir)/autosetup]
14021423
while {[gets $in buf] >= 0} {
14031424
if {$buf ne "##-- CUT HERE --##"} {
@@ -1444,12 +1465,10 @@
14441465
}
14451466
puts "Installed [autosetup_version] to autosetup/"
14461467
14471468
# Now create 'configure' if necessary
14481469
autosetup_create_configure
1449
-
1450
- exit 0
14511470
}
14521471
14531472
proc autosetup_create_configure {} {
14541473
if {[file exists configure]} {
14551474
if {!$::autosetup(force)} {
14561475
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -3,11 +3,11 @@
3 # All rights reserved
4 # vim:se syntax=tcl:
5 # \
6 dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@"
7
8 set autosetup(version) 0.6.5
9
10 # Can be set to 1 to debug early-init problems
11 set autosetup(debug) 0
12
13 ##################################################################
@@ -133,18 +133,26 @@
133 if {[opt-val {manual ref reference}] ne ""} {
134 use help
135 autosetup_reference [opt-val {manual ref reference}]
136 }
137
138 if {[opt-val init] ne ""} {
139 use init
140 autosetup_init [opt-val init]
141 }
142
143 if {[opt-val install] ne ""} {
144 use install
145 autosetup_install [opt-val install]
 
 
 
 
 
 
 
 
 
 
 
146 }
147
148 if {![file exists $autosetup(autodef)]} {
149 # Check for invalid option first
150 options {}
@@ -161,15 +169,17 @@
161 }
162 }
163
164 autosetup_add_dep $autosetup(autodef)
165
166 set cmd [file-normalize $autosetup(exe)]
167 foreach arg $autosetup(argv) {
168 append cmd " [quote-if-needed $arg]"
169 }
170 define AUTOREMAKE $cmd
 
 
171
172 # Log how we were invoked
173 configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
174
175 # Note that auto.def is *not* loaded in the global scope
@@ -192,10 +202,12 @@
192
193 # @opt-bool option ...
194 #
195 # Check each of the named, boolean options and return 1 if any of them have
196 # been set by the user.
 
 
197 #
198 proc opt-bool {args} {
199 option-check-names {*}$args
200 opt_bool ::useropts {*}$args
201 }
@@ -398,11 +410,11 @@
398 #
399 ## name:[=]value => "Description of this option"
400 #
401 # If the name:value form is used, the value must be provided with the option (as --name=myvalue).
402 # If the name:=value form is used, the value is optional and the given value is used as the default
403 # if is not provided.
404 #
405 # Undocumented options are also supported by omitting the "=> description.
406 # These options are not displayed with --help and can be useful for internal options or as aliases.
407 #
408 # For example, --disable-lfs is an alias for --disable=largefile:
@@ -458,10 +470,19 @@
458 #
459 proc define {name {value 1}} {
460 set ::define($name) $value
461 #dputs "$name <= $value"
462 }
 
 
 
 
 
 
 
 
 
463
464 # @define-append name value ...
465 #
466 # Appends the given value(s) to the given 'defined' variable.
467 # If the variable is not defined or empty, it is set to $value.
@@ -546,11 +567,11 @@
546 }
547
548 # @readfile filename ?default=""?
549 #
550 # Return the contents of the file, without the trailing newline.
551 # If the doesn't exist or can't be read, returns $default.
552 #
553 proc readfile {filename {default_value ""}} {
554 set result $default_value
555 catch {
556 set f [open $filename]
@@ -1077,10 +1098,11 @@
1077 # Simple getopt module
1078
1079 # Parse everything out of the argv list which looks like an option
1080 # Knows about --enable-thing and --disable-thing as alternatives for --thing=0 or --thing=1
1081 # Everything which doesn't look like an option, or is after --, is left unchanged
 
1082 proc getopt {argvname} {
1083 upvar $argvname argv
1084 set nargv {}
1085
1086 for {set i 0} {$i < [llength $argv]} {incr i} {
@@ -1141,11 +1163,12 @@
1141 set args [lindex $args 0]
1142 }
1143
1144 foreach o $args {
1145 if {[info exists opts($o)]} {
1146 if {"1" in $opts($o) || "yes" in $opts($o)} {
 
1147 return 1
1148 }
1149 }
1150 }
1151 return 0
@@ -1340,22 +1363,20 @@
1340 foreach type [lsort [dict keys $::autosetup(inittypes)]] {
1341 lassign [dict get $::autosetup(inittypes) $type] desc
1342 # XXX: Use the options-show code to wrap the description
1343 puts [format "%-10s %s" $type $desc]
1344 }
1345 exit 0
1346 }
1347 lassign [dict get $::autosetup(inittypes) $type] desc script
1348
1349 puts "Initialising $type: $desc\n"
1350
1351 # All initialisations happens in the top level srcdir
1352 cd $::autosetup(srcdir)
1353
1354 uplevel #0 $script
1355
1356 exit 0
1357 }
1358
1359 proc autosetup_add_init_type {type desc script} {
1360 dict set ::autosetup(inittypes) $type [list $desc $script]
1361 }
@@ -1393,11 +1414,11 @@
1393 cd $dir
1394 file mkdir autosetup
1395
1396 set f [open autosetup/autosetup w]
1397
1398 set publicmodules $::autosetup(libdir)/default.auto
1399
1400 # First the main script, but only up until "CUT HERE"
1401 set in [open $::autosetup(dir)/autosetup]
1402 while {[gets $in buf] >= 0} {
1403 if {$buf ne "##-- CUT HERE --##"} {
@@ -1444,12 +1465,10 @@
1444 }
1445 puts "Installed [autosetup_version] to autosetup/"
1446
1447 # Now create 'configure' if necessary
1448 autosetup_create_configure
1449
1450 exit 0
1451 }
1452
1453 proc autosetup_create_configure {} {
1454 if {[file exists configure]} {
1455 if {!$::autosetup(force)} {
1456
--- autosetup/autosetup
+++ autosetup/autosetup
@@ -3,11 +3,11 @@
3 # All rights reserved
4 # vim:se syntax=tcl:
5 # \
6 dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@"
7
8 set autosetup(version) 0.6.6
9
10 # Can be set to 1 to debug early-init problems
11 set autosetup(debug) 0
12
13 ##################################################################
@@ -133,18 +133,26 @@
133 if {[opt-val {manual ref reference}] ne ""} {
134 use help
135 autosetup_reference [opt-val {manual ref reference}]
136 }
137
138 # Allow combining --install and --init
139 set earlyexit 0
 
 
 
140 if {[opt-val install] ne ""} {
141 use install
142 autosetup_install [opt-val install]
143 incr earlyexit
144 }
145
146 if {[opt-val init] ne ""} {
147 use init
148 autosetup_init [opt-val init]
149 incr earlyexit
150 }
151
152 if {$earlyexit} {
153 exit 0
154 }
155
156 if {![file exists $autosetup(autodef)]} {
157 # Check for invalid option first
158 options {}
@@ -161,15 +169,17 @@
169 }
170 }
171
172 autosetup_add_dep $autosetup(autodef)
173
174 define CONFIGURE_OPTS ""
175 foreach arg $autosetup(argv) {
176 define-append CONFIGURE_OPTS [quote-if-needed $arg]
177 }
178 define AUTOREMAKE [file-normalize $autosetup(exe)]
179 define-append AUTOREMAKE [get-define CONFIGURE_OPTS]
180
181
182 # Log how we were invoked
183 configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
184
185 # Note that auto.def is *not* loaded in the global scope
@@ -192,10 +202,12 @@
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 }
@@ -398,11 +410,11 @@
410 #
411 ## name:[=]value => "Description of this option"
412 #
413 # If the name:value form is used, the value must be provided with the option (as --name=myvalue).
414 # If the name:=value form is used, the value is optional and the given value is used as the default
415 # if it is not provided.
416 #
417 # Undocumented options are also supported by omitting the "=> description.
418 # These options are not displayed with --help and can be useful for internal options or as aliases.
419 #
420 # For example, --disable-lfs is an alias for --disable=largefile:
@@ -458,10 +470,19 @@
470 #
471 proc define {name {value 1}} {
472 set ::define($name) $value
473 #dputs "$name <= $value"
474 }
475
476 # @undefine name
477 #
478 # Undefine the named variable
479 #
480 proc undefine {name} {
481 unset -nocomplain ::define($name)
482 #dputs "$name <= <undef>"
483 }
484
485 # @define-append name value ...
486 #
487 # Appends the given value(s) to the given 'defined' variable.
488 # If the variable is not defined or empty, it is set to $value.
@@ -546,11 +567,11 @@
567 }
568
569 # @readfile filename ?default=""?
570 #
571 # Return the contents of the file, without the trailing newline.
572 # If the file doesn't exist or can't be read, returns $default.
573 #
574 proc readfile {filename {default_value ""}} {
575 set result $default_value
576 catch {
577 set f [open $filename]
@@ -1077,10 +1098,11 @@
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} {
@@ -1141,11 +1163,12 @@
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
@@ -1340,22 +1363,20 @@
1363 foreach type [lsort [dict keys $::autosetup(inittypes)]] {
1364 lassign [dict get $::autosetup(inittypes) $type] desc
1365 # XXX: Use the options-show code to wrap the description
1366 puts [format "%-10s %s" $type $desc]
1367 }
1368 return
1369 }
1370 lassign [dict get $::autosetup(inittypes) $type] desc script
1371
1372 puts "Initialising $type: $desc\n"
1373
1374 # All initialisations happens in the top level srcdir
1375 cd $::autosetup(srcdir)
1376
1377 uplevel #0 $script
 
 
1378 }
1379
1380 proc autosetup_add_init_type {type desc script} {
1381 dict set ::autosetup(inittypes) $type [list $desc $script]
1382 }
@@ -1393,11 +1414,11 @@
1414 cd $dir
1415 file mkdir autosetup
1416
1417 set f [open autosetup/autosetup w]
1418
1419 set publicmodules [glob $::autosetup(libdir)/*.auto]
1420
1421 # First the main script, but only up until "CUT HERE"
1422 set in [open $::autosetup(dir)/autosetup]
1423 while {[gets $in buf] >= 0} {
1424 if {$buf ne "##-- CUT HERE --##"} {
@@ -1444,12 +1465,10 @@
1465 }
1466 puts "Installed [autosetup_version] to autosetup/"
1467
1468 # Now create 'configure' if necessary
1469 autosetup_create_configure
 
 
1470 }
1471
1472 proc autosetup_create_configure {} {
1473 if {[file exists configure]} {
1474 if {!$::autosetup(force)} {
1475
--- autosetup/cc-db.tcl
+++ autosetup/cc-db.tcl
@@ -1,11 +1,11 @@
11
# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/
22
# All rights reserved
33
44
# @synopsis:
55
#
6
-# The 'cc-db' module provides a knowledge based of system idiosyncracies
6
+# The 'cc-db' module provides a knowledge based of system idiosyncrasies
77
# In general, this module can always be included
88
99
use cc
1010
1111
module-options {}
1212
--- autosetup/cc-db.tcl
+++ autosetup/cc-db.tcl
@@ -1,11 +1,11 @@
1 # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/
2 # All rights reserved
3
4 # @synopsis:
5 #
6 # The 'cc-db' module provides a knowledge based of system idiosyncracies
7 # In general, this module can always be included
8
9 use cc
10
11 module-options {}
12
--- autosetup/cc-db.tcl
+++ autosetup/cc-db.tcl
@@ -1,11 +1,11 @@
1 # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/
2 # All rights reserved
3
4 # @synopsis:
5 #
6 # The 'cc-db' module provides a knowledge based of system idiosyncrasies
7 # In general, this module can always be included
8
9 use cc
10
11 module-options {}
12
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -14,11 +14,11 @@
1414
## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
1515
## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
1616
## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
1717
## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
1818
## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
19
-## STRIPLIBFLAGS Arguments to strip to strip a dynamic library
19
+## STRIPLIBFLAGS Arguments to strip a dynamic library
2020
2121
module-options {}
2222
2323
# Defaults: gcc on unix
2424
define SHOBJ_CFLAGS -fpic
2525
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -14,11 +14,11 @@
14 ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
15 ## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
16 ## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
17 ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
18 ## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
19 ## STRIPLIBFLAGS Arguments to strip to strip a dynamic library
20
21 module-options {}
22
23 # Defaults: gcc on unix
24 define SHOBJ_CFLAGS -fpic
25
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -14,11 +14,11 @@
14 ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
15 ## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
16 ## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
17 ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
18 ## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
19 ## STRIPLIBFLAGS Arguments to strip a dynamic library
20
21 module-options {}
22
23 # Defaults: gcc on unix
24 define SHOBJ_CFLAGS -fpic
25
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -162,11 +162,11 @@
162162
}
163163
164164
# @cc-check-decls name ...
165165
#
166166
# Checks that each given name is either a preprocessor symbol or rvalue
167
-# such as an enum. Note that the define used for a decl is HAVE_DECL_xxx
167
+# such as an enum. Note that the define used is HAVE_DECL_xxx
168168
# rather than HAVE_xxx
169169
proc cc-check-decls {args} {
170170
set ret 1
171171
foreach name $args {
172172
msg-checking "Checking for $name..."
@@ -201,11 +201,11 @@
201201
}
202202
}
203203
204204
# @cc-check-function-in-lib function libs ?otherlibs?
205205
#
206
-# Checks that the given given function can be found in one of the libs.
206
+# Checks that the given function can be found in one of the libs.
207207
#
208208
# First checks for no library required, then checks each of the libraries
209209
# in turn.
210210
#
211211
# If the function is found, the feature is defined and lib_$function is defined
@@ -285,11 +285,11 @@
285285
# Checks for existence of the given executables on the path.
286286
#
287287
# For example, when checking for "grep", the path is searched for
288288
# the executable, 'grep', and if found GREP is defined as "grep".
289289
#
290
-# It the executable is not found, the variable is defined as false.
290
+# If the executable is not found, the variable is defined as false.
291291
# Returns 1 if all programs were found, or 0 otherwise.
292292
#
293293
proc cc-check-progs {args} {
294294
set failed 0
295295
foreach prog $args {
296296
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -162,11 +162,11 @@
162 }
163
164 # @cc-check-decls name ...
165 #
166 # Checks that each given name is either a preprocessor symbol or rvalue
167 # such as an enum. Note that the define used for a decl is HAVE_DECL_xxx
168 # rather than HAVE_xxx
169 proc cc-check-decls {args} {
170 set ret 1
171 foreach name $args {
172 msg-checking "Checking for $name..."
@@ -201,11 +201,11 @@
201 }
202 }
203
204 # @cc-check-function-in-lib function libs ?otherlibs?
205 #
206 # Checks that the given given function can be found in one of the libs.
207 #
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
@@ -285,11 +285,11 @@
285 # Checks for existence of the given executables on the path.
286 #
287 # For example, when checking for "grep", the path is searched for
288 # the executable, 'grep', and if found GREP is defined as "grep".
289 #
290 # It the executable is not found, the variable is defined as false.
291 # Returns 1 if all programs were found, or 0 otherwise.
292 #
293 proc cc-check-progs {args} {
294 set failed 0
295 foreach prog $args {
296
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -162,11 +162,11 @@
162 }
163
164 # @cc-check-decls name ...
165 #
166 # Checks that each given name is either a preprocessor symbol or rvalue
167 # such as an enum. Note that the define used is HAVE_DECL_xxx
168 # rather than HAVE_xxx
169 proc cc-check-decls {args} {
170 set ret 1
171 foreach name $args {
172 msg-checking "Checking for $name..."
@@ -201,11 +201,11 @@
201 }
202 }
203
204 # @cc-check-function-in-lib function libs ?otherlibs?
205 #
206 # Checks that the given function can be found in one of the libs.
207 #
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
@@ -285,11 +285,11 @@
285 # Checks for existence of the given executables on the path.
286 #
287 # For example, when checking for "grep", the path is searched for
288 # the executable, 'grep', and if found GREP is defined as "grep".
289 #
290 # If the executable is not found, the variable is defined as false.
291 # Returns 1 if all programs were found, or 0 otherwise.
292 #
293 proc cc-check-progs {args} {
294 set failed 0
295 foreach prog $args {
296
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -1,10 +1,10 @@
11
#! /bin/sh
22
# Attempt to guess a canonical system name.
33
# Copyright 1992-2014 Free Software Foundation, Inc.
44
5
-timestamp='2014-03-23'
5
+timestamp='2014-11-04'
66
77
# This file is free software; you can redistribute it and/or modify it
88
# under the terms of the GNU General Public License as published by
99
# the Free Software Foundation; either version 3 of the License, or
1010
# (at your option) any later version.
@@ -22,16 +22,16 @@
2222
# configuration script generated by Autoconf, you may include it under
2323
# the same distribution terms that you use for the rest of that
2424
# program. This Exception is an additional permission under section 7
2525
# of the GNU General Public License, version 3 ("GPLv3").
2626
#
27
-# Originally written by Per Bothner.
27
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
2828
#
2929
# You can get the latest version of this script from:
3030
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
3131
#
32
-# Please send patches with a ChangeLog entry to [email protected].
32
+# Please send patches to <[email protected]>.
3333
3434
3535
me=`echo "$0" | sed -e 's,.*/,,'`
3636
3737
usage="\
@@ -577,12 +577,13 @@
577577
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
578578
IBM_ARCH=rs6000
579579
else
580580
IBM_ARCH=powerpc
581581
fi
582
- if [ -x /usr/bin/oslevel ] ; then
583
- IBM_REV=`/usr/bin/oslevel`
582
+ if [ -x /usr/bin/lslpp ] ; then
583
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
584
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
584585
else
585586
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
586587
fi
587588
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
588589
exit ;;
589590
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -1,10 +1,10 @@
1 #! /bin/sh
2 # Attempt to guess a canonical system name.
3 # Copyright 1992-2014 Free Software Foundation, Inc.
4
5 timestamp='2014-03-23'
6
7 # This file is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
@@ -22,16 +22,16 @@
22 # configuration script generated by Autoconf, you may include it under
23 # the same distribution terms that you use for the rest of that
24 # program. This Exception is an additional permission under section 7
25 # of the GNU General Public License, version 3 ("GPLv3").
26 #
27 # Originally written by Per Bothner.
28 #
29 # You can get the latest version of this script from:
30 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
31 #
32 # Please send patches with a ChangeLog entry to [email protected].
33
34
35 me=`echo "$0" | sed -e 's,.*/,,'`
36
37 usage="\
@@ -577,12 +577,13 @@
577 if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
578 IBM_ARCH=rs6000
579 else
580 IBM_ARCH=powerpc
581 fi
582 if [ -x /usr/bin/oslevel ] ; then
583 IBM_REV=`/usr/bin/oslevel`
 
584 else
585 IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
586 fi
587 echo ${IBM_ARCH}-ibm-aix${IBM_REV}
588 exit ;;
589
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -1,10 +1,10 @@
1 #! /bin/sh
2 # Attempt to guess a canonical system name.
3 # Copyright 1992-2014 Free Software Foundation, Inc.
4
5 timestamp='2014-11-04'
6
7 # This file is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
@@ -22,16 +22,16 @@
22 # configuration script generated by Autoconf, you may include it under
23 # the same distribution terms that you use for the rest of that
24 # program. This Exception is an additional permission under section 7
25 # of the GNU General Public License, version 3 ("GPLv3").
26 #
27 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
28 #
29 # You can get the latest version of this script from:
30 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
31 #
32 # Please send patches to <[email protected]>.
33
34
35 me=`echo "$0" | sed -e 's,.*/,,'`
36
37 usage="\
@@ -577,12 +577,13 @@
577 if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
578 IBM_ARCH=rs6000
579 else
580 IBM_ARCH=powerpc
581 fi
582 if [ -x /usr/bin/lslpp ] ; then
583 IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
584 awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
585 else
586 IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
587 fi
588 echo ${IBM_ARCH}-ibm-aix${IBM_REV}
589 exit ;;
590
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -1,10 +1,10 @@
11
#! /bin/sh
22
# Configuration validation subroutine script.
33
# Copyright 1992-2014 Free Software Foundation, Inc.
44
5
-timestamp='2014-05-01'
5
+timestamp='2014-12-03'
66
77
# This file is free software; you can redistribute it and/or modify it
88
# under the terms of the GNU General Public License as published by
99
# the Free Software Foundation; either version 3 of the License, or
1010
# (at your option) any later version.
@@ -23,11 +23,11 @@
2323
# the same distribution terms that you use for the rest of that
2424
# program. This Exception is an additional permission under section 7
2525
# of the GNU General Public License, version 3 ("GPLv3").
2626
2727
28
-# Please send patches with a ChangeLog entry to [email protected].
28
+# Please send patches to <[email protected]>.
2929
#
3030
# Configuration subroutine to validate and canonicalize a configuration type.
3131
# Supply the specified configuration type as an argument.
3232
# If it is invalid, we print an error message on stderr and exit with code 1.
3333
# Otherwise, we print the canonical config type on stdout and succeed.
@@ -300,10 +300,11 @@
300300
| ns16k | ns32k \
301301
| open8 | or1k | or1knd | or32 \
302302
| pdp10 | pdp11 | pj | pjl \
303303
| powerpc | powerpc64 | powerpc64le | powerpcle \
304304
| pyramid \
305
+ | riscv32 | riscv64 \
305306
| rl78 | rx \
306307
| score \
307308
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
308309
| sh64 | sh64le \
309310
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
@@ -310,10 +311,11 @@
310311
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
311312
| spu \
312313
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
313314
| ubicom32 \
314315
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
316
+ | visium \
315317
| we32k \
316318
| x86 | xc16x | xstormy16 | xtensa \
317319
| z8k | z80)
318320
basic_machine=$basic_machine-unknown
319321
;;
@@ -324,10 +326,13 @@
324326
basic_machine=tic55x-unknown
325327
;;
326328
c6x)
327329
basic_machine=tic6x-unknown
328330
;;
331
+ leon|leon[3-9])
332
+ basic_machine=sparc-$basic_machine
333
+ ;;
329334
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
330335
basic_machine=$basic_machine-unknown
331336
os=-none
332337
;;
333338
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
@@ -434,10 +439,11 @@
434439
| tile*-* \
435440
| tron-* \
436441
| ubicom32-* \
437442
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
438443
| vax-* \
444
+ | visium-* \
439445
| we32k-* \
440446
| x86-* | x86_64-* | xc16x-* | xps100-* \
441447
| xstormy16-* | xtensa*-* \
442448
| ymp-* \
443449
| z8k-* | z80-*)
@@ -771,10 +777,13 @@
771777
;;
772778
isi68 | isi)
773779
basic_machine=m68k-isi
774780
os=-sysv
775781
;;
782
+ leon-*|leon[3-9]-*)
783
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
784
+ ;;
776785
m68knommu)
777786
basic_machine=m68k-unknown
778787
os=-linux
779788
;;
780789
m68knommu-*)
@@ -826,10 +835,14 @@
826835
;;
827836
morphos)
828837
basic_machine=powerpc-unknown
829838
os=-morphos
830839
;;
840
+ moxiebox)
841
+ basic_machine=moxie-unknown
842
+ os=-moxiebox
843
+ ;;
831844
msdos)
832845
basic_machine=i386-pc
833846
os=-msdos
834847
;;
835848
ms1-*)
@@ -1371,11 +1384,11 @@
13711384
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
13721385
| -chorusos* | -chorusrdb* | -cegcc* \
13731386
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
13741387
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
13751388
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
1376
- | -uxpv* | -beos* | -mpeix* | -udk* \
1389
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
13771390
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
13781391
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
13791392
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
13801393
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
13811394
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
13821395
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -1,10 +1,10 @@
1 #! /bin/sh
2 # Configuration validation subroutine script.
3 # Copyright 1992-2014 Free Software Foundation, Inc.
4
5 timestamp='2014-05-01'
6
7 # This file is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
@@ -23,11 +23,11 @@
23 # the same distribution terms that you use for the rest of that
24 # program. This Exception is an additional permission under section 7
25 # of the GNU General Public License, version 3 ("GPLv3").
26
27
28 # Please send patches with a ChangeLog entry to [email protected].
29 #
30 # Configuration subroutine to validate and canonicalize a configuration type.
31 # Supply the specified configuration type as an argument.
32 # If it is invalid, we print an error message on stderr and exit with code 1.
33 # Otherwise, we print the canonical config type on stdout and succeed.
@@ -300,10 +300,11 @@
300 | ns16k | ns32k \
301 | open8 | or1k | or1knd | or32 \
302 | pdp10 | pdp11 | pj | pjl \
303 | powerpc | powerpc64 | powerpc64le | powerpcle \
304 | pyramid \
 
305 | rl78 | rx \
306 | score \
307 | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
308 | sh64 | sh64le \
309 | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
@@ -310,10 +311,11 @@
310 | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
311 | spu \
312 | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
313 | ubicom32 \
314 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
 
315 | we32k \
316 | x86 | xc16x | xstormy16 | xtensa \
317 | z8k | z80)
318 basic_machine=$basic_machine-unknown
319 ;;
@@ -324,10 +326,13 @@
324 basic_machine=tic55x-unknown
325 ;;
326 c6x)
327 basic_machine=tic6x-unknown
328 ;;
 
 
 
329 m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
330 basic_machine=$basic_machine-unknown
331 os=-none
332 ;;
333 m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
@@ -434,10 +439,11 @@
434 | tile*-* \
435 | tron-* \
436 | ubicom32-* \
437 | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
438 | vax-* \
 
439 | we32k-* \
440 | x86-* | x86_64-* | xc16x-* | xps100-* \
441 | xstormy16-* | xtensa*-* \
442 | ymp-* \
443 | z8k-* | z80-*)
@@ -771,10 +777,13 @@
771 ;;
772 isi68 | isi)
773 basic_machine=m68k-isi
774 os=-sysv
775 ;;
 
 
 
776 m68knommu)
777 basic_machine=m68k-unknown
778 os=-linux
779 ;;
780 m68knommu-*)
@@ -826,10 +835,14 @@
826 ;;
827 morphos)
828 basic_machine=powerpc-unknown
829 os=-morphos
830 ;;
 
 
 
 
831 msdos)
832 basic_machine=i386-pc
833 os=-msdos
834 ;;
835 ms1-*)
@@ -1371,11 +1384,11 @@
1371 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
1372 | -chorusos* | -chorusrdb* | -cegcc* \
1373 | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1374 | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
1375 | -linux-newlib* | -linux-musl* | -linux-uclibc* \
1376 | -uxpv* | -beos* | -mpeix* | -udk* \
1377 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
1378 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
1379 | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
1380 | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
1381 | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
1382
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -1,10 +1,10 @@
1 #! /bin/sh
2 # Configuration validation subroutine script.
3 # Copyright 1992-2014 Free Software Foundation, Inc.
4
5 timestamp='2014-12-03'
6
7 # This file is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
@@ -23,11 +23,11 @@
23 # the same distribution terms that you use for the rest of that
24 # program. This Exception is an additional permission under section 7
25 # of the GNU General Public License, version 3 ("GPLv3").
26
27
28 # Please send patches to <[email protected]>.
29 #
30 # Configuration subroutine to validate and canonicalize a configuration type.
31 # Supply the specified configuration type as an argument.
32 # If it is invalid, we print an error message on stderr and exit with code 1.
33 # Otherwise, we print the canonical config type on stdout and succeed.
@@ -300,10 +300,11 @@
300 | ns16k | ns32k \
301 | open8 | or1k | or1knd | or32 \
302 | pdp10 | pdp11 | pj | pjl \
303 | powerpc | powerpc64 | powerpc64le | powerpcle \
304 | pyramid \
305 | riscv32 | riscv64 \
306 | rl78 | rx \
307 | score \
308 | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
309 | sh64 | sh64le \
310 | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
@@ -310,10 +311,11 @@
311 | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
312 | spu \
313 | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
314 | ubicom32 \
315 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
316 | visium \
317 | we32k \
318 | x86 | xc16x | xstormy16 | xtensa \
319 | z8k | z80)
320 basic_machine=$basic_machine-unknown
321 ;;
@@ -324,10 +326,13 @@
326 basic_machine=tic55x-unknown
327 ;;
328 c6x)
329 basic_machine=tic6x-unknown
330 ;;
331 leon|leon[3-9])
332 basic_machine=sparc-$basic_machine
333 ;;
334 m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
335 basic_machine=$basic_machine-unknown
336 os=-none
337 ;;
338 m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
@@ -434,10 +439,11 @@
439 | tile*-* \
440 | tron-* \
441 | ubicom32-* \
442 | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
443 | vax-* \
444 | visium-* \
445 | we32k-* \
446 | x86-* | x86_64-* | xc16x-* | xps100-* \
447 | xstormy16-* | xtensa*-* \
448 | ymp-* \
449 | z8k-* | z80-*)
@@ -771,10 +777,13 @@
777 ;;
778 isi68 | isi)
779 basic_machine=m68k-isi
780 os=-sysv
781 ;;
782 leon-*|leon[3-9]-*)
783 basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
784 ;;
785 m68knommu)
786 basic_machine=m68k-unknown
787 os=-linux
788 ;;
789 m68knommu-*)
@@ -826,10 +835,14 @@
835 ;;
836 morphos)
837 basic_machine=powerpc-unknown
838 os=-morphos
839 ;;
840 moxiebox)
841 basic_machine=moxie-unknown
842 os=-moxiebox
843 ;;
844 msdos)
845 basic_machine=i386-pc
846 os=-msdos
847 ;;
848 ms1-*)
@@ -1371,11 +1384,11 @@
1384 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
1385 | -chorusos* | -chorusrdb* | -cegcc* \
1386 | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1387 | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
1388 | -linux-newlib* | -linux-musl* | -linux-uclibc* \
1389 | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
1390 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
1391 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
1392 | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
1393 | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
1394 | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
1395
+2101 -2054
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,20 +1,18 @@
11
/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */
2
-#define _GNU_SOURCE
32
#define JIM_TCL_COMPAT
4
-#define JIM_REFERENCES
53
#define JIM_ANSIC
64
#define JIM_REGEXP
75
#define HAVE_NO_AUTOCONF
86
#define _JIMAUTOCONF_H
97
#define TCL_LIBRARY "."
108
#define jim_ext_bootstrap
119
#define jim_ext_aio
1210
#define jim_ext_readdir
13
-#define jim_ext_glob
1411
#define jim_ext_regexp
1512
#define jim_ext_file
13
+#define jim_ext_glob
1614
#define jim_ext_exec
1715
#define jim_ext_clock
1816
#define jim_ext_array
1917
#define jim_ext_stdlib
2018
#define jim_ext_tclcompat
@@ -35,20 +33,26 @@
3533
#define HAVE_UNISTD_H
3634
#else
3735
#define TCL_PLATFORM_OS "unknown"
3836
#define TCL_PLATFORM_PLATFORM "unix"
3937
#define TCL_PLATFORM_PATH_SEPARATOR ":"
38
+#ifdef _MINIX
39
+#define vfork fork
40
+#define _POSIX_SOURCE
41
+#else
42
+#define _GNU_SOURCE
43
+#endif
4044
#define HAVE_VFORK
4145
#define HAVE_WAITPID
4246
#define HAVE_ISATTY
4347
#define HAVE_MKSTEMP
4448
#define HAVE_LINK
4549
#define HAVE_SYS_TIME_H
4650
#define HAVE_DIRENT_H
4751
#define HAVE_UNISTD_H
4852
#endif
49
-#define JIM_VERSION 76
53
+#define JIM_VERSION 77
5054
#ifndef JIM_WIN32COMPAT_H
5155
#define JIM_WIN32COMPAT_H
5256
5357
5458
@@ -64,11 +68,13 @@
6468
int dlclose(void *handle);
6569
void *dlsym(void *handle, const char *symbol);
6670
char *dlerror(void);
6771
6872
69
-#define JIM_SPRINTF_DOUBLE_NEEDS_FIX
73
+#if defined(__MINGW32__)
74
+ #define JIM_SPRINTF_DOUBLE_NEEDS_FIX
75
+#endif
7076
7177
#ifdef _MSC_VER
7278
7379
7480
#if _MSC_VER >= 1000
@@ -103,14 +109,14 @@
103109
struct dirent {
104110
char *d_name;
105111
};
106112
107113
typedef struct DIR {
108
- long handle;
114
+ long handle;
109115
struct _finddata_t info;
110
- struct dirent result;
111
- char *name;
116
+ struct dirent result;
117
+ char *name;
112118
} DIR;
113119
114120
DIR *opendir(const char *name);
115121
int closedir(DIR *dir);
116122
struct dirent *readdir(DIR *dir);
@@ -120,11 +126,11 @@
120126
#include <stdlib.h>
121127
#define strtod __strtod
122128
123129
#endif
124130
125
-#endif
131
+#endif
126132
127133
#ifdef __cplusplus
128134
}
129135
#endif
130136
@@ -173,13 +179,13 @@
173179
extern "C" {
174180
#endif
175181
176182
#include <time.h>
177183
#include <limits.h>
178
-#include <stdio.h>
179
-#include <stdlib.h>
180
-#include <stdarg.h>
184
+#include <stdio.h>
185
+#include <stdlib.h>
186
+#include <stdarg.h>
181187
182188
183189
#ifndef HAVE_NO_AUTOCONF
184190
#endif
185191
@@ -222,31 +228,31 @@
222228
#define JIM_SIGNAL 5
223229
#define JIM_EXIT 6
224230
225231
#define JIM_EVAL 7
226232
227
-#define JIM_MAX_CALLFRAME_DEPTH 1000
228
-#define JIM_MAX_EVAL_DEPTH 2000
233
+#define JIM_MAX_CALLFRAME_DEPTH 1000
234
+#define JIM_MAX_EVAL_DEPTH 2000
229235
230236
231237
#define JIM_PRIV_FLAG_SHIFT 20
232238
233
-#define JIM_NONE 0
234
-#define JIM_ERRMSG 1
235
-#define JIM_ENUM_ABBREV 2
236
-#define JIM_UNSHARED 4
237
-#define JIM_MUSTEXIST 8
238
-
239
-
240
-#define JIM_SUBST_NOVAR 1
241
-#define JIM_SUBST_NOCMD 2
242
-#define JIM_SUBST_NOESC 4
243
-#define JIM_SUBST_FLAG 128
244
-
245
-
246
-#define JIM_CASESENS 0
247
-#define JIM_NOCASE 1
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
248254
249255
250256
#define JIM_PATH_LEN 1024
251257
252258
@@ -337,79 +343,79 @@
337343
#define Jim_GetHashTableSize(ht) ((ht)->size)
338344
#define Jim_GetHashTableUsed(ht) ((ht)->used)
339345
340346
341347
typedef struct Jim_Obj {
342
- char *bytes;
343
- const struct Jim_ObjType *typePtr;
344
- int refCount;
345
- int length;
346
-
348
+ char *bytes;
349
+ const struct Jim_ObjType *typePtr;
350
+ int refCount;
351
+ int length;
352
+
347353
union {
348
-
354
+
349355
jim_wide wideValue;
350
-
356
+
351357
int intValue;
352
-
358
+
353359
double doubleValue;
354
-
360
+
355361
void *ptr;
356
-
362
+
357363
struct {
358364
void *ptr1;
359365
void *ptr2;
360366
} twoPtrValue;
361
-
367
+
362368
struct {
363369
struct Jim_Var *varPtr;
364
- unsigned long callFrameId;
365
- int global;
370
+ unsigned long callFrameId;
371
+ int global;
366372
} varValue;
367
-
373
+
368374
struct {
369375
struct Jim_Obj *nsObj;
370376
struct Jim_Cmd *cmdPtr;
371
- unsigned long procEpoch;
377
+ unsigned long procEpoch;
372378
} cmdValue;
373
-
379
+
374380
struct {
375
- struct Jim_Obj **ele;
376
- int len;
377
- int maxLen;
381
+ struct Jim_Obj **ele;
382
+ int len;
383
+ int maxLen;
378384
} listValue;
379
-
385
+
380386
struct {
381387
int maxLength;
382
- int charLength;
388
+ int charLength;
383389
} strValue;
384
-
390
+
385391
struct {
386392
unsigned long id;
387393
struct Jim_Reference *refPtr;
388394
} refValue;
389
-
395
+
390396
struct {
391397
struct Jim_Obj *fileNameObj;
392398
int lineNumber;
393399
} sourceValue;
394
-
400
+
395401
struct {
396402
struct Jim_Obj *varNameObjPtr;
397403
struct Jim_Obj *indexObjPtr;
398404
} dictSubstValue;
399
-
405
+
400406
struct {
401
- void *compre;
407
+ void *compre;
402408
unsigned flags;
403409
} regexpValue;
404410
struct {
405411
int line;
406412
int argc;
407413
} scriptLineValue;
408414
} internalRep;
409
- struct Jim_Obj *prevObjPtr;
410
- struct Jim_Obj *nextObjPtr;
415
+ struct Jim_Obj *prevObjPtr;
416
+ struct Jim_Obj *nextObjPtr;
411417
} Jim_Obj;
412418
413419
414420
#define Jim_IncrRefCount(objPtr) \
415421
++(objPtr)->refCount
@@ -440,43 +446,40 @@
440446
typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
441447
struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
442448
typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
443449
444450
typedef struct Jim_ObjType {
445
- const char *name;
451
+ const char *name;
446452
Jim_FreeInternalRepProc *freeIntRepProc;
447453
Jim_DupInternalRepProc *dupIntRepProc;
448454
Jim_UpdateStringProc *updateStringProc;
449455
int flags;
450456
} Jim_ObjType;
451457
452458
453
-#define JIM_TYPE_NONE 0
454
-#define JIM_TYPE_REFERENCES 1
455
-
456
-#define JIM_PRIV_FLAG_SHIFT 20
459
+#define JIM_TYPE_NONE 0
460
+#define JIM_TYPE_REFERENCES 1
457461
458462
459463
460464
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;
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;
473477
int line;
474
- Jim_Stack *localCommands;
475
- int tailcall;
476
- struct Jim_Obj *tailcallObj;
477
- struct Jim_Cmd *tailcallCmd;
478
+ Jim_Stack *localCommands;
479
+ struct Jim_Obj *tailcallObj;
480
+ struct Jim_Cmd *tailcallCmd;
478481
} Jim_CallFrame;
479482
480483
typedef struct Jim_Var {
481484
Jim_Obj *objPtr;
482485
struct Jim_CallFrame *linkFramePtr;
@@ -488,35 +491,35 @@
488491
typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
489492
490493
491494
492495
typedef struct Jim_Cmd {
493
- int inUse;
494
- int isproc;
495
- struct Jim_Cmd *prevCmd;
496
+ int inUse;
497
+ int isproc;
498
+ struct Jim_Cmd *prevCmd;
496499
union {
497500
struct {
498
-
499
- Jim_CmdProc *cmdProc;
500
- Jim_DelCmdProc *delProc;
501
- void *privData;
501
+
502
+ Jim_CmdProc *cmdProc;
503
+ Jim_DelCmdProc *delProc;
504
+ void *privData;
502505
} native;
503506
struct {
504
-
507
+
505508
Jim_Obj *argListObjPtr;
506509
Jim_Obj *bodyObjPtr;
507
- Jim_HashTable *staticVars;
508
- int argListLen;
509
- int reqArity;
510
- int optArity;
511
- int argsPos;
512
- int upcall;
510
+ Jim_HashTable *staticVars;
511
+ int argListLen;
512
+ int reqArity;
513
+ int optArity;
514
+ int argsPos;
515
+ int upcall;
513516
struct Jim_ProcArg {
514
- Jim_Obj *nameObjPtr;
515
- Jim_Obj *defaultObjPtr;
517
+ Jim_Obj *nameObjPtr;
518
+ Jim_Obj *defaultObjPtr;
516519
} *arglist;
517
- Jim_Obj *nsObj;
520
+ Jim_Obj *nsObj;
518521
} proc;
519522
} u;
520523
} Jim_Cmd;
521524
522525
@@ -524,64 +527,64 @@
524527
unsigned char sbox[256];
525528
unsigned int i, j;
526529
} Jim_PrngState;
527530
528531
typedef struct Jim_Interp {
529
- Jim_Obj *result;
530
- int errorLine;
531
- Jim_Obj *errorFileNameObj;
532
- int addStackTrace;
533
- int maxCallFrameDepth;
534
- int maxEvalDepth;
535
- int evalDepth;
536
- int returnCode;
537
- int returnLevel;
538
- int exitCode;
539
- long id;
540
- int signal_level;
541
- jim_wide sigmask;
542
- int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
543
- Jim_CallFrame *framePtr;
544
- Jim_CallFrame *topFramePtr;
545
- struct Jim_HashTable commands;
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;
546549
unsigned long procEpoch; /* Incremented every time the result
547550
of procedures names lookup caching
548551
may no longer be valid. */
549552
unsigned long callFrameEpoch; /* Incremented every time a new
550553
callframe is created. This id is used for the
551554
'ID' field contained in the Jim_CallFrame
552555
structure. */
553
- int local;
554
- Jim_Obj *liveList;
555
- Jim_Obj *freeList;
556
- Jim_Obj *currentScriptObj;
557
- Jim_Obj *nullScriptObj;
558
- Jim_Obj *emptyObj;
559
- Jim_Obj *trueObj;
560
- Jim_Obj *falseObj;
561
- unsigned long referenceNextId;
562
- struct Jim_HashTable references;
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;
563566
unsigned long lastCollectId; /* reference max Id of the last GC
564567
execution. It's set to -1 while the collection
565568
is running as sentinel to avoid to recursive
566569
calls via the [collect] command inside
567570
finalizers. */
568
- time_t lastCollectTime;
569
- Jim_Obj *stackTrace;
570
- Jim_Obj *errorProc;
571
- Jim_Obj *unknown;
572
- int unknown_called;
573
- int errorFlag;
571
+ time_t lastCollectTime;
572
+ Jim_Obj *stackTrace;
573
+ Jim_Obj *errorProc;
574
+ Jim_Obj *unknown;
575
+ int unknown_called;
576
+ int errorFlag;
574577
void *cmdPrivData; /* Used to pass the private data pointer to
575578
a command. It is set to what the user specified
576579
via Jim_CreateCommand(). */
577580
578
- struct Jim_CallFrame *freeFramesList;
579
- struct Jim_HashTable assocData;
580
- Jim_PrngState *prngState;
581
- struct Jim_HashTable packages;
582
- Jim_Stack *loadHandles;
581
+ struct Jim_CallFrame *freeFramesList;
582
+ struct Jim_HashTable assocData;
583
+ Jim_PrngState *prngState;
584
+ struct Jim_HashTable packages;
585
+ Jim_Stack *loadHandles;
583586
} Jim_Interp;
584587
585588
#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
586589
#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
587590
#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -737,12 +740,12 @@
737740
JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...);
738741
739742
740743
JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp);
741744
JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp,
742
- const char *cmdName, Jim_CmdProc cmdProc, void *privData,
743
- Jim_DelCmdProc delProc);
745
+ const char *cmdName, Jim_CmdProc *cmdProc, void *privData,
746
+ Jim_DelCmdProc *delProc);
744747
JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp,
745748
const char *cmdName);
746749
JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp,
747750
const char *oldName, const char *newName);
748751
JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp,
@@ -832,10 +835,14 @@
832835
JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
833836
Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
834837
JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
835838
Jim_Obj *exprObjPtr, int *boolPtr);
836839
840
+
841
+JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr,
842
+ int *booleanPtr);
843
+
837844
838845
JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
839846
jim_wide *widePtr);
840847
JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
841848
long *longPtr);
@@ -853,12 +860,13 @@
853860
854861
JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc,
855862
Jim_Obj *const *argv, const char *msg);
856863
JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr,
857864
const char * const *tablePtr, int *indexPtr, const char *name, int flags);
858
-JIM_EXPORT int Jim_ScriptIsComplete (const char *s, int len,
859
- char *stateCharPtr);
865
+JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp,
866
+ Jim_Obj *scriptObj, char *stateCharPtr);
867
+
860868
JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len);
861869
862870
863871
typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data);
864872
JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key);
@@ -904,11 +912,11 @@
904912
905913
#ifdef __cplusplus
906914
}
907915
#endif
908916
909
-#endif
917
+#endif
910918
911919
#ifndef JIM_SUBCMD_H
912920
#define JIM_SUBCMD_H
913921
914922
@@ -915,24 +923,24 @@
915923
#ifdef __cplusplus
916924
extern "C" {
917925
#endif
918926
919927
920
-#define JIM_MODFLAG_HIDDEN 0x0001
921
-#define JIM_MODFLAG_FULLARGV 0x0002
928
+#define JIM_MODFLAG_HIDDEN 0x0001
929
+#define JIM_MODFLAG_FULLARGV 0x0002
922930
923931
924932
925933
typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
926934
927935
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;
936
+ const char *cmd;
937
+ const char *args;
938
+ jim_subcmd_function *function;
939
+ short minargs;
940
+ short maxargs;
941
+ unsigned short flags;
934942
} jim_subcmd_type;
935943
936944
const jim_subcmd_type *
937945
Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv);
938946
@@ -960,36 +968,36 @@
960968
int rm_eo;
961969
} regmatch_t;
962970
963971
964972
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;
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;
991999
} regexp;
9921000
9931001
typedef regexp regex_t;
9941002
9951003
#define REG_EXTENDED 0
@@ -997,13 +1005,13 @@
9971005
#define REG_ICASE 2
9981006
9991007
#define REG_NOTBOL 16
10001008
10011009
enum {
1002
- REG_NOERROR,
1003
- REG_NOMATCH,
1004
- REG_BADPAT,
1010
+ REG_NOERROR,
1011
+ REG_NOMATCH,
1012
+ REG_BADPAT,
10051013
REG_ERR_NULL_ARGUMENT,
10061014
REG_ERR_UNKNOWN,
10071015
REG_ERR_TOO_BIG,
10081016
REG_ERR_NOMEM,
10091017
REG_ERR_TOO_MANY_PAREN,
@@ -1037,11 +1045,20 @@
10371045
return JIM_ERR;
10381046
10391047
return Jim_EvalSource(interp, "bootstrap.tcl", 1,
10401048
"\n"
10411049
"\n"
1042
-"proc package {args} {}\n"
1050
+"proc package {cmd pkg} {\n"
1051
+" if {$cmd eq \"require\"} {\n"
1052
+" foreach path $::auto_path {\n"
1053
+" if {[file exists $path/$pkg.tcl]} {\n"
1054
+" uplevel #0 [list source $path/$pkg.tcl]\n"
1055
+" return\n"
1056
+" }\n"
1057
+" }\n"
1058
+" }\n"
1059
+"}\n"
10431060
);
10441061
}
10451062
int Jim_initjimshInit(Jim_Interp *interp)
10461063
{
10471064
if (Jim_PackageProvide(interp, "initjimsh", "1.0", JIM_ERRMSG))
@@ -1771,10 +1788,11 @@
17711788
"}\n"
17721789
);
17731790
}
17741791
17751792
1793
+#define _GNU_SOURCE
17761794
#include <stdio.h>
17771795
#include <string.h>
17781796
#include <errno.h>
17791797
#include <fcntl.h>
17801798
#ifdef HAVE_UNISTD_H
@@ -1793,13 +1811,18 @@
17931811
#endif
17941812
#else
17951813
#define JIM_ANSIC
17961814
#endif
17971815
1816
+#if defined(JIM_SSL)
1817
+#include <openssl/ssl.h>
1818
+#include <openssl/err.h>
1819
+#endif
17981820
1799
-#define AIO_CMD_LEN 32
1800
-#define AIO_BUF_LEN 256
1821
+
1822
+#define AIO_CMD_LEN 32
1823
+#define AIO_BUF_LEN 256
18011824
18021825
#ifndef HAVE_FTELLO
18031826
#define ftello ftell
18041827
#endif
18051828
#ifndef HAVE_FSEEKO
@@ -1815,66 +1838,61 @@
18151838
#ifndef PF_INET6
18161839
#define PF_INET6 0
18171840
#endif
18181841
#endif
18191842
1843
+#define JimCheckStreamError(interp, af) af->fops->error(af)
1844
+
1845
+
1846
+struct AioFile;
1847
+
1848
+typedef struct {
1849
+ int (*writer)(struct AioFile *af, const char *buf, int len);
1850
+ int (*reader)(struct AioFile *af, char *buf, int len);
1851
+ const char *(*getline)(struct AioFile *af, char *buf, int len);
1852
+ int (*error)(const struct AioFile *af);
1853
+ const char *(*strerror)(struct AioFile *af);
1854
+ int (*verify)(struct AioFile *af);
1855
+} JimAioFopsType;
18201856
18211857
typedef struct AioFile
18221858
{
18231859
FILE *fp;
18241860
Jim_Obj *filename;
18251861
int type;
1826
- int openFlags;
1862
+ int openFlags;
18271863
int fd;
18281864
Jim_Obj *rEvent;
18291865
Jim_Obj *wEvent;
18301866
Jim_Obj *eEvent;
18311867
int addr_family;
1868
+ void *ssl;
1869
+ const JimAioFopsType *fops;
18321870
} AioFile;
18331871
1834
-static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
1835
-static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
1836
- const char *hdlfmt, int family, const char *mode);
1837
-
1838
-
1839
-static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
1840
-{
1841
- if (name) {
1842
- Jim_SetResultFormatted(interp, "%#s: %s", name, strerror(errno));
1843
- }
1844
- else {
1845
- Jim_SetResultString(interp, strerror(errno), -1);
1846
- }
1847
-}
1848
-
1849
-static void JimAioDelProc(Jim_Interp *interp, void *privData)
1850
-{
1851
- AioFile *af = privData;
1852
-
1853
- JIM_NOTUSED(interp);
1854
-
1855
- Jim_DecrRefCount(interp, af->filename);
1856
-
1857
-#ifdef jim_ext_eventloop
1858
-
1859
- Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
1860
-#endif
1861
-
1862
- if (!(af->openFlags & AIO_KEEPOPEN)) {
1863
- fclose(af->fp);
1864
- }
1865
-
1866
- Jim_Free(af);
1867
-}
1868
-
1869
-static int JimCheckStreamError(Jim_Interp *interp, AioFile *af)
1872
+static int stdio_writer(struct AioFile *af, const char *buf, int len)
1873
+{
1874
+ return fwrite(buf, 1, len, af->fp);
1875
+}
1876
+
1877
+static int stdio_reader(struct AioFile *af, char *buf, int len)
1878
+{
1879
+ return fread(buf, 1, len, af->fp);
1880
+}
1881
+
1882
+static const char *stdio_getline(struct AioFile *af, char *buf, int len)
1883
+{
1884
+ return fgets(buf, len, af->fp);
1885
+}
1886
+
1887
+static int stdio_error(const AioFile *af)
18701888
{
18711889
if (!ferror(af->fp)) {
18721890
return JIM_OK;
18731891
}
18741892
clearerr(af->fp);
1875
-
1893
+
18761894
if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
18771895
return JIM_OK;
18781896
}
18791897
#ifdef ECONNRESET
18801898
if (errno == ECONNRESET) {
@@ -1884,21 +1902,86 @@
18841902
#ifdef ECONNABORTED
18851903
if (errno != ECONNABORTED) {
18861904
return JIM_OK;
18871905
}
18881906
#endif
1889
- JimAioSetError(interp, af->filename);
18901907
return JIM_ERR;
18911908
}
1909
+
1910
+static const char *stdio_strerror(struct AioFile *af)
1911
+{
1912
+ return strerror(errno);
1913
+}
1914
+
1915
+static const JimAioFopsType stdio_fops = {
1916
+ stdio_writer,
1917
+ stdio_reader,
1918
+ stdio_getline,
1919
+ stdio_error,
1920
+ stdio_strerror,
1921
+ NULL
1922
+};
1923
+
1924
+
1925
+static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
1926
+static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
1927
+ const char *hdlfmt, int family, const char *mode);
1928
+
1929
+
1930
+static const char *JimAioErrorString(AioFile *af)
1931
+{
1932
+ if (af && af->fops)
1933
+ return af->fops->strerror(af);
1934
+
1935
+ return strerror(errno);
1936
+}
1937
+
1938
+static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
1939
+{
1940
+ AioFile *af = Jim_CmdPrivData(interp);
1941
+
1942
+ if (name) {
1943
+ Jim_SetResultFormatted(interp, "%#s: %s", name, JimAioErrorString(af));
1944
+ }
1945
+ else {
1946
+ Jim_SetResultString(interp, JimAioErrorString(af), -1);
1947
+ }
1948
+}
1949
+
1950
+static void JimAioDelProc(Jim_Interp *interp, void *privData)
1951
+{
1952
+ AioFile *af = privData;
1953
+
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);
1966
+ }
1967
+#endif
1968
+
1969
+ if (!(af->openFlags & AIO_KEEPOPEN)) {
1970
+ fclose(af->fp);
1971
+ }
1972
+
1973
+ Jim_Free(af);
1974
+}
18921975
18931976
static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18941977
{
18951978
AioFile *af = Jim_CmdPrivData(interp);
18961979
char buf[AIO_BUF_LEN];
18971980
Jim_Obj *objPtr;
18981981
int nonewline = 0;
1899
- jim_wide neededLen = -1;
1982
+ jim_wide neededLen = -1;
19001983
19011984
if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
19021985
nonewline = 1;
19031986
argv++;
19041987
argc--;
@@ -1923,21 +2006,21 @@
19232006
readlen = AIO_BUF_LEN;
19242007
}
19252008
else {
19262009
readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen);
19272010
}
1928
- retval = fread(buf, 1, readlen, af->fp);
2011
+ retval = af->fops->reader(af, buf, readlen);
19292012
if (retval > 0) {
19302013
Jim_AppendString(interp, objPtr, buf, retval);
19312014
if (neededLen != -1) {
19322015
neededLen -= retval;
19332016
}
19342017
}
19352018
if (retval != readlen)
19362019
break;
19372020
}
1938
-
2021
+
19392022
if (JimCheckStreamError(interp, af)) {
19402023
Jim_FreeNewObj(interp, objPtr);
19412024
return JIM_ERR;
19422025
}
19432026
if (nonewline) {
@@ -1950,19 +2033,43 @@
19502033
}
19512034
}
19522035
Jim_SetResult(interp, objPtr);
19532036
return JIM_OK;
19542037
}
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;
2049
+}
2050
+
2051
+FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
2052
+{
2053
+ AioFile *af;
2054
+
2055
+ af = Jim_AioFile(interp, command);
2056
+ if (af == NULL) {
2057
+ return NULL;
2058
+ }
2059
+
2060
+ return af->fp;
2061
+}
19552062
19562063
static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19572064
{
19582065
AioFile *af = Jim_CmdPrivData(interp);
19592066
jim_wide count = 0;
19602067
jim_wide maxlen = JIM_WIDE_MAX;
1961
- FILE *outfh = Jim_AioFilehandle(interp, argv[0]);
2068
+ AioFile *outf = Jim_AioFile(interp, argv[0]);
19622069
1963
- if (outfh == NULL) {
2070
+ if (outf == NULL) {
19642071
return JIM_ERR;
19652072
}
19662073
19672074
if (argc == 2) {
19682075
if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) {
@@ -1969,27 +2076,22 @@
19692076
return JIM_ERR;
19702077
}
19712078
}
19722079
19732080
while (count < maxlen) {
1974
- int ch = fgetc(af->fp);
2081
+ char ch;
19752082
1976
- if (ch == EOF || fputc(ch, outfh) == EOF) {
2083
+ if (af->fops->reader(af, &ch, 1) != 1) {
2084
+ break;
2085
+ }
2086
+ if (outf->fops->writer(outf, &ch, 1) != 1) {
19772087
break;
19782088
}
19792089
count++;
19802090
}
19812091
1982
- if (ferror(af->fp)) {
1983
- Jim_SetResultFormatted(interp, "error while reading: %s", strerror(errno));
1984
- clearerr(af->fp);
1985
- return JIM_ERR;
1986
- }
1987
-
1988
- if (ferror(outfh)) {
1989
- Jim_SetResultFormatted(interp, "error while writing: %s", strerror(errno));
1990
- clearerr(outfh);
2092
+ if (JimCheckStreamError(interp, af) || JimCheckStreamError(interp, outf)) {
19912093
return JIM_ERR;
19922094
}
19932095
19942096
Jim_SetResultInt(interp, count);
19952097
@@ -2006,30 +2108,32 @@
20062108
errno = 0;
20072109
20082110
objPtr = Jim_NewStringObj(interp, NULL, 0);
20092111
while (1) {
20102112
buf[AIO_BUF_LEN - 1] = '_';
2011
- if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL)
2113
+
2114
+ if (af->fops->getline(af, buf, AIO_BUF_LEN) == NULL)
20122115
break;
20132116
20142117
if (buf[AIO_BUF_LEN - 1] == '\0' && buf[AIO_BUF_LEN - 2] != '\n') {
20152118
Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN - 1);
20162119
}
20172120
else {
20182121
len = strlen(buf);
20192122
20202123
if (len && (buf[len - 1] == '\n')) {
2021
-
2124
+
20222125
len--;
20232126
}
20242127
20252128
Jim_AppendString(interp, objPtr, buf, len);
20262129
break;
20272130
}
20282131
}
2132
+
20292133
if (JimCheckStreamError(interp, af)) {
2030
-
2134
+
20312135
Jim_FreeNewObj(interp, objPtr);
20322136
return JIM_ERR;
20332137
}
20342138
20352139
if (argc) {
@@ -2039,11 +2143,11 @@
20392143
}
20402144
20412145
len = Jim_Length(objPtr);
20422146
20432147
if (len == 0 && feof(af->fp)) {
2044
-
2148
+
20452149
len = -1;
20462150
}
20472151
Jim_SetResultInt(interp, len);
20482152
}
20492153
else {
@@ -2068,12 +2172,12 @@
20682172
else {
20692173
strObj = argv[0];
20702174
}
20712175
20722176
wdata = Jim_GetString(strObj, &wlen);
2073
- if (fwrite(wdata, 1, wlen, af->fp) == (unsigned)wlen) {
2074
- if (argc == 2 || putc('\n', af->fp) != EOF) {
2177
+ if (af->fops->writer(af, wdata, wlen) == wlen) {
2178
+ if (argc == 2 || af->fops->writer(af, "\n", 1) == 1) {
20752179
return JIM_OK;
20762180
}
20772181
}
20782182
JimAioSetError(interp, af->filename);
20792183
return JIM_ERR;
@@ -2202,10 +2306,21 @@
22022306
}
22032307
Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0);
22042308
return JIM_OK;
22052309
}
22062310
#endif
2311
+
2312
+#ifdef HAVE_FSYNC
2313
+static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2314
+{
2315
+ AioFile *af = Jim_CmdPrivData(interp);
2316
+
2317
+ fflush(af->fp);
2318
+ fsync(af->fd);
2319
+ return JIM_OK;
2320
+}
2321
+#endif
22072322
22082323
static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
22092324
{
22102325
AioFile *af = Jim_CmdPrivData(interp);
22112326
@@ -2258,33 +2373,33 @@
22582373
22592374
static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
22602375
int argc, Jim_Obj * const *argv)
22612376
{
22622377
if (argc == 0) {
2263
-
2378
+
22642379
if (*scriptHandlerObj) {
22652380
Jim_SetResult(interp, *scriptHandlerObj);
22662381
}
22672382
return JIM_OK;
22682383
}
22692384
22702385
if (*scriptHandlerObj) {
2271
-
2272
- Jim_DeleteFileHandler(interp, af->fp, mask);
2386
+
2387
+ Jim_DeleteFileHandler(interp, af->fd, mask);
22732388
}
22742389
2275
-
2390
+
22762391
if (Jim_Length(argv[0]) == 0) {
2277
-
2392
+
22782393
return JIM_OK;
22792394
}
22802395
2281
-
2396
+
22822397
Jim_IncrRefCount(argv[0]);
22832398
*scriptHandlerObj = argv[0];
22842399
2285
- Jim_CreateFileHandler(interp, af->fp, mask,
2400
+ Jim_CreateFileHandler(interp, af->fd, mask,
22862401
JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
22872402
22882403
return JIM_OK;
22892404
}
22902405
@@ -2307,127 +2422,138 @@
23072422
AioFile *af = Jim_CmdPrivData(interp);
23082423
23092424
return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
23102425
}
23112426
#endif
2427
+
2428
+
23122429
23132430
static const jim_subcmd_type aio_command_table[] = {
23142431
{ "read",
23152432
"?-nonewline? ?len?",
23162433
aio_cmd_read,
23172434
0,
23182435
2,
2319
-
2436
+
23202437
},
23212438
{ "copyto",
23222439
"handle ?size?",
23232440
aio_cmd_copy,
23242441
1,
23252442
2,
2326
-
2443
+
23272444
},
23282445
{ "gets",
23292446
"?var?",
23302447
aio_cmd_gets,
23312448
0,
23322449
1,
2333
-
2450
+
23342451
},
23352452
{ "puts",
23362453
"?-nonewline? str",
23372454
aio_cmd_puts,
23382455
1,
23392456
2,
2340
-
2457
+
23412458
},
23422459
{ "isatty",
23432460
NULL,
23442461
aio_cmd_isatty,
23452462
0,
23462463
0,
2347
-
2464
+
23482465
},
23492466
{ "flush",
23502467
NULL,
23512468
aio_cmd_flush,
23522469
0,
23532470
0,
2354
-
2471
+
23552472
},
23562473
{ "eof",
23572474
NULL,
23582475
aio_cmd_eof,
23592476
0,
23602477
0,
2361
-
2478
+
23622479
},
23632480
{ "close",
23642481
"?r(ead)|w(rite)?",
23652482
aio_cmd_close,
23662483
0,
23672484
1,
23682485
JIM_MODFLAG_FULLARGV,
2369
-
2486
+
23702487
},
23712488
{ "seek",
23722489
"offset ?start|current|end",
23732490
aio_cmd_seek,
23742491
1,
23752492
2,
2376
-
2493
+
23772494
},
23782495
{ "tell",
23792496
NULL,
23802497
aio_cmd_tell,
23812498
0,
23822499
0,
2383
-
2500
+
23842501
},
23852502
{ "filename",
23862503
NULL,
23872504
aio_cmd_filename,
23882505
0,
23892506
0,
2390
-
2507
+
23912508
},
23922509
#ifdef O_NDELAY
23932510
{ "ndelay",
23942511
"?0|1?",
23952512
aio_cmd_ndelay,
23962513
0,
23972514
1,
2398
-
2515
+
2516
+ },
2517
+#endif
2518
+#ifdef HAVE_FSYNC
2519
+ { "sync",
2520
+ NULL,
2521
+ aio_cmd_sync,
2522
+ 0,
2523
+ 0,
2524
+
23992525
},
24002526
#endif
24012527
{ "buffering",
24022528
"none|line|full",
24032529
aio_cmd_buffering,
24042530
1,
24052531
1,
2406
-
2532
+
24072533
},
24082534
#ifdef jim_ext_eventloop
24092535
{ "readable",
24102536
"?readable-script?",
24112537
aio_cmd_readable,
24122538
0,
24132539
1,
2414
-
2540
+
24152541
},
24162542
{ "writable",
24172543
"?writable-script?",
24182544
aio_cmd_writable,
24192545
0,
24202546
1,
2421
-
2547
+
24222548
},
24232549
{ "onexception",
24242550
"?exception-script?",
24252551
aio_cmd_onexception,
24262552
0,
24272553
1,
2428
-
2554
+
24292555
},
24302556
#endif
24312557
{ NULL }
24322558
};
24332559
@@ -2450,11 +2576,11 @@
24502576
24512577
#ifdef jim_ext_tclcompat
24522578
{
24532579
const char *filename = Jim_String(argv[1]);
24542580
2455
-
2581
+
24562582
if (*filename == '|') {
24572583
Jim_Obj *evalObj[3];
24582584
24592585
evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
24602586
evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2462,24 +2588,31 @@
24622588
24632589
return Jim_EvalObjVector(interp, 3, evalObj);
24642590
}
24652591
}
24662592
#endif
2467
- return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode);
2593
+ return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode) ? JIM_OK : JIM_ERR;
24682594
}
24692595
2470
-static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
2596
+
2597
+static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
24712598
const char *hdlfmt, int family, const char *mode)
24722599
{
24732600
AioFile *af;
24742601
char buf[AIO_CMD_LEN];
24752602
int openFlags = 0;
24762603
2604
+ snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
2605
+
24772606
if (fh) {
2478
- filename = Jim_NewStringObj(interp, hdlfmt, -1);
24792607
openFlags = AIO_KEEPOPEN;
24802608
}
2609
+
2610
+ snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
2611
+ if (!filename) {
2612
+ filename = Jim_NewStringObj(interp, buf, -1);
2613
+ }
24812614
24822615
Jim_IncrRefCount(filename);
24832616
24842617
if (fh == NULL) {
24852618
#if !defined(JIM_ANSIC)
@@ -2496,15 +2629,15 @@
24962629
if (fd >= 0) {
24972630
close(fd);
24982631
}
24992632
#endif
25002633
Jim_DecrRefCount(interp, filename);
2501
- return JIM_ERR;
2634
+ return NULL;
25022635
}
25032636
}
25042637
2505
-
2638
+
25062639
af = Jim_Alloc(sizeof(*af));
25072640
memset(af, 0, sizeof(*af));
25082641
af->fp = fh;
25092642
af->fd = fileno(fh);
25102643
af->filename = filename;
@@ -2513,34 +2646,36 @@
25132646
(void)fcntl(af->fd, F_SETFD, FD_CLOEXEC);
25142647
}
25152648
#endif
25162649
af->openFlags = openFlags;
25172650
af->addr_family = family;
2518
- snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
2651
+ af->fops = &stdio_fops;
2652
+ af->ssl = NULL;
2653
+
25192654
Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc);
25202655
25212656
Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
25222657
2523
- return JIM_OK;
2658
+ return af;
25242659
}
25252660
25262661
#if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H))
25272662
static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename,
25282663
const char *hdlfmt, int family, const char *mode[2])
25292664
{
2530
- if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) {
2665
+ if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0])) {
25312666
Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
25322667
Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
25332668
2534
- if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1]) == JIM_OK) {
2669
+ if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1])) {
25352670
Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
25362671
Jim_SetResult(interp, objPtr);
25372672
return JIM_OK;
25382673
}
25392674
}
25402675
2541
-
2676
+
25422677
close(p[0]);
25432678
close(p[1]);
25442679
JimAioSetError(interp, NULL);
25452680
return JIM_ERR;
25462681
}
@@ -2567,13 +2702,18 @@
25672702
}
25682703
else {
25692704
filenameObj = Jim_NewStringObj(interp, template, -1);
25702705
}
25712706
2707
+#if defined(S_IRWXG) && defined(S_IRWXO)
25722708
mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
2709
+#else
25732710
2574
-
2711
+ mask = umask(S_IXUSR);
2712
+#endif
2713
+
2714
+
25752715
fd = mkstemp(filenameObj->bytes);
25762716
umask(mask);
25772717
if (fd < 0) {
25782718
JimAioSetError(interp, filenameObj);
25792719
Jim_FreeNewObj(interp, filenameObj);
@@ -2586,33 +2726,26 @@
25862726
Jim_SetResultString(interp, "platform has no tempfile support", -1);
25872727
return -1;
25882728
#endif
25892729
}
25902730
2591
-FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
2592
-{
2593
- Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
2594
-
2595
-
2596
- if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
2597
- return ((AioFile *) cmdPtr->u.native.privData)->fp;
2598
- }
2599
- Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
2600
- return NULL;
2601
-}
26022731
26032732
int Jim_aioInit(Jim_Interp *interp)
26042733
{
26052734
if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG))
26062735
return JIM_ERR;
2736
+
2737
+#if defined(JIM_SSL)
2738
+ Jim_CreateCommand(interp, "load_ssl_certs", JimAioLoadSSLCertsCommand, NULL, NULL);
2739
+#endif
26072740
26082741
Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
26092742
#ifndef JIM_ANSIC
26102743
Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
26112744
#endif
26122745
2613
-
2746
+
26142747
JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
26152748
JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
26162749
JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
26172750
26182751
return JIM_OK;
@@ -2708,20 +2841,20 @@
27082841
{
27092842
regex_t *compre;
27102843
const char *pattern;
27112844
int ret;
27122845
2713
-
2846
+
27142847
if (objPtr->typePtr == &regexpObjType &&
27152848
objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
2716
-
2849
+
27172850
return objPtr->internalRep.regexpValue.compre;
27182851
}
27192852
2720
-
27212853
2722
-
2854
+
2855
+
27232856
pattern = Jim_String(objPtr);
27242857
compre = Jim_Alloc(sizeof(regex_t));
27252858
27262859
if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
27272860
char buf[100];
@@ -2769,11 +2902,11 @@
27692902
};
27702903
27712904
if (argc < 3) {
27722905
wrongNumArgs:
27732906
Jim_WrongNumArgs(interp, 1, argv,
2774
- "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
2907
+ "?-switch ...? exp string ?matchVar? ?subMatchVar ...?");
27752908
return JIM_ERR;
27762909
}
27772910
27782911
for (i = 1; i < argc; i++) {
27792912
const char *opt = Jim_String(argv[i]);
@@ -2878,11 +3011,11 @@
28783011
}
28793012
28803013
num_matches++;
28813014
28823015
if (opt_all && !opt_inline) {
2883
-
3016
+
28843017
goto try_next_match;
28853018
}
28863019
28873020
28883021
j = 0;
@@ -2918,11 +3051,11 @@
29183051
29193052
if (opt_inline) {
29203053
Jim_ListAppendElement(interp, resultListObj, resultObj);
29213054
}
29223055
else {
2923
-
3056
+
29243057
result = Jim_SetVariable(interp, argv[i], resultObj);
29253058
29263059
if (result != JIM_OK) {
29273060
Jim_FreeObj(interp, resultObj);
29283061
break;
@@ -2991,11 +3124,11 @@
29913124
};
29923125
29933126
if (argc < 4) {
29943127
wrongNumArgs:
29953128
Jim_WrongNumArgs(interp, 1, argv,
2996
- "?switches? exp string subSpec ?varName?");
3129
+ "?-switch ...? exp string subSpec ?varName?");
29973130
return JIM_ERR;
29983131
}
29993132
30003133
for (i = 1; i < argc; i++) {
30013134
const char *opt = Jim_String(argv[i]);
@@ -3045,11 +3178,11 @@
30453178
30463179
source_str = Jim_GetString(argv[i + 1], &source_len);
30473180
replace_str = Jim_GetString(argv[i + 2], &replace_len);
30483181
varname = argv[i + 3];
30493182
3050
-
3183
+
30513184
resultObj = Jim_NewStringObj(interp, "", 0);
30523185
30533186
if (offset) {
30543187
if (offset < 0) {
30553188
offset += source_len + 1;
@@ -3060,11 +3193,11 @@
30603193
else if (offset < 0) {
30613194
offset = 0;
30623195
}
30633196
}
30643197
3065
-
3198
+
30663199
Jim_AppendString(interp, resultObj, source_str, offset);
30673200
30683201
30693202
n = source_len - offset;
30703203
p = source_str + offset;
@@ -3102,11 +3235,11 @@
31023235
else if ((c == '\\') || (c == '&')) {
31033236
Jim_AppendString(interp, resultObj, replace_str + j, 1);
31043237
continue;
31053238
}
31063239
else {
3107
- Jim_AppendString(interp, resultObj, replace_str + j - 1, 2);
3240
+ Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2);
31083241
continue;
31093242
}
31103243
}
31113244
else {
31123245
Jim_AppendString(interp, resultObj, replace_str + j, 1);
@@ -3119,23 +3252,23 @@
31193252
}
31203253
31213254
p += pmatch[0].rm_eo;
31223255
n -= pmatch[0].rm_eo;
31233256
3124
-
3257
+
31253258
if (!opt_all || n == 0) {
31263259
break;
31273260
}
31283261
3129
-
3262
+
31303263
if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
31313264
break;
31323265
}
31333266
3134
-
3267
+
31353268
if (pattern[0] == '\0' && n) {
3136
-
3269
+
31373270
Jim_AppendString(interp, resultObj, p, 1);
31383271
p++;
31393272
n--;
31403273
}
31413274
@@ -3142,11 +3275,11 @@
31423275
regexec_flags |= REG_NOTBOL;
31433276
} while (n);
31443277
31453278
Jim_AppendString(interp, resultObj, p, -1);
31463279
3147
-
3280
+
31483281
if (argc - i == 4) {
31493282
result = Jim_SetVariable(interp, varname, resultObj);
31503283
31513284
if (result == JIM_OK) {
31523285
Jim_SetResultInt(interp, num_matches);
@@ -3248,11 +3381,11 @@
32483381
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
32493382
}
32503383
32513384
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
32523385
{
3253
-
3386
+
32543387
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
32553388
32563389
AppendStatElement(interp, listObj, "dev", sb->st_dev);
32573390
AppendStatElement(interp, listObj, "ino", sb->st_ino);
32583391
AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3264,25 +3397,25 @@
32643397
AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
32653398
AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
32663399
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
32673400
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
32683401
3269
-
3402
+
32703403
if (varName) {
32713404
Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
32723405
if (objPtr) {
32733406
if (Jim_DictSize(interp, objPtr) < 0) {
3274
-
3407
+
32753408
Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
32763409
Jim_FreeNewObj(interp, listObj);
32773410
return JIM_ERR;
32783411
}
32793412
32803413
if (Jim_IsShared(objPtr))
32813414
objPtr = Jim_DuplicateObj(interp, objPtr);
32823415
3283
-
3416
+
32843417
Jim_ListAppendList(interp, objPtr, listObj);
32853418
Jim_DictSize(interp, objPtr);
32863419
Jim_InvalidateStringRep(objPtr);
32873420
32883421
Jim_FreeNewObj(interp, listObj);
@@ -3289,11 +3422,11 @@
32893422
listObj = objPtr;
32903423
}
32913424
Jim_SetVariable(interp, varName, listObj);
32923425
}
32933426
3294
-
3427
+
32953428
Jim_SetResult(interp, listObj);
32963429
32973430
return JIM_OK;
32983431
}
32993432
@@ -3309,11 +3442,11 @@
33093442
}
33103443
else if (p == path) {
33113444
Jim_SetResultString(interp, "/", -1);
33123445
}
33133446
else if (ISWINDOWS && p[-1] == ':') {
3314
-
3447
+
33153448
Jim_SetResultString(interp, path, p - path + 1);
33163449
}
33173450
else {
33183451
Jim_SetResultString(interp, path, p - path);
33193452
}
@@ -3389,35 +3522,35 @@
33893522
char *newname = Jim_Alloc(MAXPATHLEN + 1);
33903523
char *last = newname;
33913524
33923525
*newname = 0;
33933526
3394
-
3527
+
33953528
for (i = 0; i < argc; i++) {
33963529
int len;
33973530
const char *part = Jim_GetString(argv[i], &len);
33983531
33993532
if (*part == '/') {
3400
-
3533
+
34013534
last = newname;
34023535
}
34033536
else if (ISWINDOWS && strchr(part, ':')) {
3404
-
3537
+
34053538
last = newname;
34063539
}
34073540
else if (part[0] == '.') {
34083541
if (part[1] == '/') {
34093542
part += 2;
34103543
len -= 2;
34113544
}
34123545
else if (part[1] == 0 && last != newname) {
3413
-
3546
+
34143547
continue;
34153548
}
34163549
}
34173550
3418
-
3551
+
34193552
if (last != newname && last[-1] != '/') {
34203553
*last++ = '/';
34213554
}
34223555
34233556
if (len) {
@@ -3428,22 +3561,22 @@
34283561
}
34293562
memcpy(last, part, len);
34303563
last += len;
34313564
}
34323565
3433
-
3566
+
34343567
if (last > newname + 1 && last[-1] == '/') {
3435
-
3568
+
34363569
if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
34373570
*--last = 0;
34383571
}
34393572
}
34403573
}
34413574
34423575
*last = 0;
34433576
3444
-
3577
+
34453578
34463579
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
34473580
34483581
return JIM_OK;
34493582
}
@@ -3468,11 +3601,11 @@
34683601
static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
34693602
{
34703603
#ifdef X_OK
34713604
return file_access(interp, argv[0], X_OK);
34723605
#else
3473
-
3606
+
34743607
Jim_SetResultBool(interp, 1);
34753608
return JIM_OK;
34763609
#endif
34773610
}
34783611
@@ -3493,11 +3626,11 @@
34933626
while (argc--) {
34943627
const char *path = Jim_String(argv[0]);
34953628
34963629
if (unlink(path) == -1 && errno != ENOENT) {
34973630
if (rmdir(path) == -1) {
3498
-
3631
+
34993632
if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
35003633
Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
35013634
strerror(errno));
35023635
return JIM_ERR;
35033636
}
@@ -3516,15 +3649,15 @@
35163649
35173650
static int mkdir_all(char *path)
35183651
{
35193652
int ok = 1;
35203653
3521
-
3654
+
35223655
goto first;
35233656
35243657
while (ok--) {
3525
-
3658
+
35263659
{
35273660
char *slash = strrchr(path, '/');
35283661
35293662
if (slash && slash != path) {
35303663
*slash = 0;
@@ -3537,24 +3670,24 @@
35373670
first:
35383671
if (MKDIR_DEFAULT(path) == 0) {
35393672
return 0;
35403673
}
35413674
if (errno == ENOENT) {
3542
-
3675
+
35433676
continue;
35443677
}
3545
-
3678
+
35463679
if (errno == EEXIST) {
35473680
struct stat sb;
35483681
35493682
if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
35503683
return 0;
35513684
}
3552
-
3685
+
35533686
errno = EEXIST;
35543687
}
3555
-
3688
+
35563689
break;
35573690
}
35583691
return -1;
35593692
}
35603693
@@ -3839,192 +3972,192 @@
38393972
{ "atime",
38403973
"name",
38413974
file_cmd_atime,
38423975
1,
38433976
1,
3844
-
3977
+
38453978
},
38463979
{ "mtime",
38473980
"name ?time?",
38483981
file_cmd_mtime,
38493982
1,
38503983
2,
3851
-
3984
+
38523985
},
38533986
{ "copy",
38543987
"?-force? source dest",
38553988
file_cmd_copy,
38563989
2,
38573990
3,
3858
-
3991
+
38593992
},
38603993
{ "dirname",
38613994
"name",
38623995
file_cmd_dirname,
38633996
1,
38643997
1,
3865
-
3998
+
38663999
},
38674000
{ "rootname",
38684001
"name",
38694002
file_cmd_rootname,
38704003
1,
38714004
1,
3872
-
4005
+
38734006
},
38744007
{ "extension",
38754008
"name",
38764009
file_cmd_extension,
38774010
1,
38784011
1,
3879
-
4012
+
38804013
},
38814014
{ "tail",
38824015
"name",
38834016
file_cmd_tail,
38844017
1,
38854018
1,
3886
-
4019
+
38874020
},
38884021
{ "normalize",
38894022
"name",
38904023
file_cmd_normalize,
38914024
1,
38924025
1,
3893
-
4026
+
38944027
},
38954028
{ "join",
38964029
"name ?name ...?",
38974030
file_cmd_join,
38984031
1,
38994032
-1,
3900
-
4033
+
39014034
},
39024035
{ "readable",
39034036
"name",
39044037
file_cmd_readable,
39054038
1,
39064039
1,
3907
-
4040
+
39084041
},
39094042
{ "writable",
39104043
"name",
39114044
file_cmd_writable,
39124045
1,
39134046
1,
3914
-
4047
+
39154048
},
39164049
{ "executable",
39174050
"name",
39184051
file_cmd_executable,
39194052
1,
39204053
1,
3921
-
4054
+
39224055
},
39234056
{ "exists",
39244057
"name",
39254058
file_cmd_exists,
39264059
1,
39274060
1,
3928
-
4061
+
39294062
},
39304063
{ "delete",
39314064
"?-force|--? name ...",
39324065
file_cmd_delete,
39334066
1,
39344067
-1,
3935
-
4068
+
39364069
},
39374070
{ "mkdir",
39384071
"dir ...",
39394072
file_cmd_mkdir,
39404073
1,
39414074
-1,
3942
-
4075
+
39434076
},
39444077
{ "tempfile",
39454078
"?template?",
39464079
file_cmd_tempfile,
39474080
0,
39484081
1,
3949
-
4082
+
39504083
},
39514084
{ "rename",
39524085
"?-force? source dest",
39534086
file_cmd_rename,
39544087
2,
39554088
3,
3956
-
4089
+
39574090
},
39584091
#if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
39594092
{ "link",
39604093
"?-symbolic|-hard? newname target",
39614094
file_cmd_link,
39624095
2,
39634096
3,
3964
-
4097
+
39654098
},
39664099
#endif
39674100
#if defined(HAVE_READLINK)
39684101
{ "readlink",
39694102
"name",
39704103
file_cmd_readlink,
39714104
1,
39724105
1,
3973
-
4106
+
39744107
},
39754108
#endif
39764109
{ "size",
39774110
"name",
39784111
file_cmd_size,
39794112
1,
39804113
1,
3981
-
4114
+
39824115
},
39834116
{ "stat",
39844117
"name ?var?",
39854118
file_cmd_stat,
39864119
1,
39874120
2,
3988
-
4121
+
39894122
},
39904123
{ "lstat",
39914124
"name ?var?",
39924125
file_cmd_lstat,
39934126
1,
39944127
2,
3995
-
4128
+
39964129
},
39974130
{ "type",
39984131
"name",
39994132
file_cmd_type,
40004133
1,
40014134
1,
4002
-
4135
+
40034136
},
40044137
#ifdef HAVE_GETEUID
40054138
{ "owned",
40064139
"name",
40074140
file_cmd_owned,
40084141
1,
40094142
1,
4010
-
4143
+
40114144
},
40124145
#endif
40134146
{ "isdirectory",
40144147
"name",
40154148
file_cmd_isdirectory,
40164149
1,
40174150
1,
4018
-
4151
+
40194152
},
40204153
{ "isfile",
40214154
"name",
40224155
file_cmd_isfile,
40234156
1,
40244157
1,
4025
-
4158
+
40264159
},
40274160
{
40284161
NULL
40294162
}
40304163
};
@@ -4056,11 +4189,11 @@
40564189
Jim_SetResultString(interp, "Failed to get pwd", -1);
40574190
Jim_Free(cwd);
40584191
return JIM_ERR;
40594192
}
40604193
else if (ISWINDOWS) {
4061
-
4194
+
40624195
char *p = cwd;
40634196
while ((p = strchr(p, '\\')) != NULL) {
40644197
*p++ = '/';
40654198
}
40664199
}
@@ -4080,10 +4213,11 @@
40804213
Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
40814214
Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
40824215
return JIM_OK;
40834216
}
40844217
4218
+#define _GNU_SOURCE
40854219
#include <string.h>
40864220
#include <ctype.h>
40874221
40884222
40894223
#if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4091,20 +4225,20 @@
40914225
{
40924226
Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
40934227
int i, j;
40944228
int rc;
40954229
4096
-
4230
+
40974231
for (i = 1; i < argc; i++) {
40984232
int len;
40994233
const char *arg = Jim_GetString(argv[i], &len);
41004234
41014235
if (i > 1) {
41024236
Jim_AppendString(interp, cmdlineObj, " ", 1);
41034237
}
41044238
if (strpbrk(arg, "\\\" ") == NULL) {
4105
-
4239
+
41064240
Jim_AppendString(interp, cmdlineObj, arg, len);
41074241
continue;
41084242
}
41094243
41104244
Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4145,11 +4279,11 @@
41454279
41464280
#include <errno.h>
41474281
#include <signal.h>
41484282
41494283
#if defined(__MINGW32__)
4150
-
4284
+
41514285
#ifndef STRICT
41524286
#define STRICT
41534287
#endif
41544288
#define WIN32_LEAN_AND_MEAN
41554289
#include <windows.h>
@@ -4205,11 +4339,11 @@
42054339
static char **JimSaveEnv(char **env);
42064340
static void JimRestoreEnv(char **env);
42074341
static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv,
42084342
pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr);
42094343
static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr);
4210
-static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId);
4344
+static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj);
42114345
static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len);
42124346
static fdtype JimOpenForWrite(const char *filename, int append);
42134347
static int JimRewindFd(fdtype fd);
42144348
42154349
static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
@@ -4235,26 +4369,28 @@
42354369
42364370
static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj)
42374371
{
42384372
char buf[256];
42394373
FILE *fh = JimFdOpenForRead(fd);
4374
+ int ret = 0;
4375
+
42404376
if (fh == NULL) {
4241
- return JIM_ERR;
4377
+ return -1;
42424378
}
42434379
42444380
while (1) {
42454381
int retval = fread(buf, 1, sizeof(buf), fh);
42464382
if (retval > 0) {
4383
+ ret = 1;
42474384
Jim_AppendString(interp, strObj, buf, retval);
42484385
}
42494386
if (retval != sizeof(buf)) {
42504387
break;
42514388
}
42524389
}
4253
- Jim_RemoveTrailingNewline(strObj);
42544390
fclose(fh);
4255
- return JIM_OK;
4391
+ return ret;
42564392
}
42574393
42584394
static char **JimBuildEnv(Jim_Interp *interp)
42594395
{
42604396
int i;
@@ -4269,14 +4405,14 @@
42694405
if (!objPtr) {
42704406
return Jim_GetEnviron();
42714407
}
42724408
42734409
4274
-
4410
+
42754411
num = Jim_ListLength(interp, objPtr);
42764412
if (num % 2) {
4277
-
4413
+
42784414
num--;
42794415
}
42804416
size = Jim_Length(objPtr) + 2;
42814417
42824418
envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4308,25 +4444,38 @@
43084444
if (env != original_environ) {
43094445
Jim_Free(env);
43104446
}
43114447
}
43124448
4313
-static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus)
4449
+#ifndef jim_ext_signal
4450
+
4451
+const char *Jim_SignalId(int sig)
43144452
{
4315
- Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0);
4316
- int rc = JIM_ERR;
4453
+ static char buf[10];
4454
+ snprintf(buf, sizeof(buf), "%d", sig);
4455
+ return buf;
4456
+}
4457
+
4458
+const char *Jim_SignalName(int sig)
4459
+{
4460
+ return Jim_SignalId(sig);
4461
+}
4462
+#endif
4463
+
4464
+static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj)
4465
+{
4466
+ Jim_Obj *errorCode;
4467
+
4468
+ if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) {
4469
+ return JIM_OK;
4470
+ }
4471
+ errorCode = Jim_NewListObj(interp, NULL, 0);
43174472
43184473
if (WIFEXITED(waitStatus)) {
4319
- if (WEXITSTATUS(waitStatus) == 0) {
4320
- Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1));
4321
- rc = JIM_OK;
4322
- }
4323
- else {
4324
- Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
4325
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4326
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
4327
- }
4474
+ Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
4475
+ Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4476
+ Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
43284477
}
43294478
else {
43304479
const char *type;
43314480
const char *action;
43324481
@@ -4339,38 +4488,35 @@
43394488
action = "suspended";
43404489
}
43414490
43424491
Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));
43434492
4344
-#ifdef jim_ext_signal
4345
- Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus)));
4493
+ if (errStrObj) {
4494
+ Jim_AppendStrings(interp, errStrObj, "child ", action, " by signal ", Jim_SignalId(WTERMSIG(waitStatus)), "\n", NULL);
4495
+ }
4496
+
4497
+ Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
43464498
Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
4347
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid));
43484499
Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
4349
-#else
4350
- Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus));
4351
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
4352
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4353
- Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
4354
-#endif
43554500
}
43564501
Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
4357
- return rc;
4502
+
4503
+ return JIM_ERR;
43584504
}
43594505
43604506
43614507
struct WaitInfo
43624508
{
4363
- pidtype pid;
4364
- int status;
4365
- int flags;
4509
+ pidtype pid;
4510
+ int status;
4511
+ int flags;
43664512
};
43674513
43684514
struct WaitInfoTable {
4369
- struct WaitInfo *info;
4370
- int size;
4371
- int used;
4515
+ struct WaitInfo *info;
4516
+ int size;
4517
+ int used;
43724518
};
43734519
43744520
43754521
#define WI_DETACHED 2
43764522
@@ -4393,14 +4539,17 @@
43934539
return table;
43944540
}
43954541
43964542
static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
43974543
{
4398
- fdtype outputId;
4399
- fdtype errorId;
4544
+ fdtype outputId;
4545
+ fdtype errorId;
44004546
pidtype *pidPtr;
44014547
int numPids, result;
4548
+ int child_siginfo = 1;
4549
+ Jim_Obj *childErrObj;
4550
+ Jim_Obj *errStrObj;
44024551
44034552
if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) {
44044553
Jim_Obj *listObj;
44054554
int i;
44064555
@@ -4407,11 +4556,11 @@
44074556
argc--;
44084557
numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
44094558
if (numPids < 0) {
44104559
return JIM_ERR;
44114560
}
4412
-
4561
+
44134562
listObj = Jim_NewListObj(interp, NULL, 0);
44144563
for (i = 0; i < numPids; i++) {
44154564
Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
44164565
}
44174566
Jim_SetResult(interp, listObj);
@@ -4425,23 +4574,56 @@
44254574
44264575
if (numPids < 0) {
44274576
return JIM_ERR;
44284577
}
44294578
4430
- Jim_SetResultString(interp, "", 0);
4431
-
44324579
result = JIM_OK;
4580
+
4581
+ errStrObj = Jim_NewStringObj(interp, "", 0);
4582
+
4583
+
44334584
if (outputId != JIM_BAD_FD) {
4434
- result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp));
4435
- if (result < 0) {
4585
+ if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) {
4586
+ result = JIM_ERR;
44364587
Jim_SetResultErrno(interp, "error reading from output pipe");
44374588
}
44384589
}
44394590
4440
- if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) {
4591
+
4592
+ childErrObj = Jim_NewStringObj(interp, "", 0);
4593
+ Jim_IncrRefCount(childErrObj);
4594
+
4595
+ if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) {
44414596
result = JIM_ERR;
44424597
}
4598
+
4599
+ if (errorId != JIM_BAD_FD) {
4600
+ int ret;
4601
+ JimRewindFd(errorId);
4602
+ ret = JimAppendStreamToString(interp, errorId, errStrObj);
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
+
44434625
return result;
44444626
}
44454627
44464628
static void JimReapDetachedPids(struct WaitInfoTable *table)
44474629
{
@@ -4458,11 +4640,11 @@
44584640
for (count = table->used; count > 0; waitPtr++, count--) {
44594641
if (waitPtr->flags & WI_DETACHED) {
44604642
int status;
44614643
pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
44624644
if (pid == waitPtr->pid) {
4463
-
4645
+
44644646
table->used--;
44654647
continue;
44664648
}
44674649
}
44684650
if (waitPtr != &table->info[dest]) {
@@ -4474,36 +4656,36 @@
44744656
44754657
static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
44764658
{
44774659
int i;
44784660
4479
-
4661
+
44804662
for (i = 0; i < table->used; i++) {
44814663
if (pid == table->info[i].pid) {
4482
-
4664
+
44834665
JimWaitPid(pid, statusPtr, 0);
44844666
4485
-
4667
+
44864668
if (i != table->used - 1) {
44874669
table->info[i] = table->info[table->used - 1];
44884670
}
44894671
table->used--;
44904672
return pid;
44914673
}
44924674
}
44934675
4494
-
4676
+
44954677
return JIM_BAD_PID;
44964678
}
44974679
44984680
static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
44994681
{
45004682
int j;
45014683
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
45024684
45034685
for (j = 0; j < numPids; j++) {
4504
-
4686
+
45054687
int i;
45064688
for (i = 0; i < table->used; i++) {
45074689
if (pidPtr[j] == table->info[i].pid) {
45084690
table->info[i].flags |= WI_DETACHED;
45094691
break;
@@ -4536,16 +4718,16 @@
45364718
int cmdCount; /* Count of number of distinct commands
45374719
* found in argc/argv. */
45384720
const char *input = NULL; /* Describes input for pipeline, depending
45394721
* on "inputFile". NULL means take input
45404722
* from stdin/pipe. */
4541
- int input_len = 0;
4723
+ int input_len = 0;
45424724
4543
-#define FILE_NAME 0
4544
-#define FILE_APPEND 1
4545
-#define FILE_HANDLE 2
4546
-#define FILE_TEXT 3
4725
+#define FILE_NAME 0
4726
+#define FILE_APPEND 1
4727
+#define FILE_HANDLE 2
4728
+#define FILE_TEXT 3
45474729
45484730
int inputFile = FILE_NAME; /* 1 means input is name of input file.
45494731
* 2 means input is filehandle name.
45504732
* 0 means input holds actual
45514733
* text to be input to command. */
@@ -4566,20 +4748,20 @@
45664748
* or NULL if stderr goes to stderr/pipe. */
45674749
fdtype inputId = JIM_BAD_FD;
45684750
fdtype outputId = JIM_BAD_FD;
45694751
fdtype errorId = JIM_BAD_FD;
45704752
fdtype lastOutputId = JIM_BAD_FD;
4571
- fdtype pipeIds[2];
4753
+ fdtype pipeIds[2];
45724754
int firstArg, lastArg; /* Indexes of first and last arguments in
45734755
* current command. */
45744756
int lastBar;
45754757
int i;
45764758
pidtype pid;
45774759
char **save_environ;
45784760
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
45794761
4580
-
4762
+
45814763
char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
45824764
int arg_count = 0;
45834765
45844766
JimReapDetachedPids(table);
45854767
@@ -4625,11 +4807,11 @@
46254807
if (*output == '>') {
46264808
outputFile = FILE_APPEND;
46274809
output++;
46284810
}
46294811
if (*output == '&') {
4630
-
4812
+
46314813
output++;
46324814
dup_error = 1;
46334815
}
46344816
if (*output == '@') {
46354817
outputFile = FILE_HANDLE;
@@ -4666,11 +4848,11 @@
46664848
goto badargs;
46674849
}
46684850
lastBar = i;
46694851
cmdCount++;
46704852
}
4671
-
4853
+
46724854
arg_array[arg_count++] = (char *)arg;
46734855
continue;
46744856
}
46754857
46764858
if (i >= argc) {
@@ -4684,11 +4866,11 @@
46844866
badargs:
46854867
Jim_Free(arg_array);
46864868
return -1;
46874869
}
46884870
4689
-
4871
+
46904872
save_environ = JimSaveEnv(JimBuildEnv(interp));
46914873
46924874
if (input != NULL) {
46934875
if (inputFile == FILE_TEXT) {
46944876
inputId = JimCreateTemp(interp, input, input_len);
@@ -4695,11 +4877,11 @@
46954877
if (inputId == JIM_BAD_FD) {
46964878
goto error;
46974879
}
46984880
}
46994881
else if (inputFile == FILE_HANDLE) {
4700
-
4882
+
47014883
FILE *fh = JimGetAioFilehandle(interp, input);
47024884
47034885
if (fh == NULL) {
47044886
goto error;
47054887
}
@@ -4747,20 +4929,20 @@
47474929
}
47484930
lastOutputId = pipeIds[1];
47494931
*outPipePtr = pipeIds[0];
47504932
pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
47514933
}
4752
-
4934
+
47534935
if (error != NULL) {
47544936
if (errorFile == FILE_HANDLE) {
47554937
if (strcmp(error, "1") == 0) {
4756
-
4938
+
47574939
if (lastOutputId != JIM_BAD_FD) {
47584940
errorId = JimDupFd(lastOutputId);
47594941
}
47604942
else {
4761
-
4943
+
47624944
error = "stdout";
47634945
}
47644946
}
47654947
if (errorId == JIM_BAD_FD) {
47664948
FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4802,11 +4984,11 @@
48024984
pipe_dup_err = 1;
48034985
}
48044986
break;
48054987
}
48064988
}
4807
-
4989
+
48084990
arg_array[lastArg] = NULL;
48094991
if (lastArg == arg_count) {
48104992
outputId = lastOutputId;
48114993
}
48124994
else {
@@ -4815,16 +4997,16 @@
48154997
goto error;
48164998
}
48174999
outputId = pipeIds[1];
48185000
}
48195001
4820
-
5002
+
48215003
if (pipe_dup_err) {
48225004
errorId = outputId;
48235005
}
48245006
4825
-
5007
+
48265008
48275009
#ifdef __MINGW32__
48285010
pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
48295011
if (pid == JIM_BAD_PID) {
48305012
Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -4835,32 +5017,32 @@
48355017
if (pid < 0) {
48365018
Jim_SetResultErrno(interp, "couldn't fork child process");
48375019
goto error;
48385020
}
48395021
if (pid == 0) {
4840
-
5022
+
48415023
48425024
if (inputId != -1) dup2(inputId, 0);
48435025
if (outputId != -1) dup2(outputId, 1);
48445026
if (errorId != -1) dup2(errorId, 2);
48455027
48465028
for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
48475029
close(i);
48485030
}
48495031
4850
-
5032
+
48515033
(void)signal(SIGPIPE, SIG_DFL);
48525034
48535035
execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
48545036
4855
-
5037
+
48565038
fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
48575039
_exit(127);
48585040
}
48595041
#endif
48605042
4861
-
5043
+
48625044
48635045
if (table->used == table->size) {
48645046
table->size += WAIT_TABLE_GROW_BY;
48655047
table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
48665048
}
@@ -4869,11 +5051,11 @@
48695051
table->info[table->used].flags = 0;
48705052
table->used++;
48715053
48725054
pidPtr[numPids] = pid;
48735055
4874
-
5056
+
48755057
errorId = origErrorId;
48765058
48775059
48785060
if (inputId != JIM_BAD_FD) {
48795061
JimCloseFd(inputId);
@@ -4934,35 +5116,27 @@
49345116
numPids = -1;
49355117
goto cleanup;
49365118
}
49375119
49385120
4939
-static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId)
5121
+static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj)
49405122
{
49415123
struct WaitInfoTable *table = Jim_CmdPrivData(interp);
49425124
int result = JIM_OK;
49435125
int i;
5126
+
49445127
49455128
for (i = 0; i < numPids; i++) {
49465129
int waitStatus = 0;
49475130
if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
4948
- if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus) != JIM_OK) {
5131
+ if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) {
49495132
result = JIM_ERR;
49505133
}
49515134
}
49525135
}
49535136
Jim_Free(pidPtr);
49545137
4955
- if (errorId != JIM_BAD_FD) {
4956
- JimRewindFd(errorId);
4957
- if (JimAppendStreamToString(interp, errorId, Jim_GetResult(interp)) != JIM_OK) {
4958
- result = JIM_ERR;
4959
- }
4960
- }
4961
-
4962
- Jim_RemoveTrailingNewline(Jim_GetResult(interp));
4963
-
49645138
return result;
49655139
}
49665140
49675141
int Jim_execInit(Jim_Interp *interp)
49685142
{
@@ -5121,17 +5295,21 @@
51215295
}
51225296
51235297
static fdtype JimOpenForRead(const char *filename)
51245298
{
51255299
return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
5126
- JimStdSecAttrs(), OPEN_EXISTING, 0, NULL);
5300
+ JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
51275301
}
51285302
51295303
static fdtype JimOpenForWrite(const char *filename, int append)
51305304
{
5131
- return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5132
- JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL);
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;
51335311
}
51345312
51355313
static FILE *JimFdOpenForWrite(fdtype fd)
51365314
{
51375315
return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5139,11 +5317,11 @@
51395317
51405318
static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
51415319
{
51425320
DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
51435321
if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
5144
-
5322
+
51455323
return JIM_BAD_PID;
51465324
}
51475325
GetExitCodeProcess(pid, &ret);
51485326
*status = ret;
51495327
CloseHandle(pid);
@@ -5166,11 +5344,11 @@
51665344
if (handle == INVALID_HANDLE_VALUE) {
51675345
goto error;
51685346
}
51695347
51705348
if (contents != NULL) {
5171
-
5349
+
51725350
FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
51735351
if (fh == NULL) {
51745352
goto error;
51755353
}
51765354
@@ -5195,12 +5373,11 @@
51955373
{
51965374
int i;
51975375
static char extensions[][5] = {".exe", "", ".bat"};
51985376
51995377
for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
5200
- lstrcpyn(fullPath, originalName, MAX_PATH - 5);
5201
- lstrcat(fullPath, extensions[i]);
5378
+ snprintf(fullPath, MAX_PATH, "%s%s", originalName, extensions[i]);
52025379
52035380
if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) {
52045381
continue;
52055382
}
52065383
if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) {
@@ -5439,11 +5616,11 @@
54395616
#include <sys/time.h>
54405617
#endif
54415618
54425619
static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
54435620
{
5444
-
5621
+
54455622
char buf[100];
54465623
time_t t;
54475624
long seconds;
54485625
54495626
const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5480,20 +5657,20 @@
54805657
54815658
if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
54825659
return -1;
54835660
}
54845661
5485
-
5662
+
54865663
localtime_r(&now, &tm);
54875664
54885665
pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
54895666
if (pt == 0 || *pt != 0) {
54905667
Jim_SetResultString(interp, "Failed to parse time according to format", -1);
54915668
return JIM_ERR;
54925669
}
54935670
5494
-
5671
+
54955672
Jim_SetResultInt(interp, mktime(&tm));
54965673
54975674
return JIM_OK;
54985675
}
54995676
#endif
@@ -5531,47 +5708,47 @@
55315708
{ "seconds",
55325709
NULL,
55335710
clock_cmd_seconds,
55345711
0,
55355712
0,
5536
-
5713
+
55375714
},
55385715
{ "clicks",
55395716
NULL,
55405717
clock_cmd_micros,
55415718
0,
55425719
0,
5543
-
5720
+
55445721
},
55455722
{ "microseconds",
55465723
NULL,
55475724
clock_cmd_micros,
55485725
0,
55495726
0,
5550
-
5727
+
55515728
},
55525729
{ "milliseconds",
55535730
NULL,
55545731
clock_cmd_millis,
55555732
0,
55565733
0,
5557
-
5734
+
55585735
},
55595736
{ "format",
55605737
"seconds ?-format format?",
55615738
clock_cmd_format,
55625739
1,
55635740
3,
5564
-
5741
+
55655742
},
55665743
#ifdef HAVE_STRPTIME
55675744
{ "scan",
55685745
"str -format format",
55695746
clock_cmd_scan,
55705747
3,
55715748
3,
5572
-
5749
+
55735750
},
55745751
#endif
55755752
{ NULL }
55765753
};
55775754
@@ -5591,11 +5768,11 @@
55915768
#include <errno.h>
55925769
55935770
55945771
static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
55955772
{
5596
-
5773
+
55975774
Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
55985775
return JIM_OK;
55995776
}
56005777
56015778
static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5607,20 +5784,20 @@
56075784
return JIM_OK;
56085785
}
56095786
56105787
patternObj = (argc == 1) ? NULL : argv[1];
56115788
5612
-
5789
+
56135790
if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
56145791
if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
5615
-
5792
+
56165793
Jim_SetResult(interp, objPtr);
56175794
return JIM_OK;
56185795
}
56195796
}
56205797
5621
-
5798
+
56225799
return Jim_DictValues(interp, objPtr, patternObj);
56235800
}
56245801
56255802
static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
56265803
{
@@ -5640,27 +5817,27 @@
56405817
Jim_Obj *resultObj;
56415818
Jim_Obj *objPtr;
56425819
Jim_Obj **dictValuesObj;
56435820
56445821
if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
5645
-
5822
+
56465823
Jim_UnsetVariable(interp, argv[0], JIM_NONE);
56475824
return JIM_OK;
56485825
}
56495826
56505827
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
56515828
56525829
if (objPtr == NULL) {
5653
-
5830
+
56545831
return JIM_OK;
56555832
}
56565833
56575834
if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
56585835
return JIM_ERR;
56595836
}
56605837
5661
-
5838
+
56625839
resultObj = Jim_NewDictObj(interp, NULL, 0);
56635840
56645841
for (i = 0; i < len; i += 2) {
56655842
if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
56665843
Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5675,11 +5852,11 @@
56755852
static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
56765853
{
56775854
Jim_Obj *objPtr;
56785855
int len = 0;
56795856
5680
-
5857
+
56815858
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
56825859
if (objPtr) {
56835860
len = Jim_DictSize(interp, objPtr);
56845861
if (len < 0) {
56855862
return JIM_ERR;
@@ -5714,11 +5891,11 @@
57145891
return JIM_ERR;
57155892
}
57165893
57175894
dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
57185895
if (!dictObj) {
5719
-
5896
+
57205897
return Jim_SetVariable(interp, argv[0], listObj);
57215898
}
57225899
else if (Jim_DictSize(interp, dictObj) < 0) {
57235900
return JIM_ERR;
57245901
}
@@ -5743,53 +5920,53 @@
57435920
{ "exists",
57445921
"arrayName",
57455922
array_cmd_exists,
57465923
1,
57475924
1,
5748
-
5925
+
57495926
},
57505927
{ "get",
57515928
"arrayName ?pattern?",
57525929
array_cmd_get,
57535930
1,
57545931
2,
5755
-
5932
+
57565933
},
57575934
{ "names",
57585935
"arrayName ?pattern?",
57595936
array_cmd_names,
57605937
1,
57615938
2,
5762
-
5939
+
57635940
},
57645941
{ "set",
57655942
"arrayName list",
57665943
array_cmd_set,
57675944
2,
57685945
2,
5769
-
5946
+
57705947
},
57715948
{ "size",
57725949
"arrayName",
57735950
array_cmd_size,
57745951
1,
57755952
1,
5776
-
5953
+
57775954
},
57785955
{ "stat",
57795956
"arrayName",
57805957
array_cmd_stat,
57815958
1,
57825959
1,
5783
-
5960
+
57845961
},
57855962
{ "unset",
57865963
"arrayName ?pattern?",
57875964
array_cmd_unset,
57885965
1,
57895966
2,
5790
-
5967
+
57915968
},
57925969
{ NULL
57935970
}
57945971
};
57955972
@@ -5804,32 +5981,33 @@
58045981
int Jim_InitStaticExtensions(Jim_Interp *interp)
58055982
{
58065983
extern int Jim_bootstrapInit(Jim_Interp *);
58075984
extern int Jim_aioInit(Jim_Interp *);
58085985
extern int Jim_readdirInit(Jim_Interp *);
5809
-extern int Jim_globInit(Jim_Interp *);
58105986
extern int Jim_regexpInit(Jim_Interp *);
58115987
extern int Jim_fileInit(Jim_Interp *);
5988
+extern int Jim_globInit(Jim_Interp *);
58125989
extern int Jim_execInit(Jim_Interp *);
58135990
extern int Jim_clockInit(Jim_Interp *);
58145991
extern int Jim_arrayInit(Jim_Interp *);
58155992
extern int Jim_stdlibInit(Jim_Interp *);
58165993
extern int Jim_tclcompatInit(Jim_Interp *);
58175994
Jim_bootstrapInit(interp);
58185995
Jim_aioInit(interp);
58195996
Jim_readdirInit(interp);
5820
-Jim_globInit(interp);
58215997
Jim_regexpInit(interp);
58225998
Jim_fileInit(interp);
5999
+Jim_globInit(interp);
58236000
Jim_execInit(interp);
58246001
Jim_clockInit(interp);
58256002
Jim_arrayInit(interp);
58266003
Jim_stdlibInit(interp);
58276004
Jim_tclcompatInit(interp);
58286005
return JIM_OK;
58296006
}
5830
-#define JIM_OPTIMIZATION
6007
+#define JIM_OPTIMIZATION
6008
+#define _GNU_SOURCE
58316009
58326010
#include <stdio.h>
58336011
#include <stdlib.h>
58346012
58356013
#include <string.h>
@@ -5894,10 +6072,16 @@
58946072
#define JimPanic(X) JimPanicDump X
58956073
#else
58966074
#define JimPanic(X)
58976075
#endif
58986076
6077
+#ifdef JIM_OPTIMIZATION
6078
+#define JIM_IF_OPTIM(X) X
6079
+#else
6080
+#define JIM_IF_OPTIM(X)
6081
+#endif
6082
+
58996083
59006084
static char JimEmptyStringRep[] = "";
59016085
59026086
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
59036087
static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -5950,34 +6134,34 @@
59506134
if (*pattern == '^') {
59516135
not++;
59526136
pattern++;
59536137
}
59546138
5955
-
6139
+
59566140
if (*pattern == ']') {
59576141
goto first;
59586142
}
59596143
}
59606144
59616145
while (*pattern && *pattern != ']') {
5962
-
6146
+
59636147
if (pattern[0] == '\\') {
59646148
first:
59656149
pattern += utf8_tounicode_case(pattern, &pchar, nocase);
59666150
}
59676151
else {
5968
-
6152
+
59696153
int start;
59706154
int end;
59716155
59726156
pattern += utf8_tounicode_case(pattern, &start, nocase);
59736157
if (pattern[0] == '-' && pattern[1]) {
5974
-
6158
+
59756159
pattern += utf8_tounicode(pattern, &pchar);
59766160
pattern += utf8_tounicode_case(pattern, &end, nocase);
59776161
5978
-
6162
+
59796163
if ((c >= start && c <= end) || (c >= end && c <= start)) {
59806164
match = 1;
59816165
}
59826166
continue;
59836167
}
@@ -6007,19 +6191,19 @@
60076191
while (pattern[1] == '*') {
60086192
pattern++;
60096193
}
60106194
pattern++;
60116195
if (!pattern[0]) {
6012
- return 1;
6196
+ return 1;
60136197
}
60146198
while (*string) {
6015
-
6199
+
60166200
if (JimGlobMatch(pattern, string, nocase))
6017
- return 1;
6201
+ return 1;
60186202
string += utf8_tounicode(string, &c);
60196203
}
6020
- return 0;
6204
+ return 0;
60216205
60226206
case '?':
60236207
string += utf8_tounicode(string, &c);
60246208
break;
60256209
@@ -6028,20 +6212,20 @@
60286212
pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
60296213
if (!pattern) {
60306214
return 0;
60316215
}
60326216
if (!*pattern) {
6033
-
6217
+
60346218
continue;
60356219
}
60366220
break;
60376221
}
60386222
case '\\':
60396223
if (pattern[1]) {
60406224
pattern++;
60416225
}
6042
-
6226
+
60436227
default:
60446228
string += utf8_tounicode_case(string, &c, nocase);
60456229
utf8_tounicode_case(pattern, &pchar, nocase);
60466230
if (pchar != c) {
60476231
return 0;
@@ -6087,11 +6271,11 @@
60876271
maxchars--;
60886272
}
60896273
if (!maxchars) {
60906274
return 0;
60916275
}
6092
-
6276
+
60936277
if (*s1) {
60946278
return 1;
60956279
}
60966280
if (*s2) {
60976281
return -1;
@@ -6128,11 +6312,11 @@
61286312
const char *p;
61296313
61306314
if (!l1 || !l2 || l1 > l2)
61316315
return -1;
61326316
6133
-
6317
+
61346318
for (p = s2 + l2 - 1; p != s2 - 1; p--) {
61356319
if (*p == *s1 && memcmp(s1, p, l1) == 0) {
61366320
return p - s2;
61376321
}
61386322
}
@@ -6187,28 +6371,28 @@
61876371
}
61886372
*sign = 1;
61896373
}
61906374
61916375
if (str[i] != '0') {
6192
-
6376
+
61936377
return 0;
61946378
}
61956379
6196
-
6380
+
61976381
switch (str[i + 1]) {
61986382
case 'x': case 'X': *base = 16; break;
61996383
case 'o': case 'O': *base = 8; break;
62006384
case 'b': case 'B': *base = 2; break;
62016385
default: return 0;
62026386
}
62036387
i += 2;
6204
-
6388
+
62056389
if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
6206
-
6390
+
62076391
return i;
62086392
}
6209
-
6393
+
62106394
*base = 10;
62116395
return 0;
62126396
}
62136397
62146398
static long jim_strtol(const char *str, char **endptr)
@@ -6222,11 +6406,11 @@
62226406
if (endptr == NULL || *endptr != str + i) {
62236407
return value * sign;
62246408
}
62256409
}
62266410
6227
-
6411
+
62286412
return strtol(str, endptr, 10);
62296413
}
62306414
62316415
62326416
static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6241,11 +6425,11 @@
62416425
if (endptr == NULL || *endptr != str + i) {
62426426
return value * sign;
62436427
}
62446428
}
62456429
6246
-
6430
+
62476431
return strtoull(str, endptr, 10);
62486432
#else
62496433
return (unsigned long)jim_strtol(str, endptr);
62506434
#endif
62516435
}
@@ -6266,26 +6450,40 @@
62666450
62676451
int Jim_StringToDouble(const char *str, double *doublePtr)
62686452
{
62696453
char *endptr;
62706454
6271
-
6455
+
62726456
errno = 0;
62736457
62746458
*doublePtr = strtod(str, &endptr);
62756459
62766460
return JimCheckConversion(str, endptr);
62776461
}
62786462
62796463
static jim_wide JimPowWide(jim_wide b, jim_wide e)
62806464
{
6281
- jim_wide i, res = 1;
6465
+ jim_wide res = 1;
62826466
6283
- if ((b == 0 && e != 0) || (e < 0))
6284
- return 0;
6285
- for (i = 0; i < e; i++) {
6286
- res *= b;
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;
62876485
}
62886486
return res;
62896487
}
62906488
62916489
#ifdef JIM_DEBUG_PANIC
@@ -6347,11 +6545,11 @@
63476545
char *Jim_StrDupLen(const char *s, int l)
63486546
{
63496547
char *copy = Jim_Alloc(l + 1);
63506548
63516549
memcpy(copy, s, l + 1);
6352
- copy[l] = 0;
6550
+ copy[l] = 0;
63536551
return copy;
63546552
}
63556553
63566554
63576555
@@ -6436,52 +6634,52 @@
64366634
}
64376635
64386636
64396637
void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
64406638
{
6441
- Jim_HashTable n;
6639
+ Jim_HashTable n;
64426640
unsigned int realsize = JimHashTableNextPower(size), i;
64436641
64446642
if (size <= ht->used)
64456643
return;
64466644
64476645
Jim_InitHashTable(&n, ht->type, ht->privdata);
64486646
n.size = realsize;
64496647
n.sizemask = realsize - 1;
64506648
n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
6451
-
6649
+
64526650
n.uniq = ht->uniq;
64536651
6454
-
6652
+
64556653
memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
64566654
64576655
n.used = ht->used;
64586656
for (i = 0; ht->used > 0; i++) {
64596657
Jim_HashEntry *he, *nextHe;
64606658
64616659
if (ht->table[i] == NULL)
64626660
continue;
64636661
6464
-
6662
+
64656663
he = ht->table[i];
64666664
while (he) {
64676665
unsigned int h;
64686666
64696667
nextHe = he->next;
6470
-
6668
+
64716669
h = Jim_HashKey(ht, he->key) & n.sizemask;
64726670
he->next = n.table[h];
64736671
n.table[h] = he;
64746672
ht->used--;
6475
-
6673
+
64766674
he = nextHe;
64776675
}
64786676
}
64796677
assert(ht->used == 0);
64806678
Jim_Free(ht->table);
64816679
6482
-
6680
+
64836681
*ht = n;
64846682
}
64856683
64866684
64876685
int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6490,11 +6688,11 @@
64906688
64916689
entry = JimInsertHashEntry(ht, key, 0);
64926690
if (entry == NULL)
64936691
return JIM_ERR;
64946692
6495
-
6693
+
64966694
Jim_SetHashKey(ht, entry, key);
64976695
Jim_SetHashVal(ht, entry, val);
64986696
return JIM_OK;
64996697
}
65006698
@@ -6516,11 +6714,11 @@
65166714
Jim_SetHashVal(ht, entry, val);
65176715
}
65186716
existed = 1;
65196717
}
65206718
else {
6521
-
6719
+
65226720
Jim_SetHashKey(ht, entry, key);
65236721
Jim_SetHashVal(ht, entry, val);
65246722
existed = 0;
65256723
}
65266724
@@ -6539,11 +6737,11 @@
65396737
he = ht->table[h];
65406738
65416739
prevHe = NULL;
65426740
while (he) {
65436741
if (Jim_CompareHashKeys(ht, key, he->key)) {
6544
-
6742
+
65456743
if (prevHe)
65466744
prevHe->next = he->next;
65476745
else
65486746
ht->table[h] = he->next;
65496747
Jim_FreeEntryKey(ht, he);
@@ -6553,19 +6751,19 @@
65536751
return JIM_OK;
65546752
}
65556753
prevHe = he;
65566754
he = he->next;
65576755
}
6558
- return JIM_ERR;
6756
+ return JIM_ERR;
65596757
}
65606758
65616759
65626760
int Jim_FreeHashTable(Jim_HashTable *ht)
65636761
{
65646762
unsigned int i;
65656763
6566
-
6764
+
65676765
for (i = 0; ht->used > 0; i++) {
65686766
Jim_HashEntry *he, *nextHe;
65696767
65706768
if ((he = ht->table[i]) == NULL)
65716769
continue;
@@ -6576,15 +6774,15 @@
65766774
Jim_Free(he);
65776775
ht->used--;
65786776
he = nextHe;
65796777
}
65806778
}
6581
-
6779
+
65826780
Jim_Free(ht->table);
6583
-
6781
+
65846782
JimResetHashTable(ht);
6585
- return JIM_OK;
6783
+ return JIM_OK;
65866784
}
65876785
65886786
Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
65896787
{
65906788
Jim_HashEntry *he;
@@ -6657,24 +6855,24 @@
66576855
static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
66586856
{
66596857
unsigned int h;
66606858
Jim_HashEntry *he;
66616859
6662
-
6860
+
66636861
JimExpandHashTableIfNeeded(ht);
66646862
6665
-
6863
+
66666864
h = Jim_HashKey(ht, key) & ht->sizemask;
6667
-
6865
+
66686866
he = ht->table[h];
66696867
while (he) {
66706868
if (Jim_CompareHashKeys(ht, key, he->key))
66716869
return replace ? he : NULL;
66726870
he = he->next;
66736871
}
66746872
6675
-
6873
+
66766874
he = Jim_Alloc(sizeof(*he));
66776875
he->next = ht->table[h];
66786876
ht->table[h] = he;
66796877
ht->used++;
66806878
he->key = NULL;
@@ -6703,16 +6901,16 @@
67036901
{
67046902
Jim_Free(key);
67056903
}
67066904
67076905
static const Jim_HashTableType JimPackageHashTableType = {
6708
- JimStringCopyHTHashFunction,
6709
- JimStringCopyHTDup,
6710
- NULL,
6711
- JimStringCopyHTKeyCompare,
6712
- JimStringCopyHTKeyDestructor,
6713
- NULL
6906
+ JimStringCopyHTHashFunction,
6907
+ JimStringCopyHTDup,
6908
+ NULL,
6909
+ JimStringCopyHTKeyCompare,
6910
+ JimStringCopyHTKeyDestructor,
6911
+ NULL
67146912
};
67156913
67166914
typedef struct AssocDataValue
67176915
{
67186916
Jim_InterpDeleteProc *delProc;
@@ -6727,16 +6925,16 @@
67276925
assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
67286926
Jim_Free(data);
67296927
}
67306928
67316929
static const Jim_HashTableType JimAssocDataHashTableType = {
6732
- JimStringCopyHTHashFunction,
6733
- JimStringCopyHTDup,
6734
- NULL,
6735
- JimStringCopyHTKeyCompare,
6736
- JimStringCopyHTKeyDestructor,
6737
- JimAssocDataHashTableValueDestructor
6930
+ JimStringCopyHTHashFunction,
6931
+ JimStringCopyHTDup,
6932
+ NULL,
6933
+ JimStringCopyHTKeyCompare,
6934
+ JimStringCopyHTKeyDestructor,
6935
+ JimAssocDataHashTableValueDestructor
67386936
};
67396937
67406938
void Jim_InitStack(Jim_Stack *stack)
67416939
{
67426940
stack->len = 0;
@@ -6789,61 +6987,61 @@
67896987
freeFunc(stack->vector[i]);
67906988
}
67916989
67926990
67936991
6794
-#define JIM_TT_NONE 0
6795
-#define JIM_TT_STR 1
6796
-#define JIM_TT_ESC 2
6797
-#define JIM_TT_VAR 3
6798
-#define JIM_TT_DICTSUGAR 4
6799
-#define JIM_TT_CMD 5
6800
-
6801
-#define JIM_TT_SEP 6
6802
-#define JIM_TT_EOL 7
6803
-#define JIM_TT_EOF 8
6804
-
6805
-#define JIM_TT_LINE 9
6806
-#define JIM_TT_WORD 10
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
68077005
68087006
68097007
#define JIM_TT_SUBEXPR_START 11
68107008
#define JIM_TT_SUBEXPR_END 12
68117009
#define JIM_TT_SUBEXPR_COMMA 13
68127010
#define JIM_TT_EXPR_INT 14
68137011
#define JIM_TT_EXPR_DOUBLE 15
7012
+#define JIM_TT_EXPR_BOOLEAN 16
68147013
6815
-#define JIM_TT_EXPRSUGAR 16
7014
+#define JIM_TT_EXPRSUGAR 17
68167015
68177016
68187017
#define JIM_TT_EXPR_OP 20
68197018
68207019
#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
68217020
7021
+#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA)
68227022
6823
-#define JIM_PS_DEF 0
6824
-#define JIM_PS_QUOTE 1
6825
-#define JIM_PS_DICTSUGAR 2
7023
+#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP)
68267024
68277025
struct JimParseMissing {
6828
- int ch;
6829
- int line;
7026
+ int ch;
7027
+ int line;
68307028
};
68317029
68327030
struct JimParserCtx
68337031
{
6834
- const char *p;
6835
- int len;
6836
- int linenr;
7032
+ const char *p;
7033
+ int len;
7034
+ int linenr;
68377035
const char *tstart;
6838
- const char *tend;
6839
- int tline;
6840
- int tt;
6841
- int eof;
6842
- int state;
6843
- int comment;
6844
- struct JimParseMissing missing;
7036
+ const char *tend;
7037
+ int tline;
7038
+ int tt;
7039
+ int eof;
7040
+ int inquote;
7041
+ int comment;
7042
+ struct JimParseMissing missing;
68457043
};
68467044
68477045
static int JimParseScript(struct JimParserCtx *pc);
68487046
static int JimParseSep(struct JimParserCtx *pc);
68497047
static int JimParseEol(struct JimParserCtx *pc);
@@ -6864,20 +7062,20 @@
68647062
pc->tstart = NULL;
68657063
pc->tend = NULL;
68667064
pc->tline = 0;
68677065
pc->tt = JIM_TT_NONE;
68687066
pc->eof = 0;
6869
- pc->state = JIM_PS_DEF;
7067
+ pc->inquote = 0;
68707068
pc->linenr = linenr;
68717069
pc->comment = 1;
68727070
pc->missing.ch = ' ';
68737071
pc->missing.line = linenr;
68747072
}
68757073
68767074
static int JimParseScript(struct JimParserCtx *pc)
68777075
{
6878
- while (1) {
7076
+ while (1) {
68797077
if (!pc->len) {
68807078
pc->tstart = pc->p;
68817079
pc->tend = pc->p - 1;
68827080
pc->tline = pc->linenr;
68837081
pc->tt = JIM_TT_EOL;
@@ -6884,36 +7082,36 @@
68847082
pc->eof = 1;
68857083
return JIM_OK;
68867084
}
68877085
switch (*(pc->p)) {
68887086
case '\\':
6889
- if (*(pc->p + 1) == '\n' && pc->state == JIM_PS_DEF) {
7087
+ if (*(pc->p + 1) == '\n' && !pc->inquote) {
68907088
return JimParseSep(pc);
68917089
}
68927090
pc->comment = 0;
68937091
return JimParseStr(pc);
68947092
case ' ':
68957093
case '\t':
68967094
case '\r':
68977095
case '\f':
6898
- if (pc->state == JIM_PS_DEF)
7096
+ if (!pc->inquote)
68997097
return JimParseSep(pc);
69007098
pc->comment = 0;
69017099
return JimParseStr(pc);
69027100
case '\n':
69037101
case ';':
69047102
pc->comment = 1;
6905
- if (pc->state == JIM_PS_DEF)
7103
+ if (!pc->inquote)
69067104
return JimParseEol(pc);
69077105
return JimParseStr(pc);
69087106
case '[':
69097107
pc->comment = 0;
69107108
return JimParseCmd(pc);
69117109
case '$':
69127110
pc->comment = 0;
69137111
if (JimParseVar(pc) == JIM_ERR) {
6914
-
7112
+
69157113
pc->tstart = pc->tend = pc->p++;
69167114
pc->len--;
69177115
pc->tt = JIM_TT_ESC;
69187116
}
69197117
return JIM_OK;
@@ -6970,11 +7168,11 @@
69707168
69717169
static void JimParseSubBrace(struct JimParserCtx *pc)
69727170
{
69737171
int level = 1;
69747172
6975
-
7173
+
69767174
pc->p++;
69777175
pc->len--;
69787176
while (pc->len) {
69797177
switch (*pc->p) {
69807178
case '\\':
@@ -7014,11 +7212,11 @@
70147212
static int JimParseSubQuote(struct JimParserCtx *pc)
70157213
{
70167214
int tt = JIM_TT_STR;
70177215
int line = pc->tline;
70187216
7019
-
7217
+
70207218
pc->p++;
70217219
pc->len--;
70227220
while (pc->len) {
70237221
switch (*pc->p) {
70247222
case '\\':
@@ -7063,11 +7261,11 @@
70637261
{
70647262
int level = 1;
70657263
int startofword = 1;
70667264
int line = pc->tline;
70677265
7068
-
7266
+
70697267
pc->p++;
70707268
pc->len--;
70717269
while (pc->len) {
70727270
switch (*pc->p) {
70737271
case '\\':
@@ -7143,17 +7341,17 @@
71437341
return JIM_OK;
71447342
}
71457343
71467344
static int JimParseVar(struct JimParserCtx *pc)
71477345
{
7148
-
7346
+
71497347
pc->p++;
71507348
pc->len--;
71517349
71527350
#ifdef EXPRSUGAR_BRACKET
71537351
if (*pc->p == '[') {
7154
-
7352
+
71557353
JimParseCmd(pc);
71567354
pc->tt = JIM_TT_EXPRSUGAR;
71577355
return JIM_OK;
71587356
}
71597357
#endif
@@ -7179,11 +7377,11 @@
71797377
pc->len--;
71807378
}
71817379
}
71827380
else {
71837381
while (1) {
7184
-
7382
+
71857383
if (pc->p[0] == ':' && pc->p[1] == ':') {
71867384
while (*pc->p == ':') {
71877385
pc->p++;
71887386
pc->len--;
71897387
}
@@ -7194,11 +7392,11 @@
71947392
pc->len--;
71957393
continue;
71967394
}
71977395
break;
71987396
}
7199
-
7397
+
72007398
if (*pc->p == '(') {
72017399
int count = 1;
72027400
const char *paren = NULL;
72037401
72047402
pc->tt = JIM_TT_DICTSUGAR;
@@ -7221,11 +7419,11 @@
72217419
if (count == 0) {
72227420
pc->p++;
72237421
pc->len--;
72247422
}
72257423
else if (paren) {
7226
-
7424
+
72277425
paren++;
72287426
pc->len += (pc->p - paren);
72297427
pc->p = paren;
72307428
}
72317429
#ifndef EXPRSUGAR_BRACKET
@@ -7246,36 +7444,36 @@
72467444
72477445
static int JimParseStr(struct JimParserCtx *pc)
72487446
{
72497447
if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
72507448
pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
7251
-
7449
+
72527450
if (*pc->p == '{') {
72537451
return JimParseBrace(pc);
72547452
}
72557453
if (*pc->p == '"') {
7256
- pc->state = JIM_PS_QUOTE;
7454
+ pc->inquote = 1;
72577455
pc->p++;
72587456
pc->len--;
7259
-
7457
+
72607458
pc->missing.line = pc->tline;
72617459
}
72627460
}
72637461
pc->tstart = pc->p;
72647462
pc->tline = pc->linenr;
72657463
while (1) {
72667464
if (pc->len == 0) {
7267
- if (pc->state == JIM_PS_QUOTE) {
7465
+ if (pc->inquote) {
72687466
pc->missing.ch = '"';
72697467
}
72707468
pc->tend = pc->p - 1;
72717469
pc->tt = JIM_TT_ESC;
72727470
return JIM_OK;
72737471
}
72747472
switch (*pc->p) {
72757473
case '\\':
7276
- if (pc->state == JIM_PS_DEF && *(pc->p + 1) == '\n') {
7474
+ if (!pc->inquote && *(pc->p + 1) == '\n') {
72777475
pc->tend = pc->p - 1;
72787476
pc->tt = JIM_TT_ESC;
72797477
return JIM_OK;
72807478
}
72817479
if (pc->len >= 2) {
@@ -7284,24 +7482,25 @@
72847482
}
72857483
pc->p++;
72867484
pc->len--;
72877485
}
72887486
else if (pc->len == 1) {
7289
-
7487
+
72907488
pc->missing.ch = '\\';
72917489
}
72927490
break;
72937491
case '(':
7294
-
7492
+
72957493
if (pc->len > 1 && pc->p[1] != '$') {
72967494
break;
72977495
}
7496
+
72987497
case ')':
7299
-
7498
+
73007499
if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
73017500
if (pc->p == pc->tstart) {
7302
-
7501
+
73037502
pc->p++;
73047503
pc->len--;
73057504
}
73067505
pc->tend = pc->p - 1;
73077506
pc->tt = JIM_TT_ESC;
@@ -7318,34 +7517,34 @@
73187517
case '\t':
73197518
case '\n':
73207519
case '\r':
73217520
case '\f':
73227521
case ';':
7323
- if (pc->state == JIM_PS_DEF) {
7522
+ if (!pc->inquote) {
73247523
pc->tend = pc->p - 1;
73257524
pc->tt = JIM_TT_ESC;
73267525
return JIM_OK;
73277526
}
73287527
else if (*pc->p == '\n') {
73297528
pc->linenr++;
73307529
}
73317530
break;
73327531
case '"':
7333
- if (pc->state == JIM_PS_QUOTE) {
7532
+ if (pc->inquote) {
73347533
pc->tend = pc->p - 1;
73357534
pc->tt = JIM_TT_ESC;
73367535
pc->p++;
73377536
pc->len--;
7338
- pc->state = JIM_PS_DEF;
7537
+ pc->inquote = 0;
73397538
return JIM_OK;
73407539
}
73417540
break;
73427541
}
73437542
pc->p++;
73447543
pc->len--;
73457544
}
7346
- return JIM_OK;
7545
+ return JIM_OK;
73477546
}
73487547
73497548
static int JimParseComment(struct JimParserCtx *pc)
73507549
{
73517550
while (*pc->p) {
@@ -7394,13 +7593,10 @@
73947593
static int JimEscape(char *dest, const char *s, int slen)
73957594
{
73967595
char *p = dest;
73977596
int i, len;
73987597
7399
- if (slen == -1)
7400
- slen = strlen(s);
7401
-
74027598
for (i = 0; i < slen; i++) {
74037599
switch (s[i]) {
74047600
case '\\':
74057601
switch (s[i + 1]) {
74067602
case 'a':
@@ -7455,34 +7651,34 @@
74557651
if (c == -1) {
74567652
break;
74577653
}
74587654
val = (val << 4) | c;
74597655
}
7460
-
7656
+
74617657
if (s[i] == '{') {
74627658
if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
7463
-
7659
+
74647660
i--;
74657661
k = 0;
74667662
}
74677663
else {
7468
-
7664
+
74697665
k++;
74707666
}
74717667
}
74727668
if (k) {
7473
-
7669
+
74747670
if (s[i] == 'x') {
74757671
*p++ = val;
74767672
}
74777673
else {
74787674
p += utf8_fromunicode(p, val);
74797675
}
74807676
i += k;
74817677
break;
74827678
}
7483
-
7679
+
74847680
*p++ = s[i];
74857681
}
74867682
break;
74877683
case 'v':
74887684
*p++ = 0xb;
@@ -7491,11 +7687,11 @@
74917687
case '\0':
74927688
*p++ = '\\';
74937689
i++;
74947690
break;
74957691
case '\n':
7496
-
7692
+
74977693
*p++ = ' ';
74987694
do {
74997695
i++;
75007696
} while (s[i + 1] == ' ' || s[i + 1] == '\t');
75017697
break;
@@ -7505,11 +7701,11 @@
75057701
case '3':
75067702
case '4':
75077703
case '5':
75087704
case '6':
75097705
case '7':
7510
-
7706
+
75117707
{
75127708
int val = 0;
75137709
int c = odigitval(s[i + 1]);
75147710
75157711
val = c;
@@ -7562,37 +7758,23 @@
75627758
}
75637759
else {
75647760
len = (end - start) + 1;
75657761
token = Jim_Alloc(len + 1);
75667762
if (pc->tt != JIM_TT_ESC) {
7567
-
7763
+
75687764
memcpy(token, start, len);
75697765
token[len] = '\0';
75707766
}
75717767
else {
7572
-
7768
+
75737769
len = JimEscape(token, start, len);
75747770
}
75757771
}
75767772
75777773
return Jim_NewStringObjNoAlloc(interp, token, len);
75787774
}
75797775
7580
-int Jim_ScriptIsComplete(const char *s, int len, char *stateCharPtr)
7581
-{
7582
- struct JimParserCtx parser;
7583
-
7584
- JimParserInit(&parser, s, len, 1);
7585
- while (!parser.eof) {
7586
- JimParseScript(&parser);
7587
- }
7588
- if (stateCharPtr) {
7589
- *stateCharPtr = parser.missing.ch;
7590
- }
7591
- return parser.missing.ch == ' ';
7592
-}
7593
-
75947776
static int JimParseListSep(struct JimParserCtx *pc);
75957777
static int JimParseListStr(struct JimParserCtx *pc);
75967778
static int JimParseListQuote(struct JimParserCtx *pc);
75977779
75987780
static int JimParseList(struct JimParserCtx *pc)
@@ -7649,11 +7831,11 @@
76497831
while (pc->len) {
76507832
switch (*pc->p) {
76517833
case '\\':
76527834
pc->tt = JIM_TT_ESC;
76537835
if (--pc->len == 0) {
7654
-
7836
+
76557837
pc->tend = pc->p;
76567838
return JIM_OK;
76577839
}
76587840
pc->p++;
76597841
break;
@@ -7685,11 +7867,11 @@
76857867
pc->tend = pc->p - 1;
76867868
return JIM_OK;
76877869
}
76887870
if (*pc->p == '\\') {
76897871
if (--pc->len == 0) {
7690
-
7872
+
76917873
pc->tend = pc->p;
76927874
return JIM_OK;
76937875
}
76947876
pc->tt = JIM_TT_ESC;
76957877
pc->p++;
@@ -7705,24 +7887,24 @@
77057887
77067888
Jim_Obj *Jim_NewObj(Jim_Interp *interp)
77077889
{
77087890
Jim_Obj *objPtr;
77097891
7710
-
7892
+
77117893
if (interp->freeList != NULL) {
7712
-
7894
+
77137895
objPtr = interp->freeList;
77147896
interp->freeList = objPtr->nextObjPtr;
77157897
}
77167898
else {
7717
-
7899
+
77187900
objPtr = Jim_Alloc(sizeof(*objPtr));
77197901
}
77207902
77217903
objPtr->refCount = 0;
77227904
7723
-
7905
+
77247906
objPtr->prevObjPtr = NULL;
77257907
objPtr->nextObjPtr = interp->liveList;
77267908
if (interp->liveList)
77277909
interp->liveList->prevObjPtr = objPtr;
77287910
interp->liveList = objPtr;
@@ -7730,32 +7912,32 @@
77307912
return objPtr;
77317913
}
77327914
77337915
void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
77347916
{
7735
-
7917
+
77367918
JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
77377919
objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>"));
77387920
7739
-
7921
+
77407922
Jim_FreeIntRep(interp, objPtr);
7741
-
7923
+
77427924
if (objPtr->bytes != NULL) {
77437925
if (objPtr->bytes != JimEmptyStringRep)
77447926
Jim_Free(objPtr->bytes);
77457927
}
7746
-
7928
+
77477929
if (objPtr->prevObjPtr)
77487930
objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
77497931
if (objPtr->nextObjPtr)
77507932
objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
77517933
if (interp->liveList == objPtr)
77527934
interp->liveList = objPtr->nextObjPtr;
77537935
#ifdef JIM_DISABLE_OBJECT_POOL
77547936
Jim_Free(objPtr);
77557937
#else
7756
-
7938
+
77577939
objPtr->prevObjPtr = NULL;
77587940
objPtr->nextObjPtr = interp->freeList;
77597941
if (interp->freeList)
77607942
interp->freeList->prevObjPtr = objPtr;
77617943
interp->freeList = objPtr;
@@ -7778,45 +7960,45 @@
77787960
{
77797961
Jim_Obj *dupPtr;
77807962
77817963
dupPtr = Jim_NewObj(interp);
77827964
if (objPtr->bytes == NULL) {
7783
-
7965
+
77847966
dupPtr->bytes = NULL;
77857967
}
77867968
else if (objPtr->length == 0) {
7787
-
7969
+
77887970
dupPtr->bytes = JimEmptyStringRep;
77897971
dupPtr->length = 0;
77907972
dupPtr->typePtr = NULL;
77917973
return dupPtr;
77927974
}
77937975
else {
77947976
dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
77957977
dupPtr->length = objPtr->length;
7796
-
7978
+
77977979
memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
77987980
}
77997981
7800
-
7982
+
78017983
dupPtr->typePtr = objPtr->typePtr;
78027984
if (objPtr->typePtr != NULL) {
78037985
if (objPtr->typePtr->dupIntRepProc == NULL) {
78047986
dupPtr->internalRep = objPtr->internalRep;
78057987
}
78067988
else {
7807
-
7989
+
78087990
objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
78097991
}
78107992
}
78117993
return dupPtr;
78127994
}
78137995
78147996
const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
78157997
{
78167998
if (objPtr->bytes == NULL) {
7817
-
7999
+
78188000
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
78198001
objPtr->typePtr->updateStringProc(objPtr);
78208002
}
78218003
if (lenPtr)
78228004
*lenPtr = objPtr->length;
@@ -7825,11 +8007,11 @@
78258007
78268008
78278009
int Jim_Length(Jim_Obj *objPtr)
78288010
{
78298011
if (objPtr->bytes == NULL) {
7830
-
8012
+
78318013
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
78328014
objPtr->typePtr->updateStringProc(objPtr);
78338015
}
78348016
return objPtr->length;
78358017
}
@@ -7836,11 +8018,11 @@
78368018
78378019
78388020
const char *Jim_String(Jim_Obj *objPtr)
78398021
{
78408022
if (objPtr->bytes == NULL) {
7841
-
8023
+
78428024
JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
78438025
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
78448026
objPtr->typePtr->updateStringProc(objPtr);
78458027
}
78468028
return objPtr->bytes;
@@ -7896,22 +8078,22 @@
78968078
}
78978079
78988080
static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
78998081
{
79008082
if (objPtr->typePtr != &stringObjType) {
7901
-
8083
+
79028084
if (objPtr->bytes == NULL) {
7903
-
8085
+
79048086
JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
79058087
objPtr->typePtr->updateStringProc(objPtr);
79068088
}
7907
-
8089
+
79088090
Jim_FreeIntRep(interp, objPtr);
7909
-
8091
+
79108092
objPtr->typePtr = &stringObjType;
79118093
objPtr->internalRep.strValue.maxLength = objPtr->length;
7912
-
8094
+
79138095
objPtr->internalRep.strValue.charLength = -1;
79148096
}
79158097
return JIM_OK;
79168098
}
79178099
@@ -7932,14 +8114,14 @@
79328114
79338115
Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
79348116
{
79358117
Jim_Obj *objPtr = Jim_NewObj(interp);
79368118
7937
-
8119
+
79388120
if (len == -1)
79398121
len = strlen(s);
7940
-
8122
+
79418123
if (len == 0) {
79428124
objPtr->bytes = JimEmptyStringRep;
79438125
}
79448126
else {
79458127
objPtr->bytes = Jim_Alloc(len + 1);
@@ -7946,25 +8128,25 @@
79468128
memcpy(objPtr->bytes, s, len);
79478129
objPtr->bytes[len] = '\0';
79488130
}
79498131
objPtr->length = len;
79508132
7951
-
8133
+
79528134
objPtr->typePtr = NULL;
79538135
return objPtr;
79548136
}
79558137
79568138
79578139
Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
79588140
{
79598141
#ifdef JIM_UTF8
7960
-
8142
+
79618143
int bytelen = utf8_index(s, charlen);
79628144
79638145
Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
79648146
7965
-
8147
+
79668148
objPtr->typePtr = &stringObjType;
79678149
objPtr->internalRep.strValue.maxLength = bytelen;
79688150
objPtr->internalRep.strValue.charLength = charlen;
79698151
79708152
return objPtr;
@@ -7991,11 +8173,11 @@
79918173
len = strlen(str);
79928174
needlen = objPtr->length + len;
79938175
if (objPtr->internalRep.strValue.maxLength < needlen ||
79948176
objPtr->internalRep.strValue.maxLength == 0) {
79958177
needlen *= 2;
7996
-
8178
+
79978179
if (needlen < 7) {
79988180
needlen = 7;
79998181
}
80008182
if (objPtr->bytes == JimEmptyStringRep) {
80018183
objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8007,11 +8189,11 @@
80078189
}
80088190
memcpy(objPtr->bytes + objPtr->length, str, len);
80098191
objPtr->bytes[objPtr->length + len] = '\0';
80108192
80118193
if (objPtr->internalRep.strValue.charLength >= 0) {
8012
-
8194
+
80138195
objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
80148196
}
80158197
objPtr->length += len;
80168198
}
80178199
@@ -8069,11 +8251,11 @@
80698251
int l1, l2;
80708252
const char *s1 = Jim_GetString(firstObjPtr, &l1);
80718253
const char *s2 = Jim_GetString(secondObjPtr, &l2);
80728254
80738255
if (nocase) {
8074
-
8256
+
80758257
return JimStringCompareLen(s1, s2, -1, nocase);
80768258
}
80778259
return JimStringCompare(s1, l1, s2, l2);
80788260
}
80798261
@@ -8171,11 +8353,11 @@
81718353
81728354
if (first == 0 && rangeLen == len) {
81738355
return strObjPtr;
81748356
}
81758357
if (len == bytelen) {
8176
-
8358
+
81778359
return Jim_NewStringObj(interp, str + first, rangeLen);
81788360
}
81798361
return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
81808362
#else
81818363
return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8200,19 +8382,19 @@
82008382
return strObjPtr;
82018383
}
82028384
82038385
str = Jim_String(strObjPtr);
82048386
8205
-
8387
+
82068388
objPtr = Jim_NewStringObjUtf8(interp, str, first);
82078389
8208
-
8390
+
82098391
if (newStrObj) {
82108392
Jim_AppendObj(interp, objPtr, newStrObj);
82118393
}
82128394
8213
-
8395
+
82148396
Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
82158397
82168398
return objPtr;
82178399
}
82188400
@@ -8311,11 +8493,11 @@
83118493
while (len) {
83128494
int c;
83138495
int n = utf8_tounicode(str, &c);
83148496
83158497
if (utf8_memchr(trimchars, trimlen, c) == NULL) {
8316
-
8498
+
83178499
break;
83188500
}
83198501
str += n;
83208502
len -= n;
83218503
}
@@ -8382,41 +8564,41 @@
83828564
83838565
len = Jim_Length(strObjPtr);
83848566
nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
83858567
83868568
if (nontrim == NULL) {
8387
-
8569
+
83888570
return Jim_NewEmptyStringObj(interp);
83898571
}
83908572
if (nontrim == strObjPtr->bytes + len) {
8391
-
8573
+
83928574
return strObjPtr;
83938575
}
83948576
83958577
if (Jim_IsShared(strObjPtr)) {
83968578
strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
83978579
}
83988580
else {
8399
-
8581
+
84008582
strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
84018583
strObjPtr->length = (nontrim - strObjPtr->bytes);
84028584
}
84038585
84048586
return strObjPtr;
84058587
}
84068588
84078589
static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
84088590
{
8409
-
8591
+
84108592
Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
84118593
8412
-
8594
+
84138595
strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
84148596
8415
-
8597
+
84168598
if (objPtr != strObjPtr && objPtr->refCount == 0) {
8417
-
8599
+
84188600
Jim_FreeNewObj(interp, objPtr);
84198601
}
84208602
84218603
return strObjPtr;
84228604
}
@@ -8434,17 +8616,17 @@
84348616
static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
84358617
{
84368618
static const char * const strclassnames[] = {
84378619
"integer", "alpha", "alnum", "ascii", "digit",
84388620
"double", "lower", "upper", "space", "xdigit",
8439
- "control", "print", "graph", "punct",
8621
+ "control", "print", "graph", "punct", "boolean",
84408622
NULL
84418623
};
84428624
enum {
84438625
STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
84448626
STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
8445
- STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
8627
+ STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN,
84468628
};
84478629
int strclass;
84488630
int len;
84498631
int i;
84508632
const char *str;
@@ -8472,10 +8654,17 @@
84728654
{
84738655
double d;
84748656
Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
84758657
return JIM_OK;
84768658
}
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
+ }
84778666
84788667
case STR_IS_ALPHA: isclassfunc = isalpha; break;
84798668
case STR_IS_ALNUM: isclassfunc = isalnum; break;
84808669
case STR_IS_ASCII: isclassfunc = jim_isascii; break;
84818670
case STR_IS_DIGIT: isclassfunc = isdigit; break;
@@ -8524,11 +8713,11 @@
85248713
85258714
if (objPtr->typePtr != &comparedStringObjType) {
85268715
Jim_FreeIntRep(interp, objPtr);
85278716
objPtr->typePtr = &comparedStringObjType;
85288717
}
8529
- objPtr->internalRep.ptr = (char *)str;
8718
+ objPtr->internalRep.ptr = (char *)str;
85308719
return 1;
85318720
}
85328721
}
85338722
85348723
static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8600,12 +8789,10 @@
86008789
return objPtr;
86018790
}
86028791
86038792
static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
86048793
static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
8605
-static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
8606
-static int JimParseCheckMissing(Jim_Interp *interp, int ch);
86078794
86088795
static const Jim_ObjType scriptObjType = {
86098796
"script",
86108797
FreeScriptInternalRep,
86118798
DupScriptInternalRep,
@@ -8619,21 +8806,25 @@
86198806
int type;
86208807
} ScriptToken;
86218808
86228809
typedef struct ScriptObj
86238810
{
8624
- ScriptToken *token;
8625
- Jim_Obj *fileNameObj;
8626
- int len;
8627
- int substFlags;
8811
+ ScriptToken *token;
8812
+ Jim_Obj *fileNameObj;
8813
+ int len;
8814
+ int substFlags;
86288815
int inUse; /* Used to share a ScriptObj. Currently
86298816
only used by Jim_EvalObj() as protection against
86308817
shimmering of the currently evaluated object. */
8631
- int firstline;
8632
- int linenr;
8633
- int missing;
8818
+ int firstline;
8819
+ int linenr;
8820
+ int missing;
86348821
} 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);
86358826
86368827
void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
86378828
{
86388829
int i;
86398830
struct ScriptObj *script = (void *)objPtr->internalRep.ptr;
@@ -8656,23 +8847,23 @@
86568847
dupPtr->typePtr = NULL;
86578848
}
86588849
86598850
typedef struct
86608851
{
8661
- const char *token;
8662
- int len;
8663
- int type;
8664
- int line;
8852
+ const char *token;
8853
+ int len;
8854
+ int type;
8855
+ int line;
86658856
} ParseToken;
86668857
86678858
typedef struct
86688859
{
8669
-
8670
- ParseToken *list;
8671
- int size;
8672
- int count;
8673
- ParseToken static_list[20];
8860
+
8861
+ ParseToken *list;
8862
+ int size;
8863
+ int count;
8864
+ ParseToken static_list[20];
86748865
} ParseTokenList;
86758866
86768867
static void ScriptTokenListInit(ParseTokenList *tokenlist)
86778868
{
86788869
tokenlist->list = tokenlist->static_list;
@@ -8691,18 +8882,18 @@
86918882
int line)
86928883
{
86938884
ParseToken *t;
86948885
86958886
if (tokenlist->count == tokenlist->size) {
8696
-
8887
+
86978888
tokenlist->size *= 2;
86988889
if (tokenlist->list != tokenlist->static_list) {
86998890
tokenlist->list =
87008891
Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
87018892
}
87028893
else {
8703
-
8894
+
87048895
tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
87058896
memcpy(tokenlist->list, tokenlist->static_list,
87068897
tokenlist->count * sizeof(*tokenlist->list));
87078898
}
87088899
}
@@ -8716,20 +8907,20 @@
87168907
static int JimCountWordTokens(ParseToken *t)
87178908
{
87188909
int expand = 1;
87198910
int count = 0;
87208911
8721
-
8912
+
87228913
if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
87238914
if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
8724
-
8915
+
87258916
expand = -1;
87268917
t++;
87278918
}
87288919
}
87298920
8730
-
8921
+
87318922
while (!TOKEN_IS_SEP(t->type)) {
87328923
t++;
87338924
count++;
87348925
}
87358926
@@ -8739,11 +8930,11 @@
87398930
static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
87408931
{
87418932
Jim_Obj *objPtr;
87428933
87438934
if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
8744
-
8935
+
87458936
int len = t->len;
87468937
char *str = Jim_Alloc(len + 1);
87478938
len = JimEscape(str, t->token, len);
87488939
objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
87498940
}
@@ -8756,13 +8947,13 @@
87568947
static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
87578948
ParseTokenList *tokenlist)
87588949
{
87598950
int i;
87608951
struct ScriptToken *token;
8761
-
8952
+
87628953
int lineargs = 0;
8763
-
8954
+
87648955
ScriptToken *linefirst;
87658956
int count;
87668957
int linenr;
87678958
87688959
#ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8771,11 +8962,11 @@
87718962
printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
87728963
tokenlist->list[i].len, tokenlist->list[i].token);
87738964
}
87748965
#endif
87758966
8776
-
8967
+
87778968
count = tokenlist->count;
87788969
for (i = 0; i < tokenlist->count; i++) {
87798970
if (tokenlist->list[i].type == JIM_TT_EOL) {
87808971
count++;
87818972
}
@@ -8782,59 +8973,59 @@
87828973
}
87838974
linenr = script->firstline = tokenlist->list[0].line;
87848975
87858976
token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
87868977
8787
-
8978
+
87888979
linefirst = token++;
87898980
87908981
for (i = 0; i < tokenlist->count; ) {
8791
-
8982
+
87928983
int wordtokens;
87938984
8794
-
8985
+
87958986
while (tokenlist->list[i].type == JIM_TT_SEP) {
87968987
i++;
87978988
}
87988989
87998990
wordtokens = JimCountWordTokens(tokenlist->list + i);
88008991
88018992
if (wordtokens == 0) {
8802
-
8993
+
88038994
if (lineargs) {
88048995
linefirst->type = JIM_TT_LINE;
88058996
linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
88068997
Jim_IncrRefCount(linefirst->objPtr);
88078998
8808
-
8999
+
88099000
lineargs = 0;
88109001
linefirst = token++;
88119002
}
88129003
i++;
88139004
continue;
88149005
}
88159006
else if (wordtokens != 1) {
8816
-
9007
+
88179008
token->type = JIM_TT_WORD;
88189009
token->objPtr = Jim_NewIntObj(interp, wordtokens);
88199010
Jim_IncrRefCount(token->objPtr);
88209011
token++;
88219012
if (wordtokens < 0) {
8822
-
9013
+
88239014
i++;
88249015
wordtokens = -wordtokens - 1;
88259016
lineargs--;
88269017
}
88279018
}
88289019
88299020
if (lineargs == 0) {
8830
-
9021
+
88319022
linenr = tokenlist->list[i].line;
88329023
}
88339024
lineargs++;
88349025
8835
-
9026
+
88369027
while (wordtokens--) {
88379028
const ParseToken *t = &tokenlist->list[i++];
88389029
88399030
token->type = t->type;
88409031
token->objPtr = JimMakeScriptObj(interp, t);
@@ -8860,10 +9051,19 @@
88609051
printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
88619052
}
88629053
#endif
88639054
88649055
}
9056
+
9057
+int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr)
9058
+{
9059
+ ScriptObj *script = JimGetScript(interp, scriptObj);
9060
+ if (stateCharPtr) {
9061
+ *stateCharPtr = script->missing;
9062
+ }
9063
+ return (script->missing == ' ');
9064
+}
88659065
88669066
static int JimParseCheckMissing(Jim_Interp *interp, int ch)
88679067
{
88689068
const char *msg;
88699069
@@ -8897,11 +9097,11 @@
88979097
token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
88989098
88999099
for (i = 0; i < tokenlist->count; i++) {
89009100
const ParseToken *t = &tokenlist->list[i];
89019101
8902
-
9102
+
89039103
token->type = t->type;
89049104
token->objPtr = JimMakeScriptObj(interp, t);
89059105
Jim_IncrRefCount(token->objPtr);
89069106
token++;
89079107
}
@@ -8916,29 +9116,29 @@
89169116
struct JimParserCtx parser;
89179117
struct ScriptObj *script;
89189118
ParseTokenList tokenlist;
89199119
int line = 1;
89209120
8921
-
9121
+
89229122
if (objPtr->typePtr == &sourceObjType) {
89239123
line = objPtr->internalRep.sourceValue.lineNumber;
89249124
}
89259125
8926
-
9126
+
89279127
ScriptTokenListInit(&tokenlist);
89289128
89299129
JimParserInit(&parser, scriptText, scriptTextLen, line);
89309130
while (!parser.eof) {
89319131
JimParseScript(&parser);
89329132
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
89339133
parser.tline);
89349134
}
89359135
8936
-
9136
+
89379137
ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
89389138
8939
-
9139
+
89409140
script = Jim_Alloc(sizeof(*script));
89419141
memset(script, 0, sizeof(*script));
89429142
script->inUse = 1;
89439143
if (objPtr->typePtr == &sourceObjType) {
89449144
script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -8950,25 +9150,25 @@
89509150
script->missing = parser.missing.ch;
89519151
script->linenr = parser.missing.line;
89529152
89539153
ScriptObjAddTokens(interp, script, &tokenlist);
89549154
8955
-
9155
+
89569156
ScriptTokenListFree(&tokenlist);
89579157
8958
-
9158
+
89599159
Jim_FreeIntRep(interp, objPtr);
89609160
Jim_SetIntRepPtr(objPtr, script);
89619161
objPtr->typePtr = &scriptObjType;
89629162
}
89639163
89649164
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
89659165
8966
-ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
9166
+static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
89679167
{
89689168
if (objPtr == interp->emptyObj) {
8969
-
9169
+
89709170
objPtr = interp->nullScriptObj;
89719171
}
89729172
89739173
if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
89749174
JimSetScriptFromAny(interp, objPtr);
@@ -9003,17 +9203,17 @@
90039203
Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
90049204
Jim_Free(cmdPtr->u.proc.staticVars);
90059205
}
90069206
}
90079207
else {
9008
-
9208
+
90099209
if (cmdPtr->u.native.delProc) {
90109210
cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
90119211
}
90129212
}
90139213
if (cmdPtr->prevCmd) {
9014
-
9214
+
90159215
JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
90169216
}
90179217
Jim_Free(cmdPtr);
90189218
}
90199219
}
@@ -9024,46 +9224,46 @@
90249224
Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
90259225
Jim_Free(val);
90269226
}
90279227
90289228
static const Jim_HashTableType JimVariablesHashTableType = {
9029
- JimStringCopyHTHashFunction,
9030
- JimStringCopyHTDup,
9031
- NULL,
9032
- JimStringCopyHTKeyCompare,
9033
- JimStringCopyHTKeyDestructor,
9034
- JimVariablesHTValDestructor
9229
+ JimStringCopyHTHashFunction,
9230
+ JimStringCopyHTDup,
9231
+ NULL,
9232
+ JimStringCopyHTKeyCompare,
9233
+ JimStringCopyHTKeyDestructor,
9234
+ JimVariablesHTValDestructor
90359235
};
90369236
90379237
static void JimCommandsHT_ValDestructor(void *interp, void *val)
90389238
{
90399239
JimDecrCmdRefCount(interp, val);
90409240
}
90419241
90429242
static const Jim_HashTableType JimCommandsHashTableType = {
9043
- JimStringCopyHTHashFunction,
9044
- JimStringCopyHTDup,
9045
- NULL,
9046
- JimStringCopyHTKeyCompare,
9047
- JimStringCopyHTKeyDestructor,
9048
- JimCommandsHT_ValDestructor
9243
+ JimStringCopyHTHashFunction,
9244
+ JimStringCopyHTDup,
9245
+ NULL,
9246
+ JimStringCopyHTKeyCompare,
9247
+ JimStringCopyHTKeyDestructor,
9248
+ JimCommandsHT_ValDestructor
90499249
};
90509250
90519251
90529252
90539253
#ifdef jim_ext_namespace
90549254
static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
90559255
{
90569256
const char *name = Jim_String(nsObj);
90579257
if (name[0] == ':' && name[1] == ':') {
9058
-
9258
+
90599259
while (*++name == ':') {
90609260
}
90619261
nsObj = Jim_NewStringObj(interp, name, -1);
90629262
}
90639263
else if (Jim_Length(interp->framePtr->nsObj)) {
9064
-
9264
+
90659265
nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
90669266
Jim_AppendStrings(interp, nsObj, "::", name, NULL);
90679267
}
90689268
return nsObj;
90699269
}
@@ -9087,16 +9287,16 @@
90879287
static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
90889288
{
90899289
Jim_Obj *objPtr = interp->emptyObj;
90909290
90919291
if (name[0] == ':' && name[1] == ':') {
9092
-
9292
+
90939293
while (*++name == ':') {
90949294
}
90959295
}
90969296
else if (Jim_Length(interp->framePtr->nsObj)) {
9097
-
9297
+
90989298
objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
90999299
Jim_AppendStrings(interp, objPtr, "::", name, NULL);
91009300
name = Jim_String(objPtr);
91019301
}
91029302
Jim_IncrRefCount(objPtr);
@@ -9105,11 +9305,11 @@
91059305
}
91069306
91079307
#define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
91089308
91099309
#else
9110
-
9310
+
91119311
#define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
91129312
#define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
91139313
91149314
Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
91159315
{
@@ -9124,17 +9324,17 @@
91249324
91259325
Jim_InterpIncrProcEpoch(interp);
91269326
}
91279327
91289328
if (he && interp->local) {
9129
-
9329
+
91309330
cmd->prevCmd = Jim_GetHashEntryVal(he);
91319331
Jim_SetHashVal(&interp->commands, he, cmd);
91329332
}
91339333
else {
91349334
if (he) {
9135
-
9335
+
91369336
Jim_DeleteHashEntry(&interp->commands, name);
91379337
}
91389338
91399339
Jim_AddHashEntry(&interp->commands, name, cmd);
91409340
}
@@ -9141,15 +9341,15 @@
91419341
return JIM_OK;
91429342
}
91439343
91449344
91459345
int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
9146
- Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc)
9346
+ Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
91479347
{
91489348
Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
91499349
9150
-
9350
+
91519351
memset(cmdPtr, 0, sizeof(*cmdPtr));
91529352
cmdPtr->inUse = 1;
91539353
cmdPtr->u.native.delProc = delProc;
91549354
cmdPtr->u.native.cmdProc = cmdProc;
91559355
cmdPtr->u.native.privData = privData;
@@ -9174,11 +9374,11 @@
91749374
Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
91759375
Jim_Var *varPtr;
91769376
int subLen;
91779377
91789378
objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
9179
-
9379
+
91809380
subLen = Jim_ListLength(interp, objPtr);
91819381
if (subLen == 1 || subLen == 2) {
91829382
nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
91839383
if (subLen == 1) {
91849384
initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9220,19 +9420,19 @@
92209420
92219421
static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
92229422
{
92239423
#ifdef jim_ext_namespace
92249424
if (cmdPtr->isproc) {
9225
-
9425
+
92269426
const char *pt = strrchr(cmdname, ':');
92279427
if (pt && pt != cmdname && pt[-1] == ':') {
92289428
Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
92299429
cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
92309430
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
92319431
92329432
if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
9233
-
9433
+
92349434
Jim_InterpIncrProcEpoch(interp);
92359435
}
92369436
}
92379437
}
92389438
#endif
@@ -9245,11 +9445,11 @@
92459445
int argListLen;
92469446
int i;
92479447
92489448
argListLen = Jim_ListLength(interp, argListObjPtr);
92499449
9250
-
9450
+
92519451
cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
92529452
memset(cmdPtr, 0, sizeof(*cmdPtr));
92539453
cmdPtr->inUse = 1;
92549454
cmdPtr->isproc = 1;
92559455
cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9260,24 +9460,24 @@
92609460
cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
92619461
Jim_IncrRefCount(argListObjPtr);
92629462
Jim_IncrRefCount(bodyObjPtr);
92639463
Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
92649464
9265
-
9465
+
92669466
if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
92679467
goto err;
92689468
}
92699469
9270
-
9271
-
9470
+
9471
+
92729472
for (i = 0; i < argListLen; i++) {
92739473
Jim_Obj *argPtr;
92749474
Jim_Obj *nameObjPtr;
92759475
Jim_Obj *defaultObjPtr;
92769476
int len;
92779477
9278
-
9478
+
92799479
argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
92809480
len = Jim_ListLength(interp, argPtr);
92819481
if (len == 0) {
92829482
Jim_SetResultString(interp, "argument with no name", -1);
92839483
err:
@@ -9288,16 +9488,16 @@
92889488
Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
92899489
goto err;
92909490
}
92919491
92929492
if (len == 2) {
9293
-
9493
+
92949494
nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
92959495
defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
92969496
}
92979497
else {
9298
-
9498
+
92999499
nameObjPtr = argPtr;
93009500
defaultObjPtr = NULL;
93019501
}
93029502
93039503
@@ -9358,29 +9558,29 @@
93589558
}
93599559
93609560
fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
93619561
fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
93629562
9363
-
9563
+
93649564
he = Jim_FindHashEntry(&interp->commands, fqold);
93659565
if (he == NULL) {
93669566
Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
93679567
}
93689568
else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
93699569
Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
93709570
}
93719571
else {
9372
-
9572
+
93739573
cmdPtr = Jim_GetHashEntryVal(he);
93749574
JimIncrCmdRefCount(cmdPtr);
93759575
JimUpdateProcNamespace(interp, cmdPtr, fqnew);
93769576
Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
93779577
9378
-
9578
+
93799579
Jim_DeleteHashEntry(&interp->commands, fqold);
93809580
9381
-
9581
+
93829582
Jim_InterpIncrProcEpoch(interp);
93839583
93849584
ret = JIM_OK;
93859585
}
93869586
@@ -9419,23 +9619,23 @@
94199619
objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
94209620
#ifdef jim_ext_namespace
94219621
|| !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
94229622
#endif
94239623
) {
9424
-
94259624
9426
-
9625
+
9626
+
94279627
const char *name = Jim_String(objPtr);
94289628
Jim_HashEntry *he;
94299629
94309630
if (name[0] == ':' && name[1] == ':') {
94319631
while (*++name == ':') {
94329632
}
94339633
}
94349634
#ifdef jim_ext_namespace
94359635
else if (Jim_Length(interp->framePtr->nsObj)) {
9436
-
9636
+
94379637
Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
94389638
Jim_AppendStrings(interp, nameObj, "::", name, NULL);
94399639
he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
94409640
Jim_FreeNewObj(interp, nameObj);
94419641
if (he) {
@@ -9442,11 +9642,11 @@
94429642
goto found;
94439643
}
94449644
}
94459645
#endif
94469646
9447
-
9647
+
94489648
he = Jim_FindHashEntry(&interp->commands, name);
94499649
if (he == NULL) {
94509650
if (flags & JIM_ERRMSG) {
94519651
Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
94529652
}
@@ -9455,11 +9655,11 @@
94559655
#ifdef jim_ext_namespace
94569656
found:
94579657
#endif
94589658
cmd = Jim_GetHashEntryVal(he);
94599659
9460
-
9660
+
94619661
Jim_FreeIntRep(interp, objPtr);
94629662
objPtr->typePtr = &commandObjType;
94639663
objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
94649664
objPtr->internalRep.cmdValue.cmdPtr = cmd;
94659665
objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9474,11 +9674,11 @@
94749674
return cmd;
94759675
}
94769676
94779677
94789678
9479
-#define JIM_DICT_SUGAR 100
9679
+#define JIM_DICT_SUGAR 100
94809680
94819681
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
94829682
94839683
static const Jim_ObjType variableObjType = {
94849684
"variable",
@@ -9488,11 +9688,11 @@
94889688
JIM_TYPE_REFERENCES,
94899689
};
94909690
94919691
static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
94929692
{
9493
-
9693
+
94949694
if (nameObjPtr->typePtr != &variableObjType) {
94959695
int len;
94969696
const char *str = Jim_GetString(nameObjPtr, &len);
94979697
if (memchr(str, '\0', len)) {
94989698
Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9508,18 +9708,18 @@
95089708
Jim_CallFrame *framePtr;
95099709
Jim_HashEntry *he;
95109710
int global;
95119711
int len;
95129712
9513
-
9713
+
95149714
if (objPtr->typePtr == &variableObjType) {
95159715
framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
95169716
if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
9517
-
9717
+
95189718
return JIM_OK;
95199719
}
9520
-
9720
+
95219721
}
95229722
else if (objPtr->typePtr == &dictSubstObjType) {
95239723
return JIM_DICT_SUGAR;
95249724
}
95259725
else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9527,11 +9727,11 @@
95279727
}
95289728
95299729
95309730
varName = Jim_GetString(objPtr, &len);
95319731
9532
-
9732
+
95339733
if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
95349734
return JIM_DICT_SUGAR;
95359735
}
95369736
95379737
if (varName[0] == ':' && varName[1] == ':') {
@@ -9543,23 +9743,23 @@
95439743
else {
95449744
global = 0;
95459745
framePtr = interp->framePtr;
95469746
}
95479747
9548
-
9748
+
95499749
he = Jim_FindHashEntry(&framePtr->vars, varName);
95509750
if (he == NULL) {
95519751
if (!global && framePtr->staticVars) {
9552
-
9752
+
95539753
he = Jim_FindHashEntry(framePtr->staticVars, varName);
95549754
}
95559755
if (he == NULL) {
95569756
return JIM_ERR;
95579757
}
95589758
}
95599759
9560
-
9760
+
95619761
Jim_FreeIntRep(interp, objPtr);
95629762
objPtr->typePtr = &variableObjType;
95639763
objPtr->internalRep.varValue.callFrameId = framePtr->id;
95649764
objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
95659765
objPtr->internalRep.varValue.global = global;
@@ -9574,11 +9774,11 @@
95749774
{
95759775
const char *name;
95769776
Jim_CallFrame *framePtr;
95779777
int global;
95789778
9579
-
9779
+
95809780
Jim_Var *var = Jim_Alloc(sizeof(*var));
95819781
95829782
var->objPtr = valObjPtr;
95839783
Jim_IncrRefCount(valObjPtr);
95849784
var->linkFramePtr = NULL;
@@ -9593,14 +9793,14 @@
95939793
else {
95949794
framePtr = interp->framePtr;
95959795
global = 0;
95969796
}
95979797
9598
-
9798
+
95999799
Jim_AddHashEntry(&framePtr->vars, name, var);
96009800
9601
-
9801
+
96029802
Jim_FreeIntRep(interp, nameObjPtr);
96039803
nameObjPtr->typePtr = &variableObjType;
96049804
nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
96059805
nameObjPtr->internalRep.varValue.varPtr = var;
96069806
nameObjPtr->internalRep.varValue.global = global;
@@ -9630,11 +9830,11 @@
96309830
if (var->linkFramePtr == NULL) {
96319831
Jim_IncrRefCount(valObjPtr);
96329832
Jim_DecrRefCount(interp, var->objPtr);
96339833
var->objPtr = valObjPtr;
96349834
}
9635
- else {
9835
+ else {
96369836
Jim_CallFrame *savedCallFrame;
96379837
96389838
savedCallFrame = interp->framePtr;
96399839
interp->framePtr = var->linkFramePtr;
96409840
err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9691,14 +9891,14 @@
96919891
const char *varName;
96929892
const char *targetName;
96939893
Jim_CallFrame *framePtr;
96949894
Jim_Var *varPtr;
96959895
9696
-
9896
+
96979897
switch (SetVariableFromAny(interp, nameObjPtr)) {
96989898
case JIM_DICT_SUGAR:
9699
-
9899
+
97009900
Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
97019901
return JIM_ERR;
97029902
97039903
case JIM_OK:
97049904
varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9706,23 +9906,23 @@
97069906
if (varPtr->linkFramePtr == NULL) {
97079907
Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
97089908
return JIM_ERR;
97099909
}
97109910
9711
-
9911
+
97129912
varPtr->linkFramePtr = NULL;
97139913
break;
97149914
}
97159915
9716
-
9717
-
9916
+
9917
+
97189918
varName = Jim_String(nameObjPtr);
97199919
97209920
if (varName[0] == ':' && varName[1] == ':') {
97219921
while (*++varName == ':') {
97229922
}
9723
-
9923
+
97249924
framePtr = interp->topFramePtr;
97259925
}
97269926
else {
97279927
framePtr = interp->framePtr;
97289928
}
@@ -9742,15 +9942,15 @@
97429942
nameObjPtr);
97439943
Jim_DecrRefCount(interp, targetNameObjPtr);
97449944
return JIM_ERR;
97459945
}
97469946
9747
-
9947
+
97489948
if (framePtr == targetCallFrame) {
97499949
Jim_Obj *objPtr = targetNameObjPtr;
97509950
9751
-
9951
+
97529952
while (1) {
97539953
if (strcmp(Jim_String(objPtr), varName) == 0) {
97549954
Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
97559955
Jim_DecrRefCount(interp, targetNameObjPtr);
97569956
return JIM_ERR;
@@ -9762,13 +9962,13 @@
97629962
break;
97639963
objPtr = varPtr->objPtr;
97649964
}
97659965
}
97669966
9767
-
9967
+
97689968
Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
9769
-
9969
+
97709970
nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
97719971
Jim_DecrRefCount(interp, targetNameObjPtr);
97729972
return JIM_OK;
97739973
}
97749974
@@ -9782,26 +9982,26 @@
97829982
return varPtr->objPtr;
97839983
}
97849984
else {
97859985
Jim_Obj *objPtr;
97869986
9787
-
9987
+
97889988
Jim_CallFrame *savedCallFrame = interp->framePtr;
97899989
97909990
interp->framePtr = varPtr->linkFramePtr;
97919991
objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
97929992
interp->framePtr = savedCallFrame;
97939993
if (objPtr) {
97949994
return objPtr;
97959995
}
9796
-
9996
+
97979997
}
97989998
}
97999999
break;
980010000
980110001
case JIM_DICT_SUGAR:
9802
-
10002
+
980310003
return JimDictSugarGet(interp, nameObjPtr, flags);
980410004
}
980510005
if (flags & JIM_ERRMSG) {
980610006
Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
980710007
}
@@ -9851,17 +10051,17 @@
985110051
int retval;
985210052
Jim_CallFrame *framePtr;
985310053
985410054
retval = SetVariableFromAny(interp, nameObjPtr);
985510055
if (retval == JIM_DICT_SUGAR) {
9856
-
10056
+
985710057
return JimDictSugarSet(interp, nameObjPtr, NULL);
985810058
}
985910059
else if (retval == JIM_OK) {
986010060
varPtr = nameObjPtr->internalRep.varValue.varPtr;
986110061
9862
-
10062
+
986310063
if (varPtr->linkFramePtr) {
986410064
framePtr = interp->framePtr;
986510065
interp->framePtr = varPtr->linkFramePtr;
986610066
retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
986710067
interp->framePtr = framePtr;
@@ -9876,11 +10076,11 @@
987610076
framePtr = interp->framePtr;
987710077
}
987810078
987910079
retval = Jim_DeleteHashEntry(&framePtr->vars, name);
988010080
if (retval == JIM_OK) {
9881
-
10081
+
988210082
framePtr->id = interp->callFrameEpoch++;
988310083
}
988410084
}
988510085
}
988610086
if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -9909,11 +10109,11 @@
990910109
keyLen = (str + len) - p;
991010110
if (str[len - 1] == ')') {
991110111
keyLen--;
991210112
}
991310113
9914
-
10114
+
991510115
keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
991610116
991710117
Jim_IncrRefCount(varObjPtr);
991810118
Jim_IncrRefCount(keyObjPtr);
991910119
*varPtrPtr = varObjPtr;
@@ -9928,23 +10128,23 @@
992810128
992910129
err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
993010130
&objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
993110131
993210132
if (err == JIM_OK) {
9933
-
10133
+
993410134
Jim_SetEmptyResult(interp);
993510135
}
993610136
else {
993710137
if (!valObjPtr) {
9938
-
10138
+
993910139
if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
994010140
Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
994110141
objPtr);
994210142
return err;
994310143
}
994410144
}
9945
-
10145
+
994610146
Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
994710147
(valObjPtr ? "set" : "unset"), objPtr);
994810148
}
994910149
return err;
995010150
}
@@ -9966,11 +10166,11 @@
996610166
Jim_SetResultFormatted(interp,
996710167
"can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
996810168
ret < 0 ? "variable isn't" : "no such element in");
996910169
}
997010170
else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
9971
-
10171
+
997210172
Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
997310173
}
997410174
997510175
return resObjPtr;
997610176
}
@@ -10008,11 +10208,11 @@
1000810208
{
1000910209
if (objPtr->typePtr != &dictSubstObjType) {
1001010210
Jim_Obj *varObjPtr, *keyObjPtr;
1001110211
1001210212
if (objPtr->typePtr == &interpolatedObjType) {
10013
-
10213
+
1001410214
1001510215
varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
1001610216
keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
1001710217
1001810218
Jim_IncrRefCount(varObjPtr);
@@ -10053,11 +10253,11 @@
1005310253
static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
1005410254
{
1005510255
Jim_Obj *resultObjPtr;
1005610256
1005710257
if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
10058
-
10258
+
1005910259
resultObjPtr->refCount--;
1006010260
return resultObjPtr;
1006110261
}
1006210262
return NULL;
1006310263
}
@@ -10076,11 +10276,10 @@
1007610276
cf->procArgsObjPtr = NULL;
1007710277
cf->procBodyObjPtr = NULL;
1007810278
cf->next = NULL;
1007910279
cf->staticVars = NULL;
1008010280
cf->localCommands = NULL;
10081
- cf->tailcall = 0;
1008210281
cf->tailcallObj = NULL;
1008310282
cf->tailcallCmd = NULL;
1008410283
}
1008510284
else {
1008610285
cf = Jim_Alloc(sizeof(*cf));
@@ -10098,11 +10297,11 @@
1009810297
return cf;
1009910298
}
1010010299
1010110300
static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
1010210301
{
10103
-
10302
+
1010410303
if (localCommands) {
1010510304
Jim_Obj *cmdNameObj;
1010610305
1010710306
while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
1010810307
Jim_HashEntry *he;
@@ -10117,20 +10316,20 @@
1011710316
Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
1011810317
if (cmd->prevCmd) {
1011910318
Jim_Cmd *prevCmd = cmd->prevCmd;
1012010319
cmd->prevCmd = NULL;
1012110320
10122
-
10321
+
1012310322
JimDecrCmdRefCount(interp, cmd);
1012410323
10125
-
10324
+
1012610325
Jim_SetHashVal(ht, he, prevCmd);
1012710326
}
1012810327
else {
1012910328
Jim_DeleteHashEntry(ht, fqname);
10130
- Jim_InterpIncrProcEpoch(interp);
1013110329
}
10330
+ Jim_InterpIncrProcEpoch(interp);
1013210331
}
1013310332
Jim_DecrRefCount(interp, cmdNameObj);
1013410333
JimFreeQualifiedName(interp, fqObjName);
1013510334
}
1013610335
Jim_FreeStack(localCommands);
@@ -10138,12 +10337,12 @@
1013810337
}
1013910338
return JIM_OK;
1014010339
}
1014110340
1014210341
10143
-#define JIM_FCF_FULL 0
10144
-#define JIM_FCF_REUSE 1
10342
+#define JIM_FCF_FULL 0
10343
+#define JIM_FCF_REUSE 1
1014510344
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
1014610345
{
1014710346
JimDeleteLocalProcs(interp, cf->localCommands);
1014810347
1014910348
if (cf->procArgsObjPtr)
@@ -10176,263 +10375,10 @@
1017610375
cf->next = interp->freeFramesList;
1017710376
interp->freeFramesList = cf;
1017810377
}
1017910378
1018010379
10181
-#ifdef JIM_REFERENCES
10182
-
10183
-static void JimReferencesHTValDestructor(void *interp, void *val)
10184
-{
10185
- Jim_Reference *refPtr = (void *)val;
10186
-
10187
- Jim_DecrRefCount(interp, refPtr->objPtr);
10188
- if (refPtr->finalizerCmdNamePtr != NULL) {
10189
- Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10190
- }
10191
- Jim_Free(val);
10192
-}
10193
-
10194
-static unsigned int JimReferencesHTHashFunction(const void *key)
10195
-{
10196
-
10197
- const unsigned long *widePtr = key;
10198
- unsigned int intValue = (unsigned int)*widePtr;
10199
-
10200
- return Jim_IntHashFunction(intValue);
10201
-}
10202
-
10203
-static void *JimReferencesHTKeyDup(void *privdata, const void *key)
10204
-{
10205
- void *copy = Jim_Alloc(sizeof(unsigned long));
10206
-
10207
- JIM_NOTUSED(privdata);
10208
-
10209
- memcpy(copy, key, sizeof(unsigned long));
10210
- return copy;
10211
-}
10212
-
10213
-static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2)
10214
-{
10215
- JIM_NOTUSED(privdata);
10216
-
10217
- return memcmp(key1, key2, sizeof(unsigned long)) == 0;
10218
-}
10219
-
10220
-static void JimReferencesHTKeyDestructor(void *privdata, void *key)
10221
-{
10222
- JIM_NOTUSED(privdata);
10223
-
10224
- Jim_Free(key);
10225
-}
10226
-
10227
-static const Jim_HashTableType JimReferencesHashTableType = {
10228
- JimReferencesHTHashFunction,
10229
- JimReferencesHTKeyDup,
10230
- NULL,
10231
- JimReferencesHTKeyCompare,
10232
- JimReferencesHTKeyDestructor,
10233
- JimReferencesHTValDestructor
10234
-};
10235
-
10236
-
10237
-
10238
-#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
10239
-
10240
-static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
10241
-{
10242
- const char *fmt = "<reference.<%s>.%020lu>";
10243
-
10244
- sprintf(buf, fmt, refPtr->tag, id);
10245
- return JIM_REFERENCE_SPACE;
10246
-}
10247
-
10248
-static void UpdateStringOfReference(struct Jim_Obj *objPtr);
10249
-
10250
-static const Jim_ObjType referenceObjType = {
10251
- "reference",
10252
- NULL,
10253
- NULL,
10254
- UpdateStringOfReference,
10255
- JIM_TYPE_REFERENCES,
10256
-};
10257
-
10258
-static void UpdateStringOfReference(struct Jim_Obj *objPtr)
10259
-{
10260
- char buf[JIM_REFERENCE_SPACE + 1];
10261
-
10262
- JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id);
10263
- JimSetStringBytes(objPtr, buf);
10264
-}
10265
-
10266
-static int isrefchar(int c)
10267
-{
10268
- return (c == '_' || isalnum(c));
10269
-}
10270
-
10271
-static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
10272
-{
10273
- unsigned long value;
10274
- int i, len;
10275
- const char *str, *start, *end;
10276
- char refId[21];
10277
- Jim_Reference *refPtr;
10278
- Jim_HashEntry *he;
10279
- char *endptr;
10280
-
10281
-
10282
- str = Jim_GetString(objPtr, &len);
10283
-
10284
- if (len < JIM_REFERENCE_SPACE)
10285
- goto badformat;
10286
-
10287
- start = str;
10288
- end = str + len - 1;
10289
- while (*start == ' ')
10290
- start++;
10291
- while (*end == ' ' && end > start)
10292
- end--;
10293
- if (end - start + 1 != JIM_REFERENCE_SPACE)
10294
- goto badformat;
10295
-
10296
- if (memcmp(start, "<reference.<", 12) != 0)
10297
- goto badformat;
10298
- if (start[12 + JIM_REFERENCE_TAGLEN] != '>' || end[0] != '>')
10299
- goto badformat;
10300
-
10301
- for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10302
- if (!isrefchar(start[12 + i]))
10303
- goto badformat;
10304
- }
10305
-
10306
- memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
10307
- refId[20] = '\0';
10308
-
10309
- value = strtoul(refId, &endptr, 10);
10310
- if (JimCheckConversion(refId, endptr) != JIM_OK)
10311
- goto badformat;
10312
-
10313
- he = Jim_FindHashEntry(&interp->references, &value);
10314
- if (he == NULL) {
10315
- Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
10316
- return JIM_ERR;
10317
- }
10318
- refPtr = Jim_GetHashEntryVal(he);
10319
-
10320
- Jim_FreeIntRep(interp, objPtr);
10321
- objPtr->typePtr = &referenceObjType;
10322
- objPtr->internalRep.refValue.id = value;
10323
- objPtr->internalRep.refValue.refPtr = refPtr;
10324
- return JIM_OK;
10325
-
10326
- badformat:
10327
- Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
10328
- return JIM_ERR;
10329
-}
10330
-
10331
-Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
10332
-{
10333
- struct Jim_Reference *refPtr;
10334
- unsigned long id;
10335
- Jim_Obj *refObjPtr;
10336
- const char *tag;
10337
- int tagLen, i;
10338
-
10339
-
10340
- Jim_CollectIfNeeded(interp);
10341
-
10342
- refPtr = Jim_Alloc(sizeof(*refPtr));
10343
- refPtr->objPtr = objPtr;
10344
- Jim_IncrRefCount(objPtr);
10345
- refPtr->finalizerCmdNamePtr = cmdNamePtr;
10346
- if (cmdNamePtr)
10347
- Jim_IncrRefCount(cmdNamePtr);
10348
- id = interp->referenceNextId++;
10349
- Jim_AddHashEntry(&interp->references, &id, refPtr);
10350
- refObjPtr = Jim_NewObj(interp);
10351
- refObjPtr->typePtr = &referenceObjType;
10352
- refObjPtr->bytes = NULL;
10353
- refObjPtr->internalRep.refValue.id = id;
10354
- refObjPtr->internalRep.refValue.refPtr = refPtr;
10355
- interp->referenceNextId++;
10356
- tag = Jim_GetString(tagPtr, &tagLen);
10357
- if (tagLen > JIM_REFERENCE_TAGLEN)
10358
- tagLen = JIM_REFERENCE_TAGLEN;
10359
- for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10360
- if (i < tagLen && isrefchar(tag[i]))
10361
- refPtr->tag[i] = tag[i];
10362
- else
10363
- refPtr->tag[i] = '_';
10364
- }
10365
- refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0';
10366
- return refObjPtr;
10367
-}
10368
-
10369
-Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr)
10370
-{
10371
- if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR)
10372
- return NULL;
10373
- return objPtr->internalRep.refValue.refPtr;
10374
-}
10375
-
10376
-int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr)
10377
-{
10378
- Jim_Reference *refPtr;
10379
-
10380
- if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10381
- return JIM_ERR;
10382
- Jim_IncrRefCount(cmdNamePtr);
10383
- if (refPtr->finalizerCmdNamePtr)
10384
- Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10385
- refPtr->finalizerCmdNamePtr = cmdNamePtr;
10386
- return JIM_OK;
10387
-}
10388
-
10389
-int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr)
10390
-{
10391
- Jim_Reference *refPtr;
10392
-
10393
- if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10394
- return JIM_ERR;
10395
- *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr;
10396
- return JIM_OK;
10397
-}
10398
-
10399
-
10400
-
10401
-static const Jim_HashTableType JimRefMarkHashTableType = {
10402
- JimReferencesHTHashFunction,
10403
- JimReferencesHTKeyDup,
10404
- NULL,
10405
- JimReferencesHTKeyCompare,
10406
- JimReferencesHTKeyDestructor,
10407
- NULL
10408
-};
10409
-
10410
-
10411
-int Jim_Collect(Jim_Interp *interp)
10412
-{
10413
- int collected = 0;
10414
- return collected;
10415
-}
10416
-
10417
-#define JIM_COLLECT_ID_PERIOD 5000
10418
-#define JIM_COLLECT_TIME_PERIOD 300
10419
-
10420
-void Jim_CollectIfNeeded(Jim_Interp *interp)
10421
-{
10422
- unsigned long elapsedId;
10423
- int elapsedTime;
10424
-
10425
- elapsedId = interp->referenceNextId - interp->lastCollectId;
10426
- elapsedTime = time(NULL) - interp->lastCollectTime;
10427
-
10428
-
10429
- if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) {
10430
- Jim_Collect(interp);
10431
- }
10432
-}
10433
-#endif
1043410380
1043510381
int Jim_IsBigEndian(void)
1043610382
{
1043710383
union {
1043810384
unsigned short s;
@@ -10479,14 +10425,15 @@
1047910425
Jim_IncrRefCount(i->nullScriptObj);
1048010426
Jim_IncrRefCount(i->errorProc);
1048110427
Jim_IncrRefCount(i->trueObj);
1048210428
Jim_IncrRefCount(i->falseObj);
1048310429
10484
-
10430
+
1048510431
Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
1048610432
Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
1048710433
10434
+ Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim");
1048810435
Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
1048910436
Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM);
1049010437
Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR);
1049110438
Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", Jim_IsBigEndian() ? "bigEndian" : "littleEndian");
1049210439
Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0");
@@ -10500,11 +10447,11 @@
1050010447
{
1050110448
Jim_CallFrame *cf, *cfx;
1050210449
1050310450
Jim_Obj *objPtr, *nextObjPtr;
1050410451
10505
-
10452
+
1050610453
for (cf = i->framePtr; cf; cf = cfx) {
1050710454
cfx = cf->parent;
1050810455
JimFreeCallFrame(i, cf, JIM_FCF_FULL);
1050910456
}
1051010457
@@ -10553,27 +10500,27 @@
1055310500
printf("-------------------------------------\n\n");
1055410501
JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
1055510502
}
1055610503
#endif
1055710504
10558
-
10505
+
1055910506
objPtr = i->freeList;
1056010507
while (objPtr) {
1056110508
nextObjPtr = objPtr->nextObjPtr;
1056210509
Jim_Free(objPtr);
1056310510
objPtr = nextObjPtr;
1056410511
}
1056510512
10566
-
10513
+
1056710514
for (cf = i->freeFramesList; cf; cf = cfx) {
1056810515
cfx = cf->next;
1056910516
if (cf->vars.table)
1057010517
Jim_FreeHashTable(&cf->vars);
1057110518
Jim_Free(cf);
1057210519
}
1057310520
10574
-
10521
+
1057510522
Jim_Free(i);
1057610523
}
1057710524
1057810525
Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
1057910526
{
@@ -10594,25 +10541,25 @@
1059410541
else {
1059510542
if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
1059610543
level = -1;
1059710544
}
1059810545
else {
10599
-
10546
+
1060010547
level = interp->framePtr->level - level;
1060110548
}
1060210549
}
1060310550
}
1060410551
else {
10605
- str = "1";
10552
+ str = "1";
1060610553
level = interp->framePtr->level - 1;
1060710554
}
1060810555
1060910556
if (level == 0) {
1061010557
return interp->topFramePtr;
1061110558
}
1061210559
if (level > 0) {
10613
-
10560
+
1061410561
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
1061510562
if (framePtr->level == level) {
1061610563
return framePtr;
1061710564
}
1061810565
}
@@ -10627,19 +10574,19 @@
1062710574
long level;
1062810575
Jim_CallFrame *framePtr;
1062910576
1063010577
if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
1063110578
if (level <= 0) {
10632
-
10579
+
1063310580
level = interp->framePtr->level + level;
1063410581
}
1063510582
1063610583
if (level == 0) {
1063710584
return interp->topFramePtr;
1063810585
}
1063910586
10640
-
10587
+
1064110588
for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
1064210589
if (framePtr->level == level) {
1064310590
return framePtr;
1064410591
}
1064510592
}
@@ -10658,11 +10605,11 @@
1065810605
1065910606
static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
1066010607
{
1066110608
int len;
1066210609
10663
-
10610
+
1066410611
Jim_IncrRefCount(stackTraceObj);
1066510612
Jim_DecrRefCount(interp, interp->stackTrace);
1066610613
interp->stackTrace = stackTraceObj;
1066710614
interp->errorFlag = 1;
1066810615
@@ -10679,32 +10626,32 @@
1067910626
{
1068010627
if (strcmp(procname, "unknown") == 0) {
1068110628
procname = "";
1068210629
}
1068310630
if (!*procname && !Jim_Length(fileNameObj)) {
10684
-
10631
+
1068510632
return;
1068610633
}
1068710634
1068810635
if (Jim_IsShared(interp->stackTrace)) {
1068910636
Jim_DecrRefCount(interp, interp->stackTrace);
1069010637
interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
1069110638
Jim_IncrRefCount(interp->stackTrace);
1069210639
}
1069310640
10694
-
10641
+
1069510642
if (!*procname && Jim_Length(fileNameObj)) {
10696
-
10643
+
1069710644
int len = Jim_ListLength(interp, interp->stackTrace);
1069810645
1069910646
if (len >= 3) {
1070010647
Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
1070110648
if (Jim_Length(objPtr)) {
10702
-
10649
+
1070310650
objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
1070410651
if (Jim_Length(objPtr) == 0) {
10705
-
10652
+
1070610653
ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
1070710654
ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
1070810655
return;
1070910656
}
1071010657
}
@@ -10806,18 +10753,18 @@
1080610753
{
1080710754
jim_wide wideValue;
1080810755
const char *str;
1080910756
1081010757
if (objPtr->typePtr == &coercedDoubleObjType) {
10811
-
10758
+
1081210759
objPtr->typePtr = &intObjType;
1081310760
return JIM_OK;
1081410761
}
1081510762
10816
-
10763
+
1081710764
str = Jim_String(objPtr);
10818
-
10765
+
1081910766
if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
1082010767
if (flags & JIM_ERRMSG) {
1082110768
Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
1082210769
}
1082310770
return JIM_ERR;
@@ -10824,11 +10771,11 @@
1082410771
}
1082510772
if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
1082610773
Jim_SetResultString(interp, "Integer value too big to be represented", -1);
1082710774
return JIM_ERR;
1082810775
}
10829
-
10776
+
1083010777
Jim_FreeIntRep(interp, objPtr);
1083110778
objPtr->typePtr = &intObjType;
1083210779
objPtr->internalRep.wideValue = wideValue;
1083310780
return JIM_OK;
1083410781
}
@@ -10923,17 +10870,17 @@
1092310870
{
1092410871
char buf[JIM_DOUBLE_SPACE + 1];
1092510872
int i;
1092610873
int len = sprintf(buf, "%.12g", value);
1092710874
10928
-
10875
+
1092910876
for (i = 0; i < len; i++) {
1093010877
if (buf[i] == '.' || buf[i] == 'e') {
1093110878
#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
1093210879
char *e = strchr(buf, 'e');
1093310880
if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
10934
-
10881
+
1093510882
e += 2;
1093610883
memmove(e, e + 1, len - (e - buf));
1093710884
}
1093810885
#endif
1093910886
break;
@@ -10955,38 +10902,38 @@
1095510902
const char *str;
1095610903
1095710904
str = Jim_String(objPtr);
1095810905
1095910906
#ifdef HAVE_LONG_LONG
10960
-
10907
+
1096110908
#define MIN_INT_IN_DOUBLE -(1LL << 53)
1096210909
#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
1096310910
1096410911
if (objPtr->typePtr == &intObjType
1096510912
&& JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
1096610913
&& JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
1096710914
10968
-
10915
+
1096910916
objPtr->typePtr = &coercedDoubleObjType;
1097010917
return JIM_OK;
1097110918
}
1097210919
else
1097310920
#endif
1097410921
if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
10975
-
10922
+
1097610923
Jim_FreeIntRep(interp, objPtr);
1097710924
objPtr->typePtr = &coercedDoubleObjType;
1097810925
objPtr->internalRep.wideValue = wideValue;
1097910926
return JIM_OK;
1098010927
}
1098110928
else {
10982
-
10929
+
1098310930
if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
1098410931
Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
1098510932
return JIM_ERR;
1098610933
}
10987
-
10934
+
1098810935
Jim_FreeIntRep(interp, objPtr);
1098910936
}
1099010937
objPtr->typePtr = &doubleObjType;
1099110938
objPtr->internalRep.doubleValue = doubleValue;
1099210939
return JIM_OK;
@@ -11018,10 +10965,50 @@
1101810965
objPtr->typePtr = &doubleObjType;
1101910966
objPtr->bytes = NULL;
1102010967
objPtr->internalRep.doubleValue = doubleValue;
1102110968
return objPtr;
1102210969
}
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
+}
1102311010
1102411011
static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
1102511012
static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
1102611013
static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
1102711014
static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -11069,11 +11056,11 @@
1106911056
#define JIM_ELESTR_QUOTE 2
1107011057
static unsigned char ListElementQuotingType(const char *s, int len)
1107111058
{
1107211059
int i, level, blevel, trySimple = 1;
1107311060
11074
-
11061
+
1107511062
if (len == 0)
1107611063
return JIM_ELESTR_BRACE;
1107711064
if (s[0] == '"' || s[0] == '{') {
1107811065
trySimple = 0;
1107911066
goto testbrace;
@@ -11091,19 +11078,20 @@
1109111078
case '\n':
1109211079
case '\t':
1109311080
case '\f':
1109411081
case '\v':
1109511082
trySimple = 0;
11083
+
1109611084
case '{':
1109711085
case '}':
1109811086
goto testbrace;
1109911087
}
1110011088
}
1110111089
return JIM_ELESTR_SIMPLE;
1110211090
1110311091
testbrace:
11104
-
11092
+
1110511093
if (s[len - 1] == '\\')
1110611094
return JIM_ELESTR_QUOTE;
1110711095
level = 0;
1110811096
blevel = 0;
1110911097
for (i = 0; i < len; i++) {
@@ -11219,11 +11207,11 @@
1121911207
int i, bufLen, realLength;
1122011208
const char *strRep;
1122111209
char *p;
1122211210
unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
1122311211
11224
-
11212
+
1122511213
if (objc > STATIC_QUOTING_LEN) {
1122611214
quotingType = Jim_Alloc(objc);
1122711215
}
1122811216
else {
1122911217
quotingType = staticQuoting;
@@ -11238,25 +11226,25 @@
1123811226
case JIM_ELESTR_SIMPLE:
1123911227
if (i != 0 || strRep[0] != '#') {
1124011228
bufLen += len;
1124111229
break;
1124211230
}
11243
-
11231
+
1124411232
quotingType[i] = JIM_ELESTR_BRACE;
11245
-
11233
+
1124611234
case JIM_ELESTR_BRACE:
1124711235
bufLen += len + 2;
1124811236
break;
1124911237
case JIM_ELESTR_QUOTE:
1125011238
bufLen += len * 2;
1125111239
break;
1125211240
}
11253
- bufLen++;
11241
+ bufLen++;
1125411242
}
1125511243
bufLen++;
1125611244
11257
-
11245
+
1125811246
p = objPtr->bytes = Jim_Alloc(bufLen + 1);
1125911247
realLength = 0;
1126011248
for (i = 0; i < objc; i++) {
1126111249
int len, qlen;
1126211250
@@ -11283,17 +11271,17 @@
1128311271
qlen = BackslashQuoteString(strRep, len, p);
1128411272
p += qlen;
1128511273
realLength += qlen;
1128611274
break;
1128711275
}
11288
-
11276
+
1128911277
if (i + 1 != objc) {
1129011278
*p++ = ' ';
1129111279
realLength++;
1129211280
}
1129311281
}
11294
- *p = '\0';
11282
+ *p = '\0';
1129511283
objPtr->length = realLength;
1129611284
1129711285
if (quotingType != staticQuoting) {
1129811286
Jim_Free(quotingType);
1129911287
}
@@ -11324,21 +11312,21 @@
1132411312
listObjPtrPtr = JimDictPairs(objPtr, &len);
1132511313
for (i = 0; i < len; i++) {
1132611314
Jim_IncrRefCount(listObjPtrPtr[i]);
1132711315
}
1132811316
11329
-
11317
+
1133011318
Jim_FreeIntRep(interp, objPtr);
1133111319
objPtr->typePtr = &listObjType;
1133211320
objPtr->internalRep.listValue.len = len;
1133311321
objPtr->internalRep.listValue.maxLen = len;
1133411322
objPtr->internalRep.listValue.ele = listObjPtrPtr;
1133511323
1133611324
return JIM_OK;
1133711325
}
1133811326
11339
-
11327
+
1134011328
if (objPtr->typePtr == &sourceObjType) {
1134111329
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
1134211330
linenr = objPtr->internalRep.sourceValue.lineNumber;
1134311331
}
1134411332
else {
@@ -11345,20 +11333,20 @@
1134511333
fileNameObj = interp->emptyObj;
1134611334
linenr = 1;
1134711335
}
1134811336
Jim_IncrRefCount(fileNameObj);
1134911337
11350
-
11338
+
1135111339
str = Jim_GetString(objPtr, &strLen);
1135211340
1135311341
Jim_FreeIntRep(interp, objPtr);
1135411342
objPtr->typePtr = &listObjType;
1135511343
objPtr->internalRep.listValue.len = 0;
1135611344
objPtr->internalRep.listValue.maxLen = 0;
1135711345
objPtr->internalRep.listValue.ele = NULL;
1135811346
11359
-
11347
+
1136011348
if (strLen) {
1136111349
JimParserInit(&parser, str, strLen, linenr);
1136211350
while (!parser.eof) {
1136311351
Jim_Obj *elementPtr;
1136411352
@@ -11488,11 +11476,11 @@
1148811476
Jim_Obj *compare_script;
1148911477
int rc;
1149011478
1149111479
jim_wide ret = 0;
1149211480
11493
-
11481
+
1149411482
compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
1149511483
Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
1149611484
Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
1149711485
1149811486
rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11510,23 +11498,23 @@
1151011498
int dst = 0;
1151111499
Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
1151211500
1151311501
for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
1151411502
if (comp(&ele[dst], &ele[src]) == 0) {
11515
-
11503
+
1151611504
Jim_DecrRefCount(sort_info->interp, ele[dst]);
1151711505
}
1151811506
else {
11519
-
11507
+
1152011508
dst++;
1152111509
}
1152211510
ele[dst] = ele[src];
1152311511
}
11524
-
11512
+
1152511513
ele[++dst] = ele[src];
1152611514
11527
-
11515
+
1152811516
listObjPtr->internalRep.listValue.len = dst;
1152911517
}
1153011518
1153111519
1153211520
static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11540,11 +11528,11 @@
1154011528
int rc;
1154111529
1154211530
JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
1154311531
SetListFromAny(interp, listObjPtr);
1154411532
11545
-
11533
+
1154611534
prev_info = sort_info;
1154711535
sort_info = info;
1154811536
1154911537
vector = listObjPtr->internalRep.listValue.ele;
1155011538
len = listObjPtr->internalRep.listValue.len;
@@ -11563,16 +11551,17 @@
1156311551
break;
1156411552
case JIM_LSORT_COMMAND:
1156511553
fn = ListSortCommand;
1156611554
break;
1156711555
default:
11568
- fn = NULL;
11556
+ fn = NULL;
1156911557
JimPanic((1, "ListSort called with invalid sort type"));
11558
+ return -1;
1157011559
}
1157111560
1157211561
if (info->indexed) {
11573
-
11562
+
1157411563
info->subfn = fn;
1157511564
fn = ListSortIndexHelper;
1157611565
}
1157711566
1157811567
if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11596,11 +11585,11 @@
1159611585
int i;
1159711586
Jim_Obj **point;
1159811587
1159911588
if (requiredLen > listPtr->internalRep.listValue.maxLen) {
1160011589
if (requiredLen < 2) {
11601
-
11590
+
1160211591
requiredLen = 4;
1160311592
}
1160411593
else {
1160511594
requiredLen *= 2;
1160611595
}
@@ -11782,34 +11771,34 @@
1178211771
for (i = 0; i < objc; i++)
1178311772
ListAppendList(objPtr, objv[i]);
1178411773
return objPtr;
1178511774
}
1178611775
else {
11787
-
11776
+
1178811777
int len = 0, objLen;
1178911778
char *bytes, *p;
1179011779
11791
-
11780
+
1179211781
for (i = 0; i < objc; i++) {
1179311782
len += Jim_Length(objv[i]);
1179411783
}
1179511784
if (objc)
1179611785
len += objc - 1;
11797
-
11786
+
1179811787
p = bytes = Jim_Alloc(len + 1);
1179911788
for (i = 0; i < objc; i++) {
1180011789
const char *s = Jim_GetString(objv[i], &objLen);
1180111790
11802
-
11791
+
1180311792
while (objLen && isspace(UCHAR(*s))) {
1180411793
s++;
1180511794
objLen--;
1180611795
len--;
1180711796
}
11808
-
11797
+
1180911798
while (objLen && isspace(UCHAR(s[objLen - 1]))) {
11810
-
11799
+
1181111800
if (objLen > 1 && s[objLen - 2] == '\\') {
1181211801
break;
1181311802
}
1181411803
objLen--;
1181511804
len--;
@@ -11836,11 +11825,11 @@
1183611825
int len, rangeLen;
1183711826
1183811827
if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
1183911828
Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
1184011829
return NULL;
11841
- len = Jim_ListLength(interp, listObjPtr);
11830
+ len = Jim_ListLength(interp, listObjPtr);
1184211831
first = JimRelToAbsIndex(len, first);
1184311832
last = JimRelToAbsIndex(len, last);
1184411833
JimRelToAbsRange(len, &first, &last, &rangeLen);
1184511834
if (first == 0 && last == len) {
1184611835
return listObjPtr;
@@ -11876,16 +11865,16 @@
1187611865
{
1187711866
Jim_DecrRefCount(interp, (Jim_Obj *)val);
1187811867
}
1187911868
1188011869
static const Jim_HashTableType JimDictHashTableType = {
11881
- JimObjectHTHashFunction,
11882
- JimObjectHTKeyValDup,
11883
- JimObjectHTKeyValDup,
11884
- JimObjectHTKeyCompare,
11885
- JimObjectHTKeyValDestructor,
11886
- JimObjectHTKeyValDestructor
11870
+ JimObjectHTHashFunction,
11871
+ JimObjectHTKeyValDup,
11872
+ JimObjectHTKeyValDup,
11873
+ JimObjectHTKeyCompare,
11874
+ JimObjectHTKeyValDestructor,
11875
+ JimObjectHTKeyValDestructor
1188711876
};
1188811877
1188911878
static const Jim_ObjType dictObjType = {
1189011879
"dict",
1189111880
FreeDictInternalRep,
@@ -11906,17 +11895,17 @@
1190611895
{
1190711896
Jim_HashTable *ht, *dupHt;
1190811897
Jim_HashTableIterator htiter;
1190911898
Jim_HashEntry *he;
1191011899
11911
-
11900
+
1191211901
ht = srcPtr->internalRep.ptr;
1191311902
dupHt = Jim_Alloc(sizeof(*dupHt));
1191411903
Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
1191511904
if (ht->size != 0)
1191611905
Jim_ExpandHashTable(dupHt, ht->size);
11917
-
11906
+
1191811907
JimInitHashTableIterator(ht, &htiter);
1191911908
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1192011909
Jim_AddHashEntry(dupHt, he->key, he->u.val);
1192111910
}
1192211911
@@ -11932,11 +11921,11 @@
1193211921
Jim_Obj **objv;
1193311922
int i;
1193411923
1193511924
ht = dictPtr->internalRep.ptr;
1193611925
11937
-
11926
+
1193811927
objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
1193911928
JimInitHashTableIterator(ht, &htiter);
1194011929
i = 0;
1194111930
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1194211931
objv[i++] = Jim_GetHashEntryKey(he);
@@ -11946,15 +11935,15 @@
1194611935
return objv;
1194711936
}
1194811937
1194911938
static void UpdateStringOfDict(struct Jim_Obj *objPtr)
1195011939
{
11951
-
11940
+
1195211941
int len;
1195311942
Jim_Obj **objv = JimDictPairs(objPtr, &len);
1195411943
11955
-
11944
+
1195611945
JimMakeListStringRep(objPtr, objv, len);
1195711946
1195811947
Jim_Free(objv);
1195911948
}
1196011949
@@ -11968,18 +11957,18 @@
1196811957
1196911958
if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
1197011959
Jim_String(objPtr);
1197111960
}
1197211961
11973
-
11962
+
1197411963
listlen = Jim_ListLength(interp, objPtr);
1197511964
if (listlen % 2) {
1197611965
Jim_SetResultString(interp, "missing value to go with key", -1);
1197711966
return JIM_ERR;
1197811967
}
1197911968
else {
11980
-
11969
+
1198111970
Jim_HashTable *ht;
1198211971
int i;
1198311972
1198411973
ht = Jim_Alloc(sizeof(*ht));
1198511974
Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -12004,11 +11993,11 @@
1200411993
static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
1200511994
Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
1200611995
{
1200711996
Jim_HashTable *ht = objPtr->internalRep.ptr;
1200811997
12009
- if (valueObjPtr == NULL) {
11998
+ if (valueObjPtr == NULL) {
1201011999
return Jim_DeleteHashEntry(ht, keyObjPtr);
1201112000
}
1201212001
Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
1201312002
return JIM_OK;
1201412003
}
@@ -12104,11 +12093,11 @@
1210412093
int shared, i;
1210512094
1210612095
varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
1210712096
if (objPtr == NULL) {
1210812097
if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
12109
-
12098
+
1211012099
return JIM_ERR;
1211112100
}
1211212101
varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
1211312102
if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
1211412103
Jim_FreeNewObj(interp, varObjPtr);
@@ -12118,26 +12107,26 @@
1211812107
if ((shared = Jim_IsShared(objPtr)))
1211912108
varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
1212012109
for (i = 0; i < keyc; i++) {
1212112110
dictObjPtr = objPtr;
1212212111
12123
-
12112
+
1212412113
if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
1212512114
goto err;
1212612115
}
1212712116
1212812117
if (i == keyc - 1) {
12129
-
12118
+
1213012119
if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
1213112120
if (newObjPtr || (flags & JIM_MUSTEXIST)) {
1213212121
goto err;
1213312122
}
1213412123
}
1213512124
break;
1213612125
}
1213712126
12138
-
12127
+
1213912128
Jim_InvalidateStringRep(dictObjPtr);
1214012129
if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
1214112130
newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
1214212131
if (Jim_IsShared(objPtr)) {
1214312132
objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12150,11 +12139,11 @@
1215012139
}
1215112140
objPtr = Jim_NewDictObj(interp, NULL, 0);
1215212141
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
1215312142
}
1215412143
}
12155
-
12144
+
1215612145
Jim_InvalidateStringRep(objPtr);
1215712146
Jim_InvalidateStringRep(varObjPtr);
1215812147
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
1215912148
goto err;
1216012149
}
@@ -12187,11 +12176,11 @@
1218712176
char buf[JIM_INTEGER_SPACE + 1];
1218812177
if (objPtr->internalRep.intValue >= 0) {
1218912178
sprintf(buf, "%d", objPtr->internalRep.intValue);
1219012179
}
1219112180
else {
12192
-
12181
+
1219312182
sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
1219412183
}
1219512184
JimSetStringBytes(objPtr, buf);
1219612185
}
1219712186
}
@@ -12200,14 +12189,14 @@
1220012189
{
1220112190
int idx, end = 0;
1220212191
const char *str;
1220312192
char *endptr;
1220412193
12205
-
12194
+
1220612195
str = Jim_String(objPtr);
1220712196
12208
-
12197
+
1220912198
if (strncmp(str, "end", 3) == 0) {
1221012199
end = 1;
1221112200
str += 3;
1221212201
idx = 0;
1221312202
}
@@ -12218,21 +12207,21 @@
1221812207
goto badindex;
1221912208
}
1222012209
str = endptr;
1222112210
}
1222212211
12223
-
12212
+
1222412213
if (*str == '+' || *str == '-') {
1222512214
int sign = (*str == '+' ? 1 : -1);
1222612215
1222712216
idx += sign * jim_strtol(++str, &endptr);
1222812217
if (str == endptr || *endptr) {
1222912218
goto badindex;
1223012219
}
1223112220
str = endptr;
1223212221
}
12233
-
12222
+
1223412223
while (isspace(UCHAR(*str))) {
1223512224
str++;
1223612225
}
1223712226
if (*str) {
1223812227
goto badindex;
@@ -12240,19 +12229,19 @@
1224012229
if (end) {
1224112230
if (idx > 0) {
1224212231
idx = INT_MAX;
1224312232
}
1224412233
else {
12245
-
12234
+
1224612235
idx--;
1224712236
}
1224812237
}
1224912238
else if (idx < 0) {
1225012239
idx = -INT_MAX;
1225112240
}
1225212241
12253
-
12242
+
1225412243
Jim_FreeIntRep(interp, objPtr);
1225512244
objPtr->typePtr = &indexObjType;
1225612245
objPtr->internalRep.intValue = idx;
1225712246
return JIM_OK;
1225812247
@@ -12262,11 +12251,11 @@
1226212251
return JIM_ERR;
1226312252
}
1226412253
1226512254
int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
1226612255
{
12267
-
12256
+
1226812257
if (objPtr->typePtr == &intObjType) {
1226912258
jim_wide val = JimWideValue(objPtr);
1227012259
1227112260
if (val < 0)
1227212261
*indexPtr = -INT_MAX;
@@ -12319,18 +12308,18 @@
1231912308
static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
1232012309
{
1232112310
int returnCode;
1232212311
jim_wide wideValue;
1232312312
12324
-
12313
+
1232512314
if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
1232612315
returnCode = (int)wideValue;
1232712316
else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
1232812317
Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
1232912318
return JIM_ERR;
1233012319
}
12331
-
12320
+
1233212321
Jim_FreeIntRep(interp, objPtr);
1233312322
objPtr->typePtr = &returnCodeObjType;
1233412323
objPtr->internalRep.intValue = returnCode;
1233512324
return JIM_OK;
1233612325
}
@@ -12344,19 +12333,20 @@
1234412333
}
1234512334
1234612335
static int JimParseExprOperator(struct JimParserCtx *pc);
1234712336
static int JimParseExprNumber(struct JimParserCtx *pc);
1234812337
static int JimParseExprIrrational(struct JimParserCtx *pc);
12338
+static int JimParseExprBoolean(struct JimParserCtx *pc);
1234912339
1235012340
1235112341
1235212342
1235312343
enum
1235412344
{
12355
-
12356
-
12357
- JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
12345
+
12346
+
12347
+ JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
1235812348
JIM_EXPROP_DIV,
1235912349
JIM_EXPROP_MOD,
1236012350
JIM_EXPROP_SUB,
1236112351
JIM_EXPROP_ADD,
1236212352
JIM_EXPROP_LSHIFT,
@@ -12367,66 +12357,67 @@
1236712357
JIM_EXPROP_GT,
1236812358
JIM_EXPROP_LTE,
1236912359
JIM_EXPROP_GTE,
1237012360
JIM_EXPROP_NUMEQ,
1237112361
JIM_EXPROP_NUMNE,
12372
- JIM_EXPROP_BITAND,
12362
+ JIM_EXPROP_BITAND,
1237312363
JIM_EXPROP_BITXOR,
1237412364
JIM_EXPROP_BITOR,
1237512365
12376
-
12377
- JIM_EXPROP_LOGICAND,
12366
+
12367
+ JIM_EXPROP_LOGICAND,
1237812368
JIM_EXPROP_LOGICAND_LEFT,
1237912369
JIM_EXPROP_LOGICAND_RIGHT,
1238012370
12381
-
12382
- JIM_EXPROP_LOGICOR,
12371
+
12372
+ JIM_EXPROP_LOGICOR,
1238312373
JIM_EXPROP_LOGICOR_LEFT,
1238412374
JIM_EXPROP_LOGICOR_RIGHT,
1238512375
12386
-
12387
-
12388
- JIM_EXPROP_TERNARY,
12376
+
12377
+
12378
+ JIM_EXPROP_TERNARY,
1238912379
JIM_EXPROP_TERNARY_LEFT,
1239012380
JIM_EXPROP_TERNARY_RIGHT,
1239112381
12392
-
12393
- JIM_EXPROP_COLON,
12382
+
12383
+ JIM_EXPROP_COLON,
1239412384
JIM_EXPROP_COLON_LEFT,
1239512385
JIM_EXPROP_COLON_RIGHT,
1239612386
12397
- JIM_EXPROP_POW,
12387
+ JIM_EXPROP_POW,
1239812388
1239912389
12400
- JIM_EXPROP_STREQ,
12390
+ JIM_EXPROP_STREQ,
1240112391
JIM_EXPROP_STRNE,
1240212392
JIM_EXPROP_STRIN,
1240312393
JIM_EXPROP_STRNI,
1240412394
1240512395
12406
- JIM_EXPROP_NOT,
12396
+ JIM_EXPROP_NOT,
1240712397
JIM_EXPROP_BITNOT,
1240812398
JIM_EXPROP_UNARYMINUS,
1240912399
JIM_EXPROP_UNARYPLUS,
1241012400
12411
-
12412
- JIM_EXPROP_FUNC_FIRST,
12401
+
12402
+ JIM_EXPROP_FUNC_FIRST,
1241312403
JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
1241412404
JIM_EXPROP_FUNC_WIDE,
1241512405
JIM_EXPROP_FUNC_ABS,
1241612406
JIM_EXPROP_FUNC_DOUBLE,
1241712407
JIM_EXPROP_FUNC_ROUND,
1241812408
JIM_EXPROP_FUNC_RAND,
1241912409
JIM_EXPROP_FUNC_SRAND,
1242012410
12421
-
12422
- JIM_EXPROP_FUNC_SIN,
12411
+
12412
+ JIM_EXPROP_FUNC_SIN,
1242312413
JIM_EXPROP_FUNC_COS,
1242412414
JIM_EXPROP_FUNC_TAN,
1242512415
JIM_EXPROP_FUNC_ASIN,
1242612416
JIM_EXPROP_FUNC_ACOS,
1242712417
JIM_EXPROP_FUNC_ATAN,
12418
+ JIM_EXPROP_FUNC_ATAN2,
1242812419
JIM_EXPROP_FUNC_SINH,
1242912420
JIM_EXPROP_FUNC_COSH,
1243012421
JIM_EXPROP_FUNC_TANH,
1243112422
JIM_EXPROP_FUNC_CEIL,
1243212423
JIM_EXPROP_FUNC_FLOOR,
@@ -12433,10 +12424,12 @@
1243312424
JIM_EXPROP_FUNC_EXP,
1243412425
JIM_EXPROP_FUNC_LOG,
1243512426
JIM_EXPROP_FUNC_LOG10,
1243612427
JIM_EXPROP_FUNC_SQRT,
1243712428
JIM_EXPROP_FUNC_POW,
12429
+ JIM_EXPROP_FUNC_HYPOT,
12430
+ JIM_EXPROP_FUNC_FMOD,
1243812431
};
1243912432
1244012433
struct JimExprState
1244112434
{
1244212435
Jim_Obj **stack;
@@ -12513,11 +12506,15 @@
1251312506
case JIM_EXPROP_UNARYPLUS:
1251412507
dC = dA;
1251512508
intresult = 0;
1251612509
break;
1251712510
case JIM_EXPROP_FUNC_ABS:
12511
+#ifdef JIM_MATH_FUNCTIONS
12512
+ dC = fabs(dA);
12513
+#else
1251812514
dC = dA >= 0 ? dA : -dA;
12515
+#endif
1251912516
intresult = 0;
1252012517
break;
1252112518
case JIM_EXPROP_UNARYMINUS:
1252212519
dC = -dA;
1252312520
intresult = 0;
@@ -12705,16 +12702,16 @@
1270512702
}
1270612703
}
1270712704
break;
1270812705
case JIM_EXPROP_ROTL:
1270912706
case JIM_EXPROP_ROTR:{
12710
-
12707
+
1271112708
unsigned long uA = (unsigned long)wA;
1271212709
unsigned long uB = (unsigned long)wB;
1271312710
const unsigned int S = sizeof(unsigned long) * 8;
1271412711
12715
-
12712
+
1271612713
uB %= S;
1271712714
1271812715
if (e->opcode == JIM_EXPROP_ROTR) {
1271912716
uB = S - uB;
1272012717
}
@@ -12736,11 +12733,10 @@
1273612733
1273712734
1273812735
1273912736
static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
1274012737
{
12741
- int intresult = 1;
1274212738
int rc = JIM_OK;
1274312739
double dA, dB, dC = 0;
1274412740
jim_wide wA, wB, wC = 0;
1274512741
1274612742
Jim_Obj *B = ExprPop(e);
@@ -12748,30 +12744,36 @@
1274812744
1274912745
if ((A->typePtr != &doubleObjType || A->bytes) &&
1275012746
(B->typePtr != &doubleObjType || B->bytes) &&
1275112747
JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
1275212748
12753
-
12749
+
1275412750
1275512751
switch (e->opcode) {
1275612752
case JIM_EXPROP_POW:
1275712753
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
+ }
1275812759
wC = JimPowWide(wA, wB);
12759
- break;
12760
+ goto intresult;
1276012761
case JIM_EXPROP_ADD:
1276112762
wC = wA + wB;
12762
- break;
12763
+ goto intresult;
1276312764
case JIM_EXPROP_SUB:
1276412765
wC = wA - wB;
12765
- break;
12766
+ goto intresult;
1276612767
case JIM_EXPROP_MUL:
1276712768
wC = wA * wB;
12768
- break;
12769
+ goto intresult;
1276912770
case JIM_EXPROP_DIV:
1277012771
if (wB == 0) {
1277112772
Jim_SetResultString(interp, "Division by zero", -1);
1277212773
rc = JIM_ERR;
12774
+ goto done;
1277312775
}
1277412776
else {
1277512777
if (wB < 0) {
1277612778
wB = -wB;
1277712779
wA = -wA;
@@ -12778,55 +12780,67 @@
1277812780
}
1277912781
wC = wA / wB;
1278012782
if (wA % wB < 0) {
1278112783
wC--;
1278212784
}
12785
+ goto intresult;
1278312786
}
12784
- break;
1278512787
case JIM_EXPROP_LT:
1278612788
wC = wA < wB;
12787
- break;
12789
+ goto intresult;
1278812790
case JIM_EXPROP_GT:
1278912791
wC = wA > wB;
12790
- break;
12792
+ goto intresult;
1279112793
case JIM_EXPROP_LTE:
1279212794
wC = wA <= wB;
12793
- break;
12795
+ goto intresult;
1279412796
case JIM_EXPROP_GTE:
1279512797
wC = wA >= wB;
12796
- break;
12798
+ goto intresult;
1279712799
case JIM_EXPROP_NUMEQ:
1279812800
wC = wA == wB;
12799
- break;
12801
+ goto intresult;
1280012802
case JIM_EXPROP_NUMNE:
1280112803
wC = wA != wB;
12802
- break;
12803
- default:
12804
- abort();
12804
+ goto intresult;
1280512805
}
1280612806
}
12807
- else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12808
- intresult = 0;
12807
+ if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
1280912808
switch (e->opcode) {
12809
+#ifndef JIM_MATH_FUNCTIONS
1281012810
case JIM_EXPROP_POW:
1281112811
case JIM_EXPROP_FUNC_POW:
12812
-#ifdef JIM_MATH_FUNCTIONS
12813
- dC = pow(dA, dB);
12814
-#else
12812
+ case JIM_EXPROP_FUNC_ATAN2:
12813
+ case JIM_EXPROP_FUNC_HYPOT:
12814
+ case JIM_EXPROP_FUNC_FMOD:
1281512815
Jim_SetResultString(interp, "unsupported", -1);
1281612816
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;
1281712832
#endif
12818
- break;
1281912833
case JIM_EXPROP_ADD:
1282012834
dC = dA + dB;
12821
- break;
12835
+ goto doubleresult;
1282212836
case JIM_EXPROP_SUB:
1282312837
dC = dA - dB;
12824
- break;
12838
+ goto doubleresult;
1282512839
case JIM_EXPROP_MUL:
1282612840
dC = dA * dB;
12827
- break;
12841
+ goto doubleresult;
1282812842
case JIM_EXPROP_DIV:
1282912843
if (dB == 0) {
1283012844
#ifdef INFINITY
1283112845
dC = dA < 0 ? -INFINITY : INFINITY;
1283212846
#else
@@ -12834,83 +12848,70 @@
1283412848
#endif
1283512849
}
1283612850
else {
1283712851
dC = dA / dB;
1283812852
}
12839
- break;
12853
+ goto doubleresult;
1284012854
case JIM_EXPROP_LT:
1284112855
wC = dA < dB;
12842
- intresult = 1;
12843
- break;
12856
+ goto intresult;
1284412857
case JIM_EXPROP_GT:
1284512858
wC = dA > dB;
12846
- intresult = 1;
12847
- break;
12859
+ goto intresult;
1284812860
case JIM_EXPROP_LTE:
1284912861
wC = dA <= dB;
12850
- intresult = 1;
12851
- break;
12862
+ goto intresult;
1285212863
case JIM_EXPROP_GTE:
1285312864
wC = dA >= dB;
12854
- intresult = 1;
12855
- break;
12865
+ goto intresult;
1285612866
case JIM_EXPROP_NUMEQ:
1285712867
wC = dA == dB;
12858
- intresult = 1;
12859
- break;
12868
+ goto intresult;
1286012869
case JIM_EXPROP_NUMNE:
1286112870
wC = dA != dB;
12862
- intresult = 1;
12863
- break;
12864
- default:
12865
- abort();
12871
+ goto intresult;
1286612872
}
1286712873
}
1286812874
else {
12869
-
1287012875
12871
-
12876
+
12877
+
1287212878
int i = Jim_StringCompareObj(interp, A, B, 0);
1287312879
1287412880
switch (e->opcode) {
1287512881
case JIM_EXPROP_LT:
1287612882
wC = i < 0;
12877
- break;
12883
+ goto intresult;
1287812884
case JIM_EXPROP_GT:
1287912885
wC = i > 0;
12880
- break;
12886
+ goto intresult;
1288112887
case JIM_EXPROP_LTE:
1288212888
wC = i <= 0;
12883
- break;
12889
+ goto intresult;
1288412890
case JIM_EXPROP_GTE:
1288512891
wC = i >= 0;
12886
- break;
12892
+ goto intresult;
1288712893
case JIM_EXPROP_NUMEQ:
1288812894
wC = i == 0;
12889
- break;
12895
+ goto intresult;
1289012896
case JIM_EXPROP_NUMNE:
1289112897
wC = i != 0;
12892
- break;
12893
- default:
12894
- rc = JIM_ERR;
12895
- break;
12898
+ goto intresult;
1289612899
}
1289712900
}
1289812901
12899
- if (rc == JIM_OK) {
12900
- if (intresult) {
12901
- ExprPush(e, Jim_NewIntObj(interp, wC));
12902
- }
12903
- else {
12904
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
12905
- }
12906
- }
12907
-
12902
+ rc = JIM_ERR;
12903
+done:
1290812904
Jim_DecrRefCount(interp, A);
1290912905
Jim_DecrRefCount(interp, B);
12910
-
1291112906
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;
1291212913
}
1291312914
1291412915
static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
1291512916
{
1291612917
int listlen;
@@ -12959,16 +12960,20 @@
1295912960
1296012961
static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
1296112962
{
1296212963
long l;
1296312964
double d;
12965
+ int b;
1296412966
1296512967
if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
1296612968
return l != 0;
1296712969
}
1296812970
if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
1296912971
return d != 0;
12972
+ }
12973
+ if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) {
12974
+ return b != 0;
1297012975
}
1297112976
return -1;
1297212977
}
1297312978
1297412979
static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
@@ -12977,21 +12982,21 @@
1297712982
Jim_Obj *A = ExprPop(e);
1297812983
int rc = JIM_OK;
1297912984
1298012985
switch (ExprBool(interp, A)) {
1298112986
case 0:
12982
-
12987
+
1298312988
e->skip = JimWideValue(skip);
1298412989
ExprPush(e, Jim_NewIntObj(interp, 0));
1298512990
break;
1298612991
1298712992
case 1:
12988
-
12993
+
1298912994
break;
1299012995
1299112996
case -1:
12992
-
12997
+
1299312998
rc = JIM_ERR;
1299412999
}
1299513000
Jim_DecrRefCount(interp, A);
1299613001
Jim_DecrRefCount(interp, skip);
1299713002
@@ -13004,21 +13009,21 @@
1300413009
Jim_Obj *A = ExprPop(e);
1300513010
int rc = JIM_OK;
1300613011
1300713012
switch (ExprBool(interp, A)) {
1300813013
case 0:
13009
-
13014
+
1301013015
break;
1301113016
1301213017
case 1:
13013
-
13018
+
1301413019
e->skip = JimWideValue(skip);
1301513020
ExprPush(e, Jim_NewIntObj(interp, 1));
1301613021
break;
1301713022
1301813023
case -1:
13019
-
13024
+
1302013025
rc = JIM_ERR;
1302113026
break;
1302213027
}
1302313028
Jim_DecrRefCount(interp, A);
1302413029
Jim_DecrRefCount(interp, skip);
@@ -13039,11 +13044,11 @@
1303913044
case 1:
1304013045
ExprPush(e, Jim_NewIntObj(interp, 1));
1304113046
break;
1304213047
1304313048
case -1:
13044
-
13049
+
1304513050
rc = JIM_ERR;
1304613051
break;
1304713052
}
1304813053
Jim_DecrRefCount(interp, A);
1304913054
@@ -13054,27 +13059,27 @@
1305413059
{
1305513060
Jim_Obj *skip = ExprPop(e);
1305613061
Jim_Obj *A = ExprPop(e);
1305713062
int rc = JIM_OK;
1305813063
13059
-
13064
+
1306013065
ExprPush(e, A);
1306113066
1306213067
switch (ExprBool(interp, A)) {
1306313068
case 0:
13064
-
13069
+
1306513070
e->skip = JimWideValue(skip);
13066
-
13071
+
1306713072
ExprPush(e, Jim_NewIntObj(interp, 0));
1306813073
break;
1306913074
1307013075
case 1:
13071
-
13076
+
1307213077
break;
1307313078
1307413079
case -1:
13075
-
13080
+
1307613081
rc = JIM_ERR;
1307713082
break;
1307813083
}
1307913084
Jim_DecrRefCount(interp, A);
1308013085
Jim_DecrRefCount(interp, skip);
@@ -13086,15 +13091,15 @@
1308613091
{
1308713092
Jim_Obj *skip = ExprPop(e);
1308813093
Jim_Obj *B = ExprPop(e);
1308913094
Jim_Obj *A = ExprPop(e);
1309013095
13091
-
13096
+
1309213097
if (ExprBool(interp, A)) {
13093
-
13098
+
1309413099
e->skip = JimWideValue(skip);
13095
-
13100
+
1309613101
ExprPush(e, B);
1309713102
}
1309813103
1309913104
Jim_DecrRefCount(interp, skip);
1310013105
Jim_DecrRefCount(interp, A);
@@ -13110,15 +13115,16 @@
1311013115
enum
1311113116
{
1311213117
LAZY_NONE,
1311313118
LAZY_OP,
1311413119
LAZY_LEFT,
13115
- LAZY_RIGHT
13120
+ LAZY_RIGHT,
13121
+ RIGHT_ASSOC,
1311613122
};
1311713123
13118
-#define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1}
13119
-#define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1}
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)
1312013126
1312113127
static const struct Jim_ExprOperator Jim_ExprOperators[] = {
1312213128
OPRINIT("*", 110, 2, JimExprOpBin),
1312313129
OPRINIT("/", 110, 2, JimExprOpBin),
1312413130
OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13142,27 +13148,28 @@
1314213148
1314313149
OPRINIT("&", 50, 2, JimExprOpIntBin),
1314413150
OPRINIT("^", 49, 2, JimExprOpIntBin),
1314513151
OPRINIT("|", 48, 2, JimExprOpIntBin),
1314613152
13147
- OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP),
13148
- OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13149
- OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13150
-
13151
- OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP),
13152
- OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13153
- OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13154
-
13155
- OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP),
13156
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13157
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13158
-
13159
- OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP),
13160
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13161
- OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13162
-
13163
- OPRINIT("**", 250, 2, JimExprOpBin),
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),
1316413171
1316513172
OPRINIT("eq", 60, 2, JimExprOpStrBin),
1316613173
OPRINIT("ne", 60, 2, JimExprOpStrBin),
1316713174
1316813175
OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13188,10 +13195,11 @@
1318813195
OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
1318913196
OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
1319013197
OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
1319113198
OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
1319213199
OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
13200
+ OPRINIT("atan2", 200, 2, JimExprOpBin),
1319313201
OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
1319413202
OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
1319513203
OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
1319613204
OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
1319713205
OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13198,10 +13206,12 @@
1319813206
OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
1319913207
OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
1320013208
OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
1320113209
OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
1320213210
OPRINIT("pow", 200, 2, JimExprOpBin),
13211
+ OPRINIT("hypot", 200, 2, JimExprOpBin),
13212
+ OPRINIT("fmod", 200, 2, JimExprOpBin),
1320313213
#endif
1320413214
};
1320513215
#undef OPRINIT
1320613216
#undef OPRINIT_LAZY
1320713217
@@ -13208,20 +13218,20 @@
1320813218
#define JIM_EXPR_OPERATORS_NUM \
1320913219
(sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
1321013220
1321113221
static int JimParseExpression(struct JimParserCtx *pc)
1321213222
{
13213
-
13223
+
1321413224
while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
1321513225
if (*pc->p == '\n') {
1321613226
pc->linenr++;
1321713227
}
1321813228
pc->p++;
1321913229
pc->len--;
1322013230
}
1322113231
13222
-
13232
+
1322313233
pc->tline = pc->linenr;
1322413234
pc->tstart = pc->p;
1322513235
1322613236
if (pc->len == 0) {
1322713237
pc->tend = pc->p;
@@ -13247,11 +13257,11 @@
1324713257
return JimParseCmd(pc);
1324813258
case '$':
1324913259
if (JimParseVar(pc) == JIM_ERR)
1325013260
return JimParseExprOperator(pc);
1325113261
else {
13252
-
13262
+
1325313263
if (pc->tt == JIM_TT_EXPRSUGAR) {
1325413264
return JIM_ERR;
1325513265
}
1325613266
return JIM_OK;
1325713267
}
@@ -13276,10 +13286,18 @@
1327613286
case 'N':
1327713287
case 'I':
1327813288
case 'n':
1327913289
case 'i':
1328013290
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)
1328113299
return JimParseExprOperator(pc);
1328213300
break;
1328313301
default:
1328413302
return JimParseExprOperator(pc);
1328513303
break;
@@ -13289,21 +13307,21 @@
1328913307
1329013308
static int JimParseExprNumber(struct JimParserCtx *pc)
1329113309
{
1329213310
char *end;
1329313311
13294
-
13312
+
1329513313
pc->tt = JIM_TT_EXPR_INT;
1329613314
1329713315
jim_strtoull(pc->p, (char **)&pc->p);
13298
-
13316
+
1329913317
if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
13300
- if (strtod(pc->tstart, &end)) { }
13318
+ if (strtod(pc->tstart, &end)) { }
1330113319
if (end == pc->tstart)
1330213320
return JIM_ERR;
1330313321
if (end > pc->p) {
13304
-
13322
+
1330513323
pc->tt = JIM_TT_EXPR_DOUBLE;
1330613324
pc->p = end;
1330713325
}
1330813326
}
1330913327
pc->tend = pc->p - 1;
@@ -13327,17 +13345,38 @@
1332713345
return JIM_OK;
1332813346
}
1332913347
}
1333013348
return JIM_ERR;
1333113349
}
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
+}
1333213371
1333313372
static int JimParseExprOperator(struct JimParserCtx *pc)
1333413373
{
1333513374
int i;
1333613375
int bestIdx = -1, bestLen = 0;
1333713376
13338
-
13377
+
1333913378
for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
1334013379
const char * const opname = Jim_ExprOperators[i].name;
1334113380
const int oplen = Jim_ExprOperators[i].namelen;
1334213381
1334313382
if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13351,11 +13390,11 @@
1335113390
}
1335213391
if (bestIdx == -1) {
1335313392
return JIM_ERR;
1335413393
}
1335513394
13356
-
13395
+
1335713396
if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
1335813397
const char *p = pc->p + bestLen;
1335913398
int len = pc->len - bestLen;
1336013399
1336113400
while (len && isspace(UCHAR(*p))) {
@@ -13385,13 +13424,19 @@
1338513424
1338613425
const char *jim_tt_name(int type)
1338713426
{
1338813427
static const char * const tt_names[JIM_TT_EXPR_OP] =
1338913428
{ "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
13390
- "DBL", "$()" };
13429
+ "DBL", "BOO", "$()" };
1339113430
if (type < JIM_TT_EXPR_OP) {
1339213431
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";
1339313438
}
1339413439
else {
1339513440
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
1339613441
static char buf[20];
1339713442
@@ -13416,13 +13461,13 @@
1341613461
};
1341713462
1341813463
1341913464
typedef struct ExprByteCode
1342013465
{
13421
- ScriptToken *token;
13422
- int len;
13423
- int inUse;
13466
+ ScriptToken *token;
13467
+ int len;
13468
+ int inUse;
1342413469
} ExprByteCode;
1342513470
1342613471
static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
1342713472
{
1342813473
int i;
@@ -13450,26 +13495,29 @@
1345013495
static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
1345113496
{
1345213497
JIM_NOTUSED(interp);
1345313498
JIM_NOTUSED(srcPtr);
1345413499
13455
-
13500
+
1345613501
dupPtr->typePtr = NULL;
1345713502
}
1345813503
13459
-
13460
-static int ExprCheckCorrectness(ExprByteCode * expr)
13504
+static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr)
1346113505
{
1346213506
int i;
1346313507
int stacklen = 0;
1346413508
int ternary = 0;
13509
+ int lasttt = JIM_TT_NONE;
13510
+ const char *errmsg;
1346513511
1346613512
for (i = 0; i < expr->len; i++) {
1346713513
ScriptToken *t = &expr->token[i];
1346813514
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13515
+ lasttt = t->type;
1346913516
1347013517
stacklen -= op->arity;
13518
+
1347113519
if (stacklen < 0) {
1347213520
break;
1347313521
}
1347413522
if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
1347513523
ternary++;
@@ -13476,26 +13524,47 @@
1347613524
}
1347713525
else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
1347813526
ternary--;
1347913527
}
1348013528
13481
-
13529
+
1348213530
stacklen++;
1348313531
}
13484
- if (stacklen != 1 || ternary != 0) {
13485
- return JIM_ERR;
13532
+ if (stacklen == 1 && ternary == 0) {
13533
+ return JIM_OK;
1348613534
}
13487
- return JIM_OK;
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;
1348813557
}
1348913558
1349013559
static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
1349113560
{
1349213561
int i;
1349313562
1349413563
int leftindex, arity, offset;
1349513564
13496
-
13565
+
1349713566
leftindex = expr->len - 1;
1349813567
1349913568
arity = 1;
1350013569
while (arity) {
1350113570
ScriptToken *tt = &expr->token[leftindex];
@@ -13508,11 +13577,11 @@
1350813577
return JIM_ERR;
1350913578
}
1351013579
}
1351113580
leftindex++;
1351213581
13513
-
13582
+
1351413583
memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
1351513584
sizeof(*expr->token) * (expr->len - leftindex));
1351613585
expr->len += 2;
1351713586
offset = (expr->len - leftindex) - 1;
1351813587
@@ -13520,16 +13589,16 @@
1352013589
expr->token[leftindex + 1].objPtr = interp->emptyObj;
1352113590
1352213591
expr->token[leftindex].type = JIM_TT_EXPR_INT;
1352313592
expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
1352413593
13525
-
13594
+
1352613595
expr->token[expr->len].objPtr = interp->emptyObj;
1352713596
expr->token[expr->len].type = t->type + 2;
1352813597
expr->len++;
1352913598
13530
-
13599
+
1353113600
for (i = leftindex - 1; i > 0; i--) {
1353213601
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
1353313602
if (op->lazy == LAZY_LEFT) {
1353413603
if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
1353513604
JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13575,11 +13644,11 @@
1357513644
return right_index;
1357613645
}
1357713646
right_index--;
1357813647
}
1357913648
13580
-
13649
+
1358113650
return -1;
1358213651
}
1358313652
1358413653
static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
1358513654
{
@@ -13617,11 +13686,11 @@
1361713686
1361813687
if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
1361913688
continue;
1362013689
}
1362113690
13622
-
13691
+
1362313692
if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
1362413693
continue;
1362513694
}
1362613695
1362713696
tmp = expr->token[prev_right_index];
@@ -13630,25 +13699,25 @@
1363013699
}
1363113700
expr->token[i] = tmp;
1363213701
1363313702
JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
1363413703
13635
-
13704
+
1363613705
i++;
1363713706
}
1363813707
}
1363913708
13640
-static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj)
13709
+static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj)
1364113710
{
1364213711
Jim_Stack stack;
1364313712
ExprByteCode *expr;
1364413713
int ok = 1;
1364513714
int i;
1364613715
int prevtt = JIM_TT_NONE;
1364713716
int have_ternary = 0;
1364813717
13649
-
13718
+
1365013719
int count = tokenlist->count - 1;
1365113720
1365213721
expr = Jim_Alloc(sizeof(*expr));
1365313722
expr->inUse = 1;
1365413723
expr->len = 0;
@@ -13659,11 +13728,11 @@
1365913728
ParseToken *t = &tokenlist->list[i];
1366013729
const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
1366113730
1366213731
if (op->lazy == LAZY_OP) {
1366313732
count += 2;
13664
-
13733
+
1366513734
if (t->type == JIM_EXPROP_TERNARY) {
1366613735
have_ternary = 1;
1366713736
}
1366813737
}
1366913738
}
@@ -13671,128 +13740,128 @@
1367113740
expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
1367213741
1367313742
for (i = 0; i < tokenlist->count && ok; i++) {
1367413743
ParseToken *t = &tokenlist->list[i];
1367513744
13676
-
13745
+
1367713746
struct ScriptToken *token = &expr->token[expr->len];
1367813747
1367913748
if (t->type == JIM_TT_EOL) {
1368013749
break;
1368113750
}
1368213751
13683
- switch (t->type) {
13684
- case JIM_TT_STR:
13685
- case JIM_TT_ESC:
13686
- case JIM_TT_VAR:
13687
- case JIM_TT_DICTSUGAR:
13688
- case JIM_TT_EXPRSUGAR:
13689
- case JIM_TT_CMD:
13690
- token->type = t->type;
13691
-strexpr:
13692
- token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13693
- if (t->type == JIM_TT_CMD) {
13694
-
13695
- JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13696
- }
13697
- expr->len++;
13698
- break;
13699
-
13700
- case JIM_TT_EXPR_INT:
13701
- case JIM_TT_EXPR_DOUBLE:
13702
- {
13703
- char *endptr;
13704
- if (t->type == JIM_TT_EXPR_INT) {
13705
- token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13706
- }
13707
- else {
13708
- token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13709
- }
13710
- if (endptr != t->token + t->len) {
13711
-
13712
- Jim_FreeNewObj(interp, token->objPtr);
13713
- token->type = JIM_TT_STR;
13714
- goto strexpr;
13715
- }
13716
- token->type = t->type;
13717
- expr->len++;
13718
- }
13719
- break;
13720
-
13721
- case JIM_TT_SUBEXPR_START:
13722
- Jim_StackPush(&stack, t);
13723
- prevtt = JIM_TT_NONE;
13724
- continue;
13725
-
13726
- case JIM_TT_SUBEXPR_COMMA:
13727
-
13728
- continue;
13729
-
13730
- case JIM_TT_SUBEXPR_END:
13731
- ok = 0;
13732
- while (Jim_StackLen(&stack)) {
13733
- ParseToken *tt = Jim_StackPop(&stack);
13734
-
13735
- if (tt->type == JIM_TT_SUBEXPR_START) {
13736
- ok = 1;
13737
- break;
13738
- }
13739
-
13740
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13741
- goto err;
13742
- }
13743
- }
13744
- if (!ok) {
13745
- Jim_SetResultString(interp, "Unexpected close parenthesis", -1);
13746
- goto err;
13747
- }
13748
- break;
13749
-
13750
-
13751
- default:{
13752
-
13753
- const struct Jim_ExprOperator *op;
13754
- ParseToken *tt;
13755
-
13756
-
13757
- if (prevtt == JIM_TT_NONE || 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
-
13775
- if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13776
- if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13777
- ok = 0;
13778
- goto err;
13779
- }
13780
- Jim_StackPop(&stack);
13781
- }
13782
- else {
13783
- break;
13784
- }
13785
- }
13786
- Jim_StackPush(&stack, t);
13787
- break;
13788
- }
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++;
1378913858
}
1379013859
prevtt = t->type;
1379113860
}
1379213861
13793
-
13862
+
1379413863
while (Jim_StackLen(&stack)) {
1379513864
ParseToken *tt = Jim_StackPop(&stack);
1379613865
1379713866
if (tt->type == JIM_TT_SUBEXPR_START) {
1379813867
ok = 0;
@@ -13808,11 +13877,11 @@
1380813877
if (have_ternary) {
1380913878
ExprTernaryReorderExpression(interp, expr);
1381013879
}
1381113880
1381213881
err:
13813
-
13882
+
1381413883
Jim_FreeStack(&stack);
1381513884
1381613885
for (i = 0; i < expr->len; i++) {
1381713886
Jim_IncrRefCount(expr->token[i].objPtr);
1381813887
}
@@ -13835,11 +13904,11 @@
1383513904
ParseTokenList tokenlist;
1383613905
int line;
1383713906
Jim_Obj *fileNameObj;
1383813907
int rc = JIM_ERR;
1383913908
13840
-
13909
+
1384113910
if (objPtr->typePtr == &sourceObjType) {
1384213911
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
1384313912
line = objPtr->internalRep.sourceValue.lineNumber;
1384413913
}
1384513914
else {
@@ -13848,18 +13917,17 @@
1384813917
}
1384913918
Jim_IncrRefCount(fileNameObj);
1385013919
1385113920
exprText = Jim_GetString(objPtr, &exprTextLen);
1385213921
13853
-
13922
+
1385413923
ScriptTokenListInit(&tokenlist);
1385513924
1385613925
JimParserInit(&parser, exprText, exprTextLen, line);
1385713926
while (!parser.eof) {
1385813927
if (JimParseExpression(&parser) != JIM_OK) {
1385913928
ScriptTokenListFree(&tokenlist);
13860
- invalidexpr:
1386113929
Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
1386213930
expr = NULL;
1386313931
goto err;
1386413932
}
1386513933
@@ -13882,14 +13950,14 @@
1388213950
ScriptTokenListFree(&tokenlist);
1388313951
Jim_DecrRefCount(interp, fileNameObj);
1388413952
return JIM_ERR;
1388513953
}
1388613954
13887
-
13888
- expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj);
1388913955
13890
-
13956
+ expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj);
13957
+
13958
+
1389113959
ScriptTokenListFree(&tokenlist);
1389213960
1389313961
if (!expr) {
1389413962
goto err;
1389513963
}
@@ -13905,20 +13973,22 @@
1390513973
printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
1390613974
}
1390713975
}
1390813976
#endif
1390913977
13910
-
13911
- if (ExprCheckCorrectness(expr) != JIM_OK) {
13978
+
13979
+ if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) {
13980
+
1391213981
ExprFreeByteCode(interp, expr);
13913
- goto invalidexpr;
13982
+ expr = NULL;
13983
+ goto err;
1391413984
}
1391513985
1391613986
rc = JIM_OK;
1391713987
1391813988
err:
13919
-
13989
+
1392013990
Jim_DecrRefCount(interp, fileNameObj);
1392113991
Jim_FreeIntRep(interp, objPtr);
1392213992
Jim_SetIntRepPtr(objPtr, expr);
1392313993
objPtr->typePtr = &exprObjType;
1392413994
return rc;
@@ -13958,11 +14028,11 @@
1395814028
int retcode = JIM_OK;
1395914029
struct JimExprState e;
1396014030
1396114031
expr = JimGetExpression(interp, exprObjPtr);
1396214032
if (!expr) {
13963
- return JIM_ERR;
14033
+ return JIM_ERR;
1396414034
}
1396514035
1396614036
#ifdef JIM_OPTIMIZATION
1396714037
{
1396814038
Jim_Obj *objPtr;
@@ -14031,26 +14101,27 @@
1403114101
noopt:
1403214102
#endif
1403314103
1403414104
expr->inUse++;
1403514105
14036
-
14106
+
1403714107
1403814108
if (expr->len > JIM_EE_STATICSTACK_LEN)
1403914109
e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
1404014110
else
1404114111
e.stack = staticStack;
1404214112
1404314113
e.stacklen = 0;
1404414114
14045
-
14115
+
1404614116
for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
1404714117
Jim_Obj *objPtr;
1404814118
1404914119
switch (expr->token[i].type) {
1405014120
case JIM_TT_EXPR_INT:
1405114121
case JIM_TT_EXPR_DOUBLE:
14122
+ case JIM_TT_EXPR_BOOLEAN:
1405214123
case JIM_TT_STR:
1405314124
ExprPush(&e, expr->token[i].objPtr);
1405414125
break;
1405514126
1405614127
case JIM_TT_VAR:
@@ -14086,16 +14157,16 @@
1408614157
ExprPush(&e, Jim_GetResult(interp));
1408714158
}
1408814159
break;
1408914160
1409014161
default:{
14091
-
14162
+
1409214163
e.skip = 0;
1409314164
e.opcode = expr->token[i].type;
1409414165
1409514166
retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
14096
-
14167
+
1409714168
i += e.skip;
1409814169
continue;
1409914170
}
1410014171
}
1410114172
}
@@ -14119,20 +14190,27 @@
1411914190
int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
1412014191
{
1412114192
int retcode;
1412214193
jim_wide wideValue;
1412314194
double doubleValue;
14195
+ int booleanValue;
1412414196
Jim_Obj *exprResultPtr;
1412514197
1412614198
retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
1412714199
if (retcode != JIM_OK)
1412814200
return retcode;
1412914201
1413014202
if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
1413114203
if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
14132
- Jim_DecrRefCount(interp, exprResultPtr);
14133
- return JIM_ERR;
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
+ }
1413414212
}
1413514213
else {
1413614214
Jim_DecrRefCount(interp, exprResultPtr);
1413714215
*boolPtr = doubleValue != 0;
1413814216
return JIM_OK;
@@ -14147,29 +14225,29 @@
1414714225
1414814226
1414914227
1415014228
typedef struct ScanFmtPartDescr
1415114229
{
14152
- char *arg;
14153
- char *prefix;
14154
- size_t width;
14155
- int pos;
14156
- char type;
14157
- char modifier;
14230
+ char *arg;
14231
+ char *prefix;
14232
+ size_t width;
14233
+ int pos;
14234
+ char type;
14235
+ char modifier;
1415814236
} ScanFmtPartDescr;
1415914237
1416014238
1416114239
typedef struct ScanFmtStringObj
1416214240
{
14163
- jim_wide size;
14164
- char *stringRep;
14165
- size_t count;
14166
- size_t convCount;
14167
- size_t maxPos;
14168
- const char *error;
14169
- char *scratch;
14170
- ScanFmtPartDescr descr[1];
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];
1417114249
} ScanFmtStringObj;
1417214250
1417314251
1417414252
static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
1417514253
static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14216,22 +14294,22 @@
1421614294
int maxFmtLen = objPtr->length;
1421714295
const char *fmtEnd = fmt + maxFmtLen;
1421814296
int curr;
1421914297
1422014298
Jim_FreeIntRep(interp, objPtr);
14221
-
14299
+
1422214300
for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
1422314301
if (fmt[i] == '%')
1422414302
++maxCount;
14225
-
14226
- approxSize = sizeof(ScanFmtStringObj)
14227
- +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14228
- +maxFmtLen * sizeof(char) + 3 + 1
14229
- + maxFmtLen * sizeof(char) + 1
14230
- + maxFmtLen * sizeof(char)
14231
- +(maxCount + 1) * sizeof(char)
14232
- +1;
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;
1423314311
fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
1423414312
memset(fmtObj, 0, approxSize);
1423514313
fmtObj->size = approxSize;
1423614314
fmtObj->maxPos = 0;
1423714315
fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14243,12 +14321,12 @@
1424314321
for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
1424414322
int width = 0, skip;
1424514323
ScanFmtPartDescr *descr = &fmtObj->descr[curr];
1424614324
1424714325
fmtObj->count++;
14248
- descr->width = 0;
14249
-
14326
+ descr->width = 0;
14327
+
1425014328
if (*fmt != '%' || fmt[1] == '%') {
1425114329
descr->type = 0;
1425214330
descr->prefix = &buffer[i];
1425314331
for (; fmt < fmtEnd; ++fmt) {
1425414332
if (*fmt == '%') {
@@ -14258,65 +14336,65 @@
1425814336
}
1425914337
buffer[i++] = *fmt;
1426014338
}
1426114339
buffer[i++] = 0;
1426214340
}
14263
-
14341
+
1426414342
++fmt;
14265
-
14343
+
1426614344
if (fmt >= fmtEnd)
1426714345
goto done;
14268
- descr->pos = 0;
14346
+ descr->pos = 0;
1426914347
if (*fmt == '*') {
14270
- descr->pos = -1;
14348
+ descr->pos = -1;
1427114349
++fmt;
1427214350
}
1427314351
else
14274
- fmtObj->convCount++;
14275
-
14352
+ fmtObj->convCount++;
14353
+
1427614354
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
1427714355
fmt += skip;
14278
-
14356
+
1427914357
if (descr->pos != -1 && *fmt == '$') {
1428014358
int prev;
1428114359
1428214360
++fmt;
1428314361
descr->pos = width;
1428414362
width = 0;
14285
-
14363
+
1428614364
if ((lastPos == 0 && descr->pos > 0)
1428714365
|| (lastPos > 0 && descr->pos == 0)) {
1428814366
fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
1428914367
return JIM_ERR;
1429014368
}
14291
-
14369
+
1429214370
for (prev = 0; prev < curr; ++prev) {
1429314371
if (fmtObj->descr[prev].pos == -1)
1429414372
continue;
1429514373
if (fmtObj->descr[prev].pos == descr->pos) {
1429614374
fmtObj->error =
1429714375
"variable is assigned by multiple \"%n$\" conversion specifiers";
1429814376
return JIM_ERR;
1429914377
}
1430014378
}
14301
-
14379
+
1430214380
if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
1430314381
descr->width = width;
1430414382
fmt += skip;
1430514383
}
1430614384
if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
1430714385
fmtObj->maxPos = descr->pos;
1430814386
}
1430914387
else {
14310
-
14388
+
1431114389
descr->width = width;
1431214390
}
1431314391
}
14314
-
14392
+
1431514393
if (lastPos == -1)
1431614394
lastPos = descr->pos;
14317
-
14395
+
1431814396
if (*fmt == '[') {
1431914397
int swapped = 1, beg = i, end, j;
1432014398
1432114399
descr->type = '[';
1432214400
descr->arg = &buffer[i];
@@ -14331,11 +14409,11 @@
1433114409
fmtObj->error = "unmatched [ in format string";
1433214410
return JIM_ERR;
1433314411
}
1433414412
end = i;
1433514413
buffer[i++] = 0;
14336
-
14414
+
1433714415
while (swapped) {
1433814416
swapped = 0;
1433914417
for (j = beg + 1; j < end - 1; ++j) {
1434014418
if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
1434114419
char tmp = buffer[j - 1];
@@ -14346,11 +14424,11 @@
1434614424
}
1434714425
}
1434814426
}
1434914427
}
1435014428
else {
14351
-
14429
+
1435214430
if (strchr("hlL", *fmt) != 0)
1435314431
descr->modifier = tolower((int)*fmt++);
1435414432
1435514433
descr->type = *fmt;
1435614434
if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14389,11 +14467,11 @@
1438914467
while (*str) {
1439014468
int c;
1439114469
int n;
1439214470
1439314471
if (!sdescr && isspace(UCHAR(*str)))
14394
- break;
14472
+ break;
1439514473
1439614474
n = utf8_tounicode(str, &c);
1439714475
if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
1439814476
break;
1439914477
while (n--)
@@ -14412,89 +14490,89 @@
1441214490
size_t scanned = 0;
1441314491
size_t anchor = pos;
1441414492
int i;
1441514493
Jim_Obj *tmpObj = NULL;
1441614494
14417
-
14495
+
1441814496
*valObjPtr = 0;
1441914497
if (descr->prefix) {
1442014498
for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
14421
-
14499
+
1442214500
if (isspace(UCHAR(descr->prefix[i])))
1442314501
while (pos < strLen && isspace(UCHAR(str[pos])))
1442414502
++pos;
1442514503
else if (descr->prefix[i] != str[pos])
14426
- break;
14504
+ break;
1442714505
else
14428
- ++pos;
14506
+ ++pos;
1442914507
}
1443014508
if (pos >= strLen) {
14431
- return -1;
14509
+ return -1;
1443214510
}
1443314511
else if (descr->prefix[i] != 0)
14434
- return 0;
14512
+ return 0;
1443514513
}
14436
-
14514
+
1443714515
if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
1443814516
while (isspace(UCHAR(str[pos])))
1443914517
++pos;
14440
-
14518
+
1444114519
scanned = pos - anchor;
1444214520
14443
-
14521
+
1444414522
if (descr->type == 'n') {
14445
-
14523
+
1444614524
*valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
1444714525
}
1444814526
else if (pos >= strLen) {
14449
-
14527
+
1445014528
return -1;
1445114529
}
1445214530
else if (descr->type == 'c') {
1445314531
int c;
1445414532
scanned += utf8_tounicode(&str[pos], &c);
1445514533
*valObjPtr = Jim_NewIntObj(interp, c);
1445614534
return scanned;
1445714535
}
1445814536
else {
14459
-
14537
+
1446014538
if (descr->width > 0) {
1446114539
size_t sLen = utf8_strlen(&str[pos], strLen - pos);
1446214540
size_t tLen = descr->width > sLen ? sLen : descr->width;
1446314541
1446414542
tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
1446514543
tok = tmpObj->bytes;
1446614544
}
1446714545
else {
14468
-
14546
+
1446914547
tok = &str[pos];
1447014548
}
1447114549
switch (descr->type) {
1447214550
case 'd':
1447314551
case 'o':
1447414552
case 'x':
1447514553
case 'u':
1447614554
case 'i':{
14477
- char *endp;
14555
+ char *endp;
1447814556
jim_wide w;
1447914557
1448014558
int base = descr->type == 'o' ? 8
1448114559
: descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
1448214560
14483
-
14561
+
1448414562
if (base == 0) {
1448514563
w = jim_strtoull(tok, &endp);
1448614564
}
1448714565
else {
1448814566
w = strtoull(tok, &endp, base);
1448914567
}
1449014568
1449114569
if (endp != tok) {
14492
-
14570
+
1449314571
*valObjPtr = Jim_NewIntObj(interp, w);
1449414572
14495
-
14573
+
1449614574
scanned += endp - tok;
1449714575
}
1449814576
else {
1449914577
scanned = *tok ? 0 : -1;
1450014578
}
@@ -14511,13 +14589,13 @@
1451114589
case 'g':{
1451214590
char *endp;
1451314591
double value = strtod(tok, &endp);
1451414592
1451514593
if (endp != tok) {
14516
-
14594
+
1451714595
*valObjPtr = Jim_NewDoubleObj(interp, value);
14518
-
14596
+
1451914597
scanned += endp - tok;
1452014598
}
1452114599
else {
1452214600
scanned = *tok ? 0 : -1;
1452314601
}
@@ -14542,65 +14620,65 @@
1454214620
Jim_Obj **resultVec = 0;
1454314621
int resultc;
1454414622
Jim_Obj *emptyStr = 0;
1454514623
ScanFmtStringObj *fmtObj;
1454614624
14547
-
14625
+
1454814626
JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
1454914627
1455014628
fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
14551
-
14629
+
1455214630
if (fmtObj->error != 0) {
1455314631
if (flags & JIM_ERRMSG)
1455414632
Jim_SetResultString(interp, fmtObj->error, -1);
1455514633
return 0;
1455614634
}
14557
-
14635
+
1455814636
emptyStr = Jim_NewEmptyStringObj(interp);
1455914637
Jim_IncrRefCount(emptyStr);
14560
-
14638
+
1456114639
resultList = Jim_NewListObj(interp, NULL, 0);
1456214640
if (fmtObj->maxPos > 0) {
1456314641
for (i = 0; i < fmtObj->maxPos; ++i)
1456414642
Jim_ListAppendElement(interp, resultList, emptyStr);
1456514643
JimListGetElements(interp, resultList, &resultc, &resultVec);
1456614644
}
14567
-
14645
+
1456814646
for (i = 0, pos = 0; i < fmtObj->count; ++i) {
1456914647
ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
1457014648
Jim_Obj *value = 0;
1457114649
14572
-
14650
+
1457314651
if (descr->type == 0)
1457414652
continue;
14575
-
14653
+
1457614654
if (scanned > 0)
1457714655
scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
14578
-
14656
+
1457914657
if (scanned == -1 && i == 0)
1458014658
goto eof;
14581
-
14659
+
1458214660
pos += scanned;
1458314661
14584
-
14662
+
1458514663
if (value == 0)
1458614664
value = Jim_NewEmptyStringObj(interp);
14587
-
14665
+
1458814666
if (descr->pos == -1) {
1458914667
Jim_FreeNewObj(interp, value);
1459014668
}
1459114669
else if (descr->pos == 0)
14592
-
14670
+
1459314671
Jim_ListAppendElement(interp, resultList, value);
1459414672
else if (resultVec[descr->pos - 1] == emptyStr) {
14595
-
14673
+
1459614674
Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
1459714675
Jim_IncrRefCount(value);
1459814676
resultVec[descr->pos - 1] = value;
1459914677
}
1460014678
else {
14601
-
14679
+
1460214680
Jim_FreeNewObj(interp, value);
1460314681
goto err;
1460414682
}
1460514683
}
1460614684
Jim_DecrRefCount(interp, emptyStr);
@@ -14638,15 +14716,15 @@
1463814716
{
1463914717
Jim_PrngState *prng;
1464014718
unsigned char *destByte = (unsigned char *)dest;
1464114719
unsigned int si, sj, x;
1464214720
14643
-
14721
+
1464414722
if (interp->prngState == NULL)
1464514723
JimPrngInit(interp);
1464614724
prng = interp->prngState;
14647
-
14725
+
1464814726
for (x = 0; x < len; x++) {
1464914727
prng->i = (prng->i + 1) & 0xff;
1465014728
si = prng->sbox[prng->i];
1465114729
prng->j = (prng->j + si) & 0xff;
1465214730
sj = prng->sbox[prng->j];
@@ -14660,19 +14738,19 @@
1466014738
static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
1466114739
{
1466214740
int i;
1466314741
Jim_PrngState *prng;
1466414742
14665
-
14743
+
1466614744
if (interp->prngState == NULL)
1466714745
JimPrngInit(interp);
1466814746
prng = interp->prngState;
1466914747
14670
-
14748
+
1467114749
for (i = 0; i < 256; i++)
1467214750
prng->sbox[i] = i;
14673
-
14751
+
1467414752
for (i = 0; i < seedLen; i++) {
1467514753
unsigned char t;
1467614754
1467714755
t = prng->sbox[i & 0xFF];
1467814756
prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14699,11 +14777,11 @@
1469914777
if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
1470014778
return JIM_ERR;
1470114779
}
1470214780
intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1470314781
if (!intObjPtr) {
14704
-
14782
+
1470514783
wideValue = 0;
1470614784
}
1470714785
else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
1470814786
return JIM_ERR;
1470914787
}
@@ -14713,26 +14791,26 @@
1471314791
Jim_FreeNewObj(interp, intObjPtr);
1471414792
return JIM_ERR;
1471514793
}
1471614794
}
1471714795
else {
14718
-
14796
+
1471914797
Jim_InvalidateStringRep(intObjPtr);
1472014798
JimWideValue(intObjPtr) = wideValue + increment;
1472114799
1472214800
if (argv[1]->typePtr != &variableObjType) {
14723
-
14801
+
1472414802
Jim_SetVariable(interp, argv[1], intObjPtr);
1472514803
}
1472614804
}
1472714805
Jim_SetResult(interp, intObjPtr);
1472814806
return JIM_OK;
1472914807
}
1473014808
1473114809
14732
-#define JIM_EVAL_SARGV_LEN 8
14733
-#define JIM_EVAL_SINTV_LEN 8
14810
+#define JIM_EVAL_SARGV_LEN 8
14811
+#define JIM_EVAL_SINTV_LEN 8
1473414812
1473514813
1473614814
static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1473714815
{
1473814816
int retcode;
@@ -14740,16 +14818,16 @@
1474014818
if (interp->unknown_called > 50) {
1474114819
return JIM_ERR;
1474214820
}
1474314821
1474414822
14745
-
14823
+
1474614824
if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
1474714825
return JIM_ERR;
1474814826
1474914827
interp->unknown_called++;
14750
-
14828
+
1475114829
retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
1475214830
interp->unknown_called--;
1475314831
1475414832
return retcode;
1475514833
}
@@ -14767,11 +14845,11 @@
1476714845
}
1476814846
printf("\n");
1476914847
#endif
1477014848
1477114849
if (interp->framePtr->tailcallCmd) {
14772
-
14850
+
1477314851
cmdPtr = interp->framePtr->tailcallCmd;
1477414852
interp->framePtr->tailcallCmd = NULL;
1477514853
}
1477614854
else {
1477714855
cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14786,11 +14864,11 @@
1478614864
retcode = JIM_ERR;
1478714865
goto out;
1478814866
}
1478914867
interp->evalDepth++;
1479014868
14791
-
14869
+
1479214870
Jim_SetEmptyResult(interp);
1479314871
if (cmdPtr->isproc) {
1479414872
retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
1479514873
}
1479614874
else {
@@ -14807,17 +14885,17 @@
1480714885
1480814886
int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
1480914887
{
1481014888
int i, retcode;
1481114889
14812
-
14890
+
1481314891
for (i = 0; i < objc; i++)
1481414892
Jim_IncrRefCount(objv[i]);
1481514893
1481614894
retcode = JimInvokeCommand(interp, objc, objv);
1481714895
14818
-
14896
+
1481914897
for (i = 0; i < objc; i++)
1482014898
Jim_DecrRefCount(interp, objv[i]);
1482114899
1482214900
return retcode;
1482314901
}
@@ -14835,25 +14913,25 @@
1483514913
}
1483614914
1483714915
static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
1483814916
{
1483914917
if (!interp->errorFlag) {
14840
-
14918
+
1484114919
interp->errorFlag = 1;
1484214920
Jim_IncrRefCount(script->fileNameObj);
1484314921
Jim_DecrRefCount(interp, interp->errorFileNameObj);
1484414922
interp->errorFileNameObj = script->fileNameObj;
1484514923
interp->errorLine = script->linenr;
1484614924
1484714925
JimResetStackTrace(interp);
14848
-
14926
+
1484914927
interp->addStackTrace++;
1485014928
}
1485114929
14852
-
14930
+
1485314931
if (interp->addStackTrace > 0) {
14854
-
14932
+
1485514933
1485614934
JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
1485714935
1485814936
if (Jim_Length(script->fileNameObj)) {
1485914937
interp->addStackTrace = 0;
@@ -14888,14 +14966,14 @@
1488814966
case JIM_OK:
1488914967
case JIM_RETURN:
1489014968
objPtr = interp->result;
1489114969
break;
1489214970
case JIM_BREAK:
14893
-
14971
+
1489414972
return JIM_BREAK;
1489514973
case JIM_CONTINUE:
14896
-
14974
+
1489714975
return JIM_CONTINUE;
1489814976
default:
1489914977
return JIM_ERR;
1490014978
}
1490114979
break;
@@ -14930,23 +15008,23 @@
1493015008
case JIM_OK:
1493115009
case JIM_RETURN:
1493215010
break;
1493315011
case JIM_BREAK:
1493415012
if (flags & JIM_SUBST_FLAG) {
14935
-
15013
+
1493615014
tokens = i;
1493715015
continue;
1493815016
}
14939
-
14940
-
15017
+
15018
+
1494115019
case JIM_CONTINUE:
1494215020
if (flags & JIM_SUBST_FLAG) {
1494315021
intv[i] = NULL;
1494415022
continue;
1494515023
}
14946
-
14947
-
15024
+
15025
+
1494815026
default:
1494915027
while (i--) {
1495015028
Jim_DecrRefCount(interp, intv[i]);
1495115029
}
1495215030
if (intv != sintv) {
@@ -14957,28 +15035,28 @@
1495715035
Jim_IncrRefCount(intv[i]);
1495815036
Jim_String(intv[i]);
1495915037
totlen += intv[i]->length;
1496015038
}
1496115039
14962
-
15040
+
1496315041
if (tokens == 1 && intv[0] && intv == sintv) {
1496415042
Jim_DecrRefCount(interp, intv[0]);
1496515043
return intv[0];
1496615044
}
1496715045
1496815046
objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
1496915047
1497015048
if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
1497115049
&& token[2].type == JIM_TT_VAR) {
14972
-
15050
+
1497315051
objPtr->typePtr = &interpolatedObjType;
1497415052
objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
1497515053
objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
1497615054
Jim_IncrRefCount(intv[2]);
1497715055
}
1497815056
else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
14979
-
15057
+
1498015058
JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
1498115059
}
1498215060
1498315061
1498415062
s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -14989,11 +15067,11 @@
1498915067
s += intv[i]->length;
1499015068
Jim_DecrRefCount(interp, intv[i]);
1499115069
}
1499215070
}
1499315071
objPtr->bytes[totlen] = '\0';
14994
-
15072
+
1499515073
if (intv != sintv) {
1499615074
Jim_Free(intv);
1499715075
}
1499815076
1499915077
return objPtr;
@@ -15033,11 +15111,11 @@
1503315111
1503415112
if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
1503515113
return JimEvalObjList(interp, scriptObjPtr);
1503615114
}
1503715115
15038
- Jim_IncrRefCount(scriptObjPtr);
15116
+ Jim_IncrRefCount(scriptObjPtr);
1503915117
script = JimGetScript(interp, scriptObjPtr);
1504015118
if (!JimScriptValid(interp, script)) {
1504115119
Jim_DecrRefCount(interp, scriptObjPtr);
1504215120
return JIM_ERR;
1504315121
}
@@ -15069,11 +15147,11 @@
1506915147
}
1507015148
#endif
1507115149
1507215150
script->inUse++;
1507315151
15074
-
15152
+
1507515153
prevScriptObj = interp->currentScriptObj;
1507615154
interp->currentScriptObj = scriptObjPtr;
1507715155
1507815156
interp->errorFlag = 0;
1507915157
argv = sargv;
@@ -15080,19 +15158,19 @@
1508015158
1508115159
for (i = 0; i < script->len && retcode == JIM_OK; ) {
1508215160
int argc;
1508315161
int j;
1508415162
15085
-
15163
+
1508615164
argc = token[i].objPtr->internalRep.scriptLineValue.argc;
1508715165
script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
1508815166
15089
-
15167
+
1509015168
if (argc > JIM_EVAL_SARGV_LEN)
1509115169
argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
1509215170
15093
-
15171
+
1509415172
i++;
1509515173
1509615174
for (j = 0; j < argc; j++) {
1509715175
long wordtokens = 1;
1509815176
int expand = 0;
@@ -15148,11 +15226,11 @@
1514815226
1514915227
if (!expand) {
1515015228
argv[j] = wordObjPtr;
1515115229
}
1515215230
else {
15153
-
15231
+
1515415232
int len = Jim_ListLength(interp, wordObjPtr);
1515515233
int newargc = argc + len - 1;
1515615234
int k;
1515715235
1515815236
if (len > 1) {
@@ -15161,39 +15239,39 @@
1516115239
argv = Jim_Alloc(sizeof(*argv) * newargc);
1516215240
memcpy(argv, sargv, sizeof(*argv) * j);
1516315241
}
1516415242
}
1516515243
else {
15166
-
15244
+
1516715245
argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
1516815246
}
1516915247
}
1517015248
15171
-
15249
+
1517215250
for (k = 0; k < len; k++) {
1517315251
argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
1517415252
Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
1517515253
}
1517615254
1517715255
Jim_DecrRefCount(interp, wordObjPtr);
1517815256
15179
-
15257
+
1518015258
j--;
1518115259
argc += len - 1;
1518215260
}
1518315261
}
1518415262
1518515263
if (retcode == JIM_OK && argc) {
15186
-
15264
+
1518715265
retcode = JimInvokeCommand(interp, argc, argv);
15188
-
15266
+
1518915267
if (Jim_CheckSignal(interp)) {
1519015268
retcode = JIM_SIGNAL;
1519115269
}
1519215270
}
1519315271
15194
-
15272
+
1519515273
while (j-- > 0) {
1519615274
Jim_DecrRefCount(interp, argv[j]);
1519715275
}
1519815276
1519915277
if (argv != sargv) {
@@ -15200,21 +15278,21 @@
1520015278
Jim_Free(argv);
1520115279
argv = sargv;
1520215280
}
1520315281
}
1520415282
15205
-
15283
+
1520615284
if (retcode == JIM_ERR) {
1520715285
JimAddErrorToStack(interp, script);
1520815286
}
15209
-
15287
+
1521015288
else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
15211
-
15289
+
1521215290
interp->addStackTrace = 0;
1521315291
}
1521415292
15215
-
15293
+
1521615294
interp->currentScriptObj = prevScriptObj;
1521715295
1521815296
Jim_FreeIntRep(interp, scriptObjPtr);
1521915297
scriptObjPtr->typePtr = &scriptObjType;
1522015298
Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15224,14 +15302,14 @@
1522415302
}
1522515303
1522615304
static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
1522715305
{
1522815306
int retcode;
15229
-
15307
+
1523015308
const char *varname = Jim_String(argNameObj);
1523115309
if (*varname == '&') {
15232
-
15310
+
1523315311
Jim_Obj *objPtr;
1523415312
Jim_CallFrame *savedCallFrame = interp->framePtr;
1523515313
1523615314
interp->framePtr = interp->framePtr->parent;
1523715315
objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15238,11 +15316,11 @@
1523815316
interp->framePtr = savedCallFrame;
1523915317
if (!objPtr) {
1524015318
return JIM_ERR;
1524115319
}
1524215320
15243
-
15321
+
1524415322
objPtr = Jim_NewStringObj(interp, varname + 1, -1);
1524515323
Jim_IncrRefCount(objPtr);
1524615324
retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
1524715325
Jim_DecrRefCount(interp, objPtr);
1524815326
}
@@ -15252,26 +15330,26 @@
1525215330
return retcode;
1525315331
}
1525415332
1525515333
static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
1525615334
{
15257
-
15335
+
1525815336
Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
1525915337
int i;
1526015338
1526115339
for (i = 0; i < cmd->u.proc.argListLen; i++) {
1526215340
Jim_AppendString(interp, argmsg, " ", 1);
1526315341
1526415342
if (i == cmd->u.proc.argsPos) {
1526515343
if (cmd->u.proc.arglist[i].defaultObjPtr) {
15266
-
15344
+
1526715345
Jim_AppendString(interp, argmsg, "?", 1);
1526815346
Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
1526915347
Jim_AppendString(interp, argmsg, " ...?", -1);
1527015348
}
1527115349
else {
15272
-
15350
+
1527315351
Jim_AppendString(interp, argmsg, "?arg...?", -1);
1527415352
}
1527515353
}
1527615354
else {
1527715355
if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15296,11 +15374,11 @@
1529615374
int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
1529715375
{
1529815376
Jim_CallFrame *callFramePtr;
1529915377
int retcode;
1530015378
15301
-
15379
+
1530215380
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
1530315381
callFramePtr->argv = &interp->emptyObj;
1530415382
callFramePtr->argc = 0;
1530515383
callFramePtr->procArgsObjPtr = NULL;
1530615384
callFramePtr->procBodyObjPtr = scriptObj;
@@ -15308,21 +15386,21 @@
1530815386
callFramePtr->fileNameObj = interp->emptyObj;
1530915387
callFramePtr->line = 0;
1531015388
Jim_IncrRefCount(scriptObj);
1531115389
interp->framePtr = callFramePtr;
1531215390
15313
-
15391
+
1531415392
if (interp->framePtr->level == interp->maxCallFrameDepth) {
1531515393
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
1531615394
retcode = JIM_ERR;
1531715395
}
1531815396
else {
15319
-
15397
+
1532015398
retcode = Jim_EvalObj(interp, scriptObj);
1532115399
}
1532215400
15323
-
15401
+
1532415402
interp->framePtr = interp->framePtr->parent;
1532515403
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
1532615404
1532715405
return retcode;
1532815406
}
@@ -15332,62 +15410,62 @@
1533215410
{
1533315411
Jim_CallFrame *callFramePtr;
1533415412
int i, d, retcode, optargs;
1533515413
ScriptObj *script;
1533615414
15337
-
15415
+
1533815416
if (argc - 1 < cmd->u.proc.reqArity ||
1533915417
(cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
1534015418
JimSetProcWrongArgs(interp, argv[0], cmd);
1534115419
return JIM_ERR;
1534215420
}
1534315421
1534415422
if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15345
-
15423
+
1534615424
return JIM_OK;
1534715425
}
1534815426
15349
-
15427
+
1535015428
if (interp->framePtr->level == interp->maxCallFrameDepth) {
1535115429
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
1535215430
return JIM_ERR;
1535315431
}
1535415432
15355
-
15433
+
1535615434
callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
1535715435
callFramePtr->argv = argv;
1535815436
callFramePtr->argc = argc;
1535915437
callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
1536015438
callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
1536115439
callFramePtr->staticVars = cmd->u.proc.staticVars;
1536215440
15363
-
15441
+
1536415442
script = JimGetScript(interp, interp->currentScriptObj);
1536515443
callFramePtr->fileNameObj = script->fileNameObj;
1536615444
callFramePtr->line = script->linenr;
1536715445
1536815446
Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
1536915447
Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
1537015448
interp->framePtr = callFramePtr;
1537115449
15372
-
15450
+
1537315451
optargs = (argc - 1 - cmd->u.proc.reqArity);
1537415452
15375
-
15453
+
1537615454
i = 1;
1537715455
for (d = 0; d < cmd->u.proc.argListLen; d++) {
1537815456
Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
1537915457
if (d == cmd->u.proc.argsPos) {
15380
-
15458
+
1538115459
Jim_Obj *listObjPtr;
1538215460
int argsLen = 0;
1538315461
if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
1538415462
argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
1538515463
}
1538615464
listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
1538715465
15388
-
15466
+
1538915467
if (cmd->u.proc.arglist[d].defaultObjPtr) {
1539015468
nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
1539115469
}
1539215470
retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
1539315471
if (retcode != JIM_OK) {
@@ -15396,60 +15474,56 @@
1539615474
1539715475
i += argsLen;
1539815476
continue;
1539915477
}
1540015478
15401
-
15479
+
1540215480
if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
1540315481
retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
1540415482
}
1540515483
else {
15406
-
15484
+
1540715485
retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
1540815486
}
1540915487
if (retcode != JIM_OK) {
1541015488
goto badargset;
1541115489
}
1541215490
}
1541315491
15414
-
15492
+
1541515493
retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
1541615494
1541715495
badargset:
1541815496
15419
-
15497
+
1542015498
interp->framePtr = interp->framePtr->parent;
1542115499
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15500
+
1542215501
1542315502
if (interp->framePtr->tailcallObj) {
15424
-
15425
- if (interp->framePtr->tailcall++ == 0) {
15426
-
15427
- do {
15428
- Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
15429
-
15430
- interp->framePtr->tailcallObj = NULL;
15431
-
15432
- if (retcode == JIM_EVAL) {
15433
- retcode = Jim_EvalObjList(interp, tailcallObj);
15434
- if (retcode == JIM_RETURN) {
15435
- interp->returnLevel++;
15436
- }
15437
- }
15438
- Jim_DecrRefCount(interp, tailcallObj);
15439
- } while (interp->framePtr->tailcallObj);
15440
-
15441
-
15442
- if (interp->framePtr->tailcallCmd) {
15443
- JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
15444
- interp->framePtr->tailcallCmd = NULL;
15445
- }
15446
- }
15447
- interp->framePtr->tailcall--;
15448
- }
15449
-
15450
-
15503
+ do {
15504
+ Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
15505
+
15506
+ interp->framePtr->tailcallObj = NULL;
15507
+
15508
+ if (retcode == JIM_EVAL) {
15509
+ retcode = Jim_EvalObjList(interp, tailcallObj);
15510
+ if (retcode == JIM_RETURN) {
15511
+ interp->returnLevel++;
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
+
1545115525
if (retcode == JIM_RETURN) {
1545215526
if (--interp->returnLevel <= 0) {
1545315527
retcode = interp->returnCode;
1545415528
interp->returnCode = JIM_OK;
1545515529
interp->returnLevel = 0;
@@ -15561,20 +15635,20 @@
1556115635
prevScriptObj = interp->currentScriptObj;
1556215636
interp->currentScriptObj = scriptObjPtr;
1556315637
1556415638
retcode = Jim_EvalObj(interp, scriptObjPtr);
1556515639
15566
-
15640
+
1556715641
if (retcode == JIM_RETURN) {
1556815642
if (--interp->returnLevel <= 0) {
1556915643
retcode = interp->returnCode;
1557015644
interp->returnCode = JIM_OK;
1557115645
interp->returnLevel = 0;
1557215646
}
1557315647
}
1557415648
if (retcode == JIM_ERR) {
15575
-
15649
+
1557615650
interp->addStackTrace++;
1557715651
}
1557815652
1557915653
interp->currentScriptObj = prevScriptObj;
1558015654
@@ -15600,11 +15674,11 @@
1560015674
}
1560115675
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
1560215676
if (JimParseVar(pc) == JIM_OK) {
1560315677
return;
1560415678
}
15605
-
15679
+
1560615680
pc->tstart = pc->p;
1560715681
flags |= JIM_SUBST_NOVAR;
1560815682
}
1560915683
while (pc->len) {
1561015684
if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15631,32 +15705,32 @@
1563115705
const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
1563215706
struct JimParserCtx parser;
1563315707
struct ScriptObj *script = Jim_Alloc(sizeof(*script));
1563415708
ParseTokenList tokenlist;
1563515709
15636
-
15710
+
1563715711
ScriptTokenListInit(&tokenlist);
1563815712
1563915713
JimParserInit(&parser, scriptText, scriptTextLen, 1);
1564015714
while (1) {
1564115715
JimParseSubst(&parser, flags);
1564215716
if (parser.eof) {
15643
-
15717
+
1564415718
break;
1564515719
}
1564615720
ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
1564715721
parser.tline);
1564815722
}
1564915723
15650
-
15724
+
1565115725
script->inUse = 1;
1565215726
script->substFlags = flags;
1565315727
script->fileNameObj = interp->emptyObj;
1565415728
Jim_IncrRefCount(script->fileNameObj);
1565515729
SubstObjAddTokens(interp, script, &tokenlist);
1565615730
15657
-
15731
+
1565815732
ScriptTokenListFree(&tokenlist);
1565915733
1566015734
#ifdef DEBUG_SHOW_SUBST
1566115735
{
1566215736
int i;
@@ -15667,11 +15741,11 @@
1566715741
Jim_String(script->token[i].objPtr));
1566815742
}
1566915743
}
1567015744
#endif
1567115745
15672
-
15746
+
1567315747
Jim_FreeIntRep(interp, objPtr);
1567415748
Jim_SetIntRepPtr(objPtr, script);
1567515749
objPtr->typePtr = &scriptObjType;
1567615750
return JIM_OK;
1567715751
}
@@ -15685,11 +15759,11 @@
1568515759
1568615760
int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
1568715761
{
1568815762
ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
1568915763
15690
- Jim_IncrRefCount(substObjPtr);
15764
+ Jim_IncrRefCount(substObjPtr);
1569115765
script->inUse++;
1569215766
1569315767
*resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
1569415768
1569515769
script->inUse--;
@@ -15701,11 +15775,15 @@
1570115775
}
1570215776
1570315777
void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
1570415778
{
1570515779
Jim_Obj *objPtr;
15706
- Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
15780
+ Jim_Obj *listObjPtr;
15781
+
15782
+ JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0"));
15783
+
15784
+ listObjPtr = Jim_NewListObj(interp, argv, argc);
1570715785
1570815786
if (*msg) {
1570915787
Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
1571015788
}
1571115789
Jim_IncrRefCount(listObjPtr);
@@ -15726,11 +15804,11 @@
1572615804
JimHashtableIteratorCallbackType *callback, int type)
1572715805
{
1572815806
Jim_HashEntry *he;
1572915807
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
1573015808
15731
-
15809
+
1573215810
if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
1573315811
he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
1573415812
if (he) {
1573515813
callback(interp, listObjPtr, he, type);
1573615814
}
@@ -15757,11 +15835,11 @@
1575715835
{
1575815836
Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
1575915837
Jim_Obj *objPtr;
1576015838
1576115839
if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
15762
-
15840
+
1576315841
return;
1576415842
}
1576515843
1576615844
objPtr = Jim_NewStringObj(interp, he->key, -1);
1576715845
Jim_IncrRefCount(objPtr);
@@ -15817,11 +15895,11 @@
1581715895
1581815896
targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
1581915897
if (targetCallFrame == NULL) {
1582015898
return JIM_ERR;
1582115899
}
15822
-
15900
+
1582315901
if (targetCallFrame == interp->topFramePtr) {
1582415902
Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
1582515903
return JIM_ERR;
1582615904
}
1582715905
if (info_level_cmd) {
@@ -16004,11 +16082,11 @@
1600416082
if (!objPtr)
1600516083
return JIM_ERR;
1600616084
Jim_SetResult(interp, objPtr);
1600716085
return JIM_OK;
1600816086
}
16009
-
16087
+
1601016088
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
1601116089
return JIM_ERR;
1601216090
Jim_SetResult(interp, argv[2]);
1601316091
return JIM_OK;
1601416092
}
@@ -16047,11 +16125,11 @@
1604716125
if (argc != 3) {
1604816126
Jim_WrongNumArgs(interp, 1, argv, "condition body");
1604916127
return JIM_ERR;
1605016128
}
1605116129
16052
-
16130
+
1605316131
while (1) {
1605416132
int boolean, retval;
1605516133
1605616134
if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
1605716135
return retval;
@@ -16087,11 +16165,11 @@
1608716165
if (argc != 5) {
1608816166
Jim_WrongNumArgs(interp, 1, argv, "start test next body");
1608916167
return JIM_ERR;
1609016168
}
1609116169
16092
-
16170
+
1609316171
if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
1609416172
return retval;
1609516173
}
1609616174
1609716175
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16103,19 +16181,19 @@
1610316181
ExprByteCode *expr;
1610416182
jim_wide stop, currentVal;
1610516183
Jim_Obj *objPtr;
1610616184
int cmpOffset;
1610716185
16108
-
16186
+
1610916187
expr = JimGetExpression(interp, argv[2]);
1611016188
incrScript = JimGetScript(interp, argv[3]);
1611116189
16112
-
16190
+
1611316191
if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
1611416192
goto evalstart;
1611516193
}
16116
-
16194
+
1611716195
if (incrScript->token[1].type != JIM_TT_ESC ||
1611816196
expr->token[0].type != JIM_TT_VAR ||
1611916197
(expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
1612016198
goto evalstart;
1612116199
}
@@ -16128,48 +16206,48 @@
1612816206
}
1612916207
else {
1613016208
goto evalstart;
1613116209
}
1613216210
16133
-
16211
+
1613416212
if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
1613516213
goto evalstart;
1613616214
}
1613716215
16138
-
16216
+
1613916217
if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
1614016218
goto evalstart;
1614116219
}
1614216220
16143
-
16221
+
1614416222
if (expr->token[1].type == JIM_TT_EXPR_INT) {
1614516223
if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
1614616224
goto evalstart;
1614716225
}
1614816226
}
1614916227
else {
1615016228
stopVarNamePtr = expr->token[1].objPtr;
1615116229
Jim_IncrRefCount(stopVarNamePtr);
16152
-
16230
+
1615316231
stop = 0;
1615416232
}
1615516233
16156
-
16234
+
1615716235
varNamePtr = expr->token[0].objPtr;
1615816236
Jim_IncrRefCount(varNamePtr);
1615916237
1616016238
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
1616116239
if (objPtr == NULL || Jim_GetWide(interp, objPtr, &currentVal) != JIM_OK) {
1616216240
goto testcond;
1616316241
}
1616416242
16165
-
16243
+
1616616244
while (retval == JIM_OK) {
16167
-
16168
-
1616916245
16170
-
16246
+
16247
+
16248
+
1617116249
if (stopVarNamePtr) {
1617216250
objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
1617316251
if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
1617416252
goto testcond;
1617516253
}
@@ -16177,18 +16255,18 @@
1617716255
1617816256
if (currentVal >= stop + cmpOffset) {
1617916257
break;
1618016258
}
1618116259
16182
-
16260
+
1618316261
retval = Jim_EvalObj(interp, argv[4]);
1618416262
if (retval == JIM_OK || retval == JIM_CONTINUE) {
1618516263
retval = JIM_OK;
1618616264
1618716265
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
1618816266
16189
-
16267
+
1619016268
if (objPtr == NULL) {
1619116269
retval = JIM_ERR;
1619216270
goto out;
1619316271
}
1619416272
if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16208,25 +16286,25 @@
1620816286
}
1620916287
evalstart:
1621016288
#endif
1621116289
1621216290
while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
16213
-
16291
+
1621416292
retval = Jim_EvalObj(interp, argv[4]);
1621516293
1621616294
if (retval == JIM_OK || retval == JIM_CONTINUE) {
16217
-
16218
- evalnext:
16295
+
16296
+JIM_IF_OPTIM(evalnext:)
1621916297
retval = Jim_EvalObj(interp, argv[3]);
1622016298
if (retval == JIM_OK || retval == JIM_CONTINUE) {
16221
-
16222
- testcond:
16299
+
16300
+JIM_IF_OPTIM(testcond:)
1622316301
retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
1622416302
}
1622516303
}
1622616304
}
16227
- out:
16305
+JIM_IF_OPTIM(out:)
1622816306
if (stopVarNamePtr) {
1622916307
Jim_DecrRefCount(interp, stopVarNamePtr);
1623016308
}
1623116309
if (varNamePtr) {
1623216310
Jim_DecrRefCount(interp, varNamePtr);
@@ -16268,11 +16346,11 @@
1626816346
if (retval == JIM_OK || retval == JIM_CONTINUE) {
1626916347
Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
1627016348
1627116349
retval = JIM_OK;
1627216350
16273
-
16351
+
1627416352
i += incr;
1627516353
1627616354
if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
1627716355
if (argv[1]->typePtr != &variableObjType) {
1627816356
if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16333,21 +16411,21 @@
1633316411
1633416412
static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
1633516413
{
1633616414
int result = JIM_OK;
1633716415
int i, numargs;
16338
- Jim_ListIter twoiters[2];
16416
+ Jim_ListIter twoiters[2];
1633916417
Jim_ListIter *iters;
1634016418
Jim_Obj *script;
1634116419
Jim_Obj *resultObj;
1634216420
1634316421
if (argc < 4 || argc % 2 != 0) {
1634416422
Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
1634516423
return JIM_ERR;
1634616424
}
16347
- script = argv[argc - 1];
16348
- numargs = (argc - 1 - 1);
16425
+ script = argv[argc - 1];
16426
+ numargs = (argc - 1 - 1);
1634916427
1635016428
if (numargs == 2) {
1635116429
iters = twoiters;
1635216430
}
1635316431
else {
@@ -16371,34 +16449,34 @@
1637116449
resultObj = interp->emptyObj;
1637216450
}
1637316451
Jim_IncrRefCount(resultObj);
1637416452
1637516453
while (1) {
16376
-
16454
+
1637716455
for (i = 0; i < numargs; i += 2) {
1637816456
if (!JimListIterDone(interp, &iters[i + 1])) {
1637916457
break;
1638016458
}
1638116459
}
1638216460
if (i == numargs) {
16383
-
16461
+
1638416462
break;
1638516463
}
1638616464
16387
-
16465
+
1638816466
for (i = 0; i < numargs; i += 2) {
1638916467
Jim_Obj *varName;
1639016468
16391
-
16469
+
1639216470
JimListIterInit(&iters[i], argv[i + 1]);
1639316471
while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
1639416472
Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
1639516473
if (!valObj) {
16396
-
16474
+
1639716475
valObj = interp->emptyObj;
1639816476
}
16399
-
16477
+
1640016478
Jim_IncrRefCount(valObj);
1640116479
result = Jim_SetVariable(interp, varName, valObj);
1640216480
Jim_DecrRefCount(interp, valObj);
1640316481
if (result != JIM_OK) {
1640416482
goto err;
@@ -16480,41 +16558,41 @@
1648016558
{
1648116559
int boolean, retval, current = 1, falsebody = 0;
1648216560
1648316561
if (argc >= 3) {
1648416562
while (1) {
16485
-
16563
+
1648616564
if (current >= argc)
1648716565
goto err;
1648816566
if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
1648916567
!= JIM_OK)
1649016568
return retval;
16491
-
16569
+
1649216570
if (current >= argc)
1649316571
goto err;
1649416572
if (Jim_CompareStringImmediate(interp, argv[current], "then"))
1649516573
current++;
16496
-
16574
+
1649716575
if (current >= argc)
1649816576
goto err;
1649916577
if (boolean)
1650016578
return Jim_EvalObj(interp, argv[current]);
16501
-
16579
+
1650216580
if (++current >= argc) {
1650316581
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
1650416582
return JIM_OK;
1650516583
}
1650616584
falsebody = current++;
1650716585
if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
16508
-
16586
+
1650916587
if (current != argc - 1)
1651016588
goto err;
1651116589
return Jim_EvalObj(interp, argv[current]);
1651216590
}
1651316591
else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
1651416592
continue;
16515
-
16593
+
1651616594
else if (falsebody != argc - 1)
1651716595
goto err;
1651816596
return Jim_EvalObj(interp, argv[falsebody]);
1651916597
}
1652016598
return JIM_OK;
@@ -16622,21 +16700,21 @@
1662216700
if (Jim_StringMatchObj(interp, patObj, strObj, 0))
1662316701
script = caseList[i + 1];
1662416702
break;
1662516703
case SWITCH_RE:
1662616704
command = Jim_NewStringObj(interp, "regexp", -1);
16627
-
16705
+
1662816706
case SWITCH_CMD:{
1662916707
int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
1663016708
1663116709
if (argc - opt == 1) {
1663216710
Jim_Obj **vector;
1663316711
1663416712
JimListGetElements(interp, argv[opt], &patCount, &vector);
1663516713
caseList = vector;
1663616714
}
16637
-
16715
+
1663816716
if (rc < 0) {
1663916717
return -rc;
1664016718
}
1664116719
if (rc)
1664216720
script = caseList[i + 1];
@@ -16770,11 +16848,11 @@
1677016848
case OPT_COMMAND:
1677116849
if (i >= argc - 2) {
1677216850
goto wrongargs;
1677316851
}
1677416852
commandObj = argv[++i];
16775
-
16853
+
1677616854
case OPT_EXACT:
1677716855
case OPT_GLOB:
1677816856
case OPT_REGEXP:
1677916857
opt_match = option;
1678016858
break;
@@ -16818,17 +16896,17 @@
1681816896
goto done;
1681916897
}
1682016898
break;
1682116899
}
1682216900
16823
-
16901
+
1682416902
if (!eq && opt_bool && opt_not && !opt_all) {
1682516903
continue;
1682616904
}
1682716905
1682816906
if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
16829
-
16907
+
1683016908
Jim_Obj *resultObj;
1683116909
1683216910
if (opt_bool) {
1683316911
resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
1683416912
}
@@ -16851,11 +16929,11 @@
1685116929
1685216930
if (opt_all) {
1685316931
Jim_SetResult(interp, listObjPtr);
1685416932
}
1685516933
else {
16856
-
16934
+
1685716935
if (opt_bool) {
1685816936
Jim_SetResultBool(interp, opt_not);
1685916937
}
1686016938
else if (!opt_inline) {
1686116939
Jim_SetResultInt(interp, -1);
@@ -16871,32 +16949,31 @@
1687116949
1687216950
1687316951
static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1687416952
{
1687516953
Jim_Obj *listObjPtr;
16876
- int shared, i;
16954
+ int new_obj = 0;
16955
+ int i;
1687716956
1687816957
if (argc < 2) {
1687916958
Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
1688016959
return JIM_ERR;
1688116960
}
1688216961
listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1688316962
if (!listObjPtr) {
16884
-
16963
+
1688516964
listObjPtr = Jim_NewListObj(interp, NULL, 0);
16886
- if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) {
16887
- Jim_FreeNewObj(interp, listObjPtr);
16888
- return JIM_ERR;
16889
- }
16965
+ new_obj = 1;
1689016966
}
16891
- shared = Jim_IsShared(listObjPtr);
16892
- if (shared)
16967
+ else if (Jim_IsShared(listObjPtr)) {
1689316968
listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
16969
+ new_obj = 1;
16970
+ }
1689416971
for (i = 2; i < argc; i++)
1689516972
Jim_ListAppendElement(interp, listObjPtr, argv[i]);
1689616973
if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) {
16897
- if (shared)
16974
+ if (new_obj)
1689816975
Jim_FreeNewObj(interp, listObjPtr);
1689916976
return JIM_ERR;
1690016977
}
1690116978
Jim_SetResult(interp, listObjPtr);
1690216979
return JIM_OK;
@@ -16954,31 +17031,31 @@
1695417031
first = JimRelToAbsIndex(len, first);
1695517032
last = JimRelToAbsIndex(len, last);
1695617033
JimRelToAbsRange(len, &first, &last, &rangeLen);
1695717034
1695817035
16959
-
17036
+
1696017037
if (first < len) {
16961
-
17038
+
1696217039
}
1696317040
else if (len == 0) {
16964
-
17041
+
1696517042
first = 0;
1696617043
}
1696717044
else {
1696817045
Jim_SetResultString(interp, "list doesn't contain element ", -1);
1696917046
Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
1697017047
return JIM_ERR;
1697117048
}
1697217049
16973
-
17050
+
1697417051
newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
1697517052
16976
-
17053
+
1697717054
ListInsertElements(newListObj, -1, argc - 4, argv + 4);
1697817055
16979
-
17056
+
1698017057
ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
1698117058
1698217059
Jim_SetResult(interp, newListObj);
1698317060
return JIM_OK;
1698417061
}
@@ -16989,11 +17066,11 @@
1698917066
if (argc < 3) {
1699017067
Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
1699117068
return JIM_ERR;
1699217069
}
1699317070
else if (argc == 3) {
16994
-
17071
+
1699517072
if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
1699617073
return JIM_ERR;
1699717074
Jim_SetResult(interp, argv[2]);
1699817075
return JIM_OK;
1699917076
}
@@ -17101,26 +17178,26 @@
1710117178
stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
1710217179
if (!stringObjPtr)
1710317180
return JIM_ERR;
1710417181
}
1710517182
else {
17106
- int freeobj = 0;
17183
+ int new_obj = 0;
1710717184
stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
1710817185
if (!stringObjPtr) {
17109
-
17186
+
1711017187
stringObjPtr = Jim_NewEmptyStringObj(interp);
17111
- freeobj = 1;
17188
+ new_obj = 1;
1711217189
}
1711317190
else if (Jim_IsShared(stringObjPtr)) {
17114
- freeobj = 1;
17191
+ new_obj = 1;
1711517192
stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr);
1711617193
}
1711717194
for (i = 2; i < argc; i++) {
1711817195
Jim_AppendObj(interp, stringObjPtr, argv[i]);
1711917196
}
1712017197
if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) {
17121
- if (freeobj) {
17198
+ if (new_obj) {
1712217199
Jim_FreeNewObj(interp, stringObjPtr);
1712317200
}
1712417201
return JIM_ERR;
1712517202
}
1712617203
}
@@ -17153,11 +17230,11 @@
1715317230
else {
1715417231
rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
1715517232
}
1715617233
1715717234
if (rc == JIM_ERR) {
17158
-
17235
+
1715917236
interp->addStackTrace++;
1716017237
}
1716117238
return rc;
1716217239
}
1716317240
@@ -17165,17 +17242,16 @@
1716517242
static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1716617243
{
1716717244
if (argc >= 2) {
1716817245
int retcode;
1716917246
Jim_CallFrame *savedCallFrame, *targetCallFrame;
17170
- int savedTailcall;
1717117247
const char *str;
1717217248
17173
-
17249
+
1717417250
savedCallFrame = interp->framePtr;
1717517251
17176
-
17252
+
1717717253
str = Jim_String(argv[1]);
1717817254
if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
1717917255
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
1718017256
argc--;
1718117257
argv++;
@@ -17188,22 +17264,18 @@
1718817264
}
1718917265
if (argc < 2) {
1719017266
Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
1719117267
return JIM_ERR;
1719217268
}
17193
-
17269
+
1719417270
interp->framePtr = targetCallFrame;
17195
-
17196
- savedTailcall = interp->framePtr->tailcall;
17197
- interp->framePtr->tailcall = 0;
1719817271
if (argc == 2) {
1719917272
retcode = Jim_EvalObj(interp, argv[1]);
1720017273
}
1720117274
else {
1720217275
retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
1720317276
}
17204
- interp->framePtr->tailcall = savedTailcall;
1720517277
interp->framePtr = savedCallFrame;
1720617278
return retcode;
1720717279
}
1720817280
else {
1720917281
Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?");
@@ -17294,15 +17366,15 @@
1729417366
if (i != argc - 1 && i != argc) {
1729517367
Jim_WrongNumArgs(interp, 1, argv,
1729617368
"?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
1729717369
}
1729817370
17299
-
17371
+
1730017372
if (stackTraceObj && returnCode == JIM_ERR) {
1730117373
JimSetStackTrace(interp, stackTraceObj);
1730217374
}
17303
-
17375
+
1730417376
if (errorCodeObj && returnCode == JIM_ERR) {
1730517377
Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
1730617378
}
1730717379
interp->returnCode = returnCode;
1730817380
interp->returnLevel = level;
@@ -17319,31 +17391,31 @@
1731917391
if (interp->framePtr->level == 0) {
1732017392
Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
1732117393
return JIM_ERR;
1732217394
}
1732317395
else if (argc >= 2) {
17324
-
17396
+
1732517397
Jim_CallFrame *cf = interp->framePtr->parent;
1732617398
1732717399
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
1732817400
if (cmdPtr == NULL) {
1732917401
return JIM_ERR;
1733017402
}
1733117403
1733217404
JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
1733317405
17334
-
17406
+
1733517407
JimIncrCmdRefCount(cmdPtr);
1733617408
cf->tailcallCmd = cmdPtr;
1733717409
17338
-
17410
+
1733917411
JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
1734017412
1734117413
cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
1734217414
Jim_IncrRefCount(cf->tailcallObj);
1734317415
17344
-
17416
+
1734517417
return JIM_EVAL;
1734617418
}
1734717419
return JIM_OK;
1734817420
}
1734917421
@@ -17350,11 +17422,11 @@
1735017422
static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1735117423
{
1735217424
Jim_Obj *cmdList;
1735317425
Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
1735417426
17355
-
17427
+
1735617428
cmdList = Jim_DuplicateObj(interp, prefixListObj);
1735717429
Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
1735817430
1735917431
return JimEvalObjList(interp, cmdList);
1736017432
}
@@ -17408,22 +17480,22 @@
1740817480
else {
1740917481
cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
1741017482
}
1741117483
1741217484
if (cmd) {
17413
-
17485
+
1741417486
Jim_Obj *qualifiedCmdNameObj;
1741517487
const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
1741617488
1741717489
JimCreateCommand(interp, cmdname, cmd);
1741817490
17419
-
17491
+
1742017492
JimUpdateProcNamespace(interp, cmd, cmdname);
1742117493
1742217494
JimFreeQualifiedName(interp, qualifiedCmdNameObj);
1742317495
17424
-
17496
+
1742517497
Jim_SetResult(interp, argv[1]);
1742617498
return JIM_OK;
1742717499
}
1742817500
return JIM_ERR;
1742917501
}
@@ -17436,17 +17508,17 @@
1743617508
if (argc < 2) {
1743717509
Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
1743817510
return JIM_ERR;
1743917511
}
1744017512
17441
-
17513
+
1744217514
interp->local++;
1744317515
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
1744417516
interp->local--;
1744517517
1744617518
17447
-
17519
+
1744817520
if (retcode == 0) {
1744917521
Jim_Obj *cmdNameObj = Jim_GetResult(interp);
1745017522
1745117523
if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
1745217524
return JIM_ERR;
@@ -17475,18 +17547,18 @@
1747517547
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
1747617548
if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
1747717549
Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
1747817550
return JIM_ERR;
1747917551
}
17480
-
17552
+
1748117553
cmdPtr->u.proc.upcall++;
1748217554
JimIncrCmdRefCount(cmdPtr);
1748317555
17484
-
17556
+
1748517557
retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
1748617558
17487
-
17559
+
1748817560
cmdPtr->u.proc.upcall--;
1748917561
JimDecrCmdRefCount(interp, cmdPtr);
1749017562
1749117563
return retcode;
1749217564
}
@@ -17513,11 +17585,11 @@
1751317585
return JIM_ERR;
1751417586
}
1751517587
1751617588
if (len == 3) {
1751717589
#ifdef jim_ext_namespace
17518
-
17590
+
1751917591
nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
1752017592
#else
1752117593
Jim_SetResultString(interp, "namespaces not enabled", -1);
1752217594
return JIM_ERR;
1752317595
#endif
@@ -17526,11 +17598,11 @@
1752617598
bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
1752717599
1752817600
cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
1752917601
1753017602
if (cmd) {
17531
-
17603
+
1753217604
nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
1753317605
nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
1753417606
Jim_IncrRefCount(nargv[0]);
1753517607
memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
1753617608
ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17556,11 +17628,11 @@
1755617628
static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1755717629
{
1755817630
int i;
1755917631
Jim_CallFrame *targetCallFrame;
1756017632
17561
-
17633
+
1756217634
if (argc > 3 && (argc % 2 == 0)) {
1756317635
targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
1756417636
argc--;
1756517637
argv++;
1756617638
}
@@ -17569,17 +17641,17 @@
1756917641
}
1757017642
if (targetCallFrame == NULL) {
1757117643
return JIM_ERR;
1757217644
}
1757317645
17574
-
17646
+
1757517647
if (argc < 3) {
1757617648
Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
1757717649
return JIM_ERR;
1757817650
}
1757917651
17580
-
17652
+
1758117653
for (i = 1; i < argc; i += 2) {
1758217654
if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
1758317655
return JIM_ERR;
1758417656
}
1758517657
return JIM_OK;
@@ -17592,15 +17664,15 @@
1759217664
1759317665
if (argc < 2) {
1759417666
Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
1759517667
return JIM_ERR;
1759617668
}
17597
-
17669
+
1759817670
if (interp->framePtr->level == 0)
17599
- return JIM_OK;
17671
+ return JIM_OK;
1760017672
for (i = 1; i < argc; i++) {
17601
-
17673
+
1760217674
const char *name = Jim_String(argv[i]);
1760317675
if (name[0] != ':' || name[1] != ':') {
1760417676
if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
1760517677
return JIM_ERR;
1760617678
}
@@ -17623,21 +17695,21 @@
1762317695
}
1762417696
1762517697
str = Jim_String(objPtr);
1762617698
strLen = Jim_Utf8Length(interp, objPtr);
1762717699
17628
-
17700
+
1762917701
resultObjPtr = Jim_NewStringObj(interp, "", 0);
1763017702
while (strLen) {
1763117703
for (i = 0; i < numMaps; i += 2) {
17632
- Jim_Obj *objPtr;
17704
+ Jim_Obj *eachObjPtr;
1763317705
const char *k;
1763417706
int kl;
1763517707
17636
- objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17637
- k = Jim_String(objPtr);
17638
- kl = Jim_Utf8Length(interp, objPtr);
17708
+ eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17709
+ k = Jim_String(eachObjPtr);
17710
+ kl = Jim_Utf8Length(interp, eachObjPtr);
1763917711
1764017712
if (strLen >= kl && kl) {
1764117713
int rc;
1764217714
rc = JimStringCompareLen(str, k, kl, nocase);
1764317715
if (rc == 0) {
@@ -17650,11 +17722,11 @@
1765017722
strLen -= kl;
1765117723
break;
1765217724
}
1765317725
}
1765417726
}
17655
- if (i == numMaps) {
17727
+ if (i == numMaps) {
1765617728
int c;
1765717729
if (noMatchStart == NULL)
1765817730
noMatchStart = str;
1765917731
str += utf8_tounicode(str, &c);
1766017732
strLen--;
@@ -17715,11 +17787,11 @@
1771517787
return JIM_OK;
1771617788
1771717789
case OPT_CAT:{
1771817790
Jim_Obj *objPtr;
1771917791
if (argc == 3) {
17720
-
17792
+
1772117793
objPtr = argv[2];
1772217794
}
1772317795
else {
1772417796
int i;
1772517797
@@ -17734,11 +17806,11 @@
1773417806
}
1773517807
1773617808
case OPT_COMPARE:
1773717809
case OPT_EQUAL:
1773817810
{
17739
-
17811
+
1774017812
long opt_length = -1;
1774117813
int n = argc - 4;
1774217814
int i = 2;
1774317815
while (n > 0) {
1774417816
int subopt;
@@ -17747,16 +17819,16 @@
1774717819
badcompareargs:
1774817820
Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
1774917821
return JIM_ERR;
1775017822
}
1775117823
if (subopt == 0) {
17752
-
17824
+
1775317825
opt_case = 0;
1775417826
n--;
1775517827
}
1775617828
else {
17757
-
17829
+
1775817830
if (n < 2) {
1775917831
goto badcompareargs;
1776017832
}
1776117833
if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
1776217834
return JIM_ERR;
@@ -17767,11 +17839,11 @@
1776717839
if (n) {
1776817840
goto badcompareargs;
1776917841
}
1777017842
argv += argc - 2;
1777117843
if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17772
-
17844
+
1777317845
Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
1777417846
}
1777517847
else {
1777617848
if (opt_length >= 0) {
1777717849
n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -17881,11 +17953,10 @@
1788117953
}
1788217954
1788317955
case OPT_REVERSE:{
1788417956
char *buf, *p;
1788517957
const char *str;
17886
- int len;
1788717958
int i;
1788817959
1788917960
if (argc != 3) {
1789017961
Jim_WrongNumArgs(interp, 2, argv, "string");
1789117962
return JIM_ERR;
@@ -17925,11 +17996,11 @@
1792517996
}
1792617997
if (idx < 0 || idx >= len || str == NULL) {
1792717998
Jim_SetResultString(interp, "", 0);
1792817999
}
1792918000
else if (len == Jim_Length(argv[2])) {
17930
-
18001
+
1793118002
Jim_SetResultString(interp, str + idx, 1);
1793218003
}
1793318004
else {
1793418005
int c;
1793518006
int i = utf8_index(str, idx);
@@ -18079,11 +18150,11 @@
1807918150
{
1808018151
int exitCode = 0;
1808118152
int i;
1808218153
int sig = 0;
1808318154
18084
-
18155
+
1808518156
jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
1808618157
static const int max_ignore_code = sizeof(ignore_mask) * 8;
1808718158
1808818159
Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
1808918160
@@ -18090,11 +18161,11 @@
1809018161
for (i = 1; i < argc - 1; i++) {
1809118162
const char *arg = Jim_String(argv[i]);
1809218163
jim_wide option;
1809318164
int ignore;
1809418165
18095
-
18166
+
1809618167
if (strcmp(arg, "--") == 0) {
1809718168
i++;
1809818169
break;
1809918170
}
1810018171
if (*arg != '-') {
@@ -18119,14 +18190,14 @@
1811918190
if (option < 0) {
1812018191
goto wrongargs;
1812118192
}
1812218193
1812318194
if (ignore) {
18124
- ignore_mask |= (1 << option);
18195
+ ignore_mask |= ((jim_wide)1 << option);
1812518196
}
1812618197
else {
18127
- ignore_mask &= ~(1 << option);
18198
+ ignore_mask &= (~((jim_wide)1 << option));
1812818199
}
1812918200
}
1813018201
1813118202
argc -= i;
1813218203
if (argc < 1 || argc > 3) {
@@ -18141,28 +18212,28 @@
1814118212
sig++;
1814218213
}
1814318214
1814418215
interp->signal_level += sig;
1814518216
if (Jim_CheckSignal(interp)) {
18146
-
18217
+
1814718218
exitCode = JIM_SIGNAL;
1814818219
}
1814918220
else {
1815018221
exitCode = Jim_EvalObj(interp, argv[0]);
18151
-
18222
+
1815218223
interp->errorFlag = 0;
1815318224
}
1815418225
interp->signal_level -= sig;
1815518226
18156
-
18227
+
1815718228
if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
18158
-
18229
+
1815918230
return exitCode;
1816018231
}
1816118232
1816218233
if (sig && exitCode == JIM_SIGNAL) {
18163
-
18234
+
1816418235
if (interp->signal_set_result) {
1816518236
interp->signal_set_result(interp, interp->sigmask);
1816618237
}
1816718238
else {
1816818239
Jim_SetResultInt(interp, interp->sigmask);
@@ -18201,125 +18272,10 @@
1820118272
}
1820218273
Jim_SetResultInt(interp, exitCode);
1820318274
return JIM_OK;
1820418275
}
1820518276
18206
-#ifdef JIM_REFERENCES
18207
-
18208
-
18209
-static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18210
-{
18211
- if (argc != 3 && argc != 4) {
18212
- Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?");
18213
- return JIM_ERR;
18214
- }
18215
- if (argc == 3) {
18216
- Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL));
18217
- }
18218
- else {
18219
- Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3]));
18220
- }
18221
- return JIM_OK;
18222
-}
18223
-
18224
-
18225
-static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18226
-{
18227
- Jim_Reference *refPtr;
18228
-
18229
- if (argc != 2) {
18230
- Jim_WrongNumArgs(interp, 1, argv, "reference");
18231
- return JIM_ERR;
18232
- }
18233
- if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18234
- return JIM_ERR;
18235
- Jim_SetResult(interp, refPtr->objPtr);
18236
- return JIM_OK;
18237
-}
18238
-
18239
-
18240
-static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18241
-{
18242
- Jim_Reference *refPtr;
18243
-
18244
- if (argc != 3) {
18245
- Jim_WrongNumArgs(interp, 1, argv, "reference newValue");
18246
- return JIM_ERR;
18247
- }
18248
- if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18249
- return JIM_ERR;
18250
- Jim_IncrRefCount(argv[2]);
18251
- Jim_DecrRefCount(interp, refPtr->objPtr);
18252
- refPtr->objPtr = argv[2];
18253
- Jim_SetResult(interp, argv[2]);
18254
- return JIM_OK;
18255
-}
18256
-
18257
-
18258
-static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18259
-{
18260
- if (argc != 1) {
18261
- Jim_WrongNumArgs(interp, 1, argv, "");
18262
- return JIM_ERR;
18263
- }
18264
- Jim_SetResultInt(interp, Jim_Collect(interp));
18265
-
18266
-
18267
- while (interp->freeList) {
18268
- Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr;
18269
- Jim_Free(interp->freeList);
18270
- interp->freeList = nextObjPtr;
18271
- }
18272
-
18273
- return JIM_OK;
18274
-}
18275
-
18276
-
18277
-static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18278
-{
18279
- if (argc != 2 && argc != 3) {
18280
- Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?");
18281
- return JIM_ERR;
18282
- }
18283
- if (argc == 2) {
18284
- Jim_Obj *cmdNamePtr;
18285
-
18286
- if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK)
18287
- return JIM_ERR;
18288
- if (cmdNamePtr != NULL)
18289
- Jim_SetResult(interp, cmdNamePtr);
18290
- }
18291
- else {
18292
- if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK)
18293
- return JIM_ERR;
18294
- Jim_SetResult(interp, argv[2]);
18295
- }
18296
- return JIM_OK;
18297
-}
18298
-
18299
-
18300
-static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18301
-{
18302
- Jim_Obj *listObjPtr;
18303
- Jim_HashTableIterator htiter;
18304
- Jim_HashEntry *he;
18305
-
18306
- listObjPtr = Jim_NewListObj(interp, NULL, 0);
18307
-
18308
- JimInitHashTableIterator(&interp->references, &htiter);
18309
- while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18310
- char buf[JIM_REFERENCE_SPACE + 1];
18311
- Jim_Reference *refPtr = Jim_GetHashEntryVal(he);
18312
- const unsigned long *refId = he->key;
18313
-
18314
- JimFormatReference(buf, refPtr, *refId);
18315
- Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
18316
- }
18317
- Jim_SetResult(interp, listObjPtr);
18318
- return JIM_OK;
18319
-}
18320
-#endif
1832118277
1832218278
1832318279
static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1832418280
{
1832518281
if (argc != 3) {
@@ -18350,11 +18306,11 @@
1835018306
JimDictMatchCallbackType *callback, int type)
1835118307
{
1835218308
Jim_HashEntry *he;
1835318309
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
1835418310
18355
-
18311
+
1835618312
Jim_HashTableIterator htiter;
1835718313
JimInitHashTableIterator(ht, &htiter);
1835818314
while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
1835918315
if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
1836018316
callback(interp, listObjPtr, he, type);
@@ -18400,11 +18356,11 @@
1840018356
return JIM_ERR;
1840118357
}
1840218358
1840318359
ht = (Jim_HashTable *)objPtr->internalRep.ptr;
1840418360
18405
-
18361
+
1840618362
printf("%d entries in table, %d buckets\n", ht->used, ht->size);
1840718363
1840818364
for (i = 0; i < ht->size; i++) {
1840918365
Jim_HashEntry *he = ht->table[i];
1841018366
@@ -18524,16 +18480,16 @@
1852418480
return JIM_OK;
1852518481
}
1852618482
if (Jim_DictSize(interp, argv[2]) < 0) {
1852718483
return JIM_ERR;
1852818484
}
18529
-
18485
+
1853018486
break;
1853118487
1853218488
case OPT_UPDATE:
1853318489
if (argc < 6 || argc % 2) {
18534
-
18490
+
1853518491
argc = 2;
1853618492
}
1853718493
break;
1853818494
1853918495
case OPT_CREATE:
@@ -18550,11 +18506,11 @@
1855018506
Jim_WrongNumArgs(interp, 2, argv, "dictionary");
1855118507
return JIM_ERR;
1855218508
}
1855318509
return Jim_DictInfo(interp, argv[2]);
1855418510
}
18555
-
18511
+
1855618512
return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
1855718513
}
1855818514
1855918515
1856018516
static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18620,11 +18576,11 @@
1862018576
1862118577
#ifdef jim_ext_namespace
1862218578
int nons = 0;
1862318579
1862418580
if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18625
-
18581
+
1862618582
argc--;
1862718583
argv++;
1862818584
nons = 1;
1862918585
}
1863018586
#endif
@@ -18636,11 +18592,11 @@
1863618592
if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
1863718593
!= JIM_OK) {
1863818594
return JIM_ERR;
1863918595
}
1864018596
18641
-
18597
+
1864218598
switch (cmd) {
1864318599
case INFO_EXISTS:
1864418600
if (argc != 3) {
1864518601
Jim_WrongNumArgs(interp, 2, argv, "varName");
1864618602
return JIM_ERR;
@@ -18665,19 +18621,21 @@
1866518621
Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
1866618622
return JIM_OK;
1866718623
}
1866818624
1866918625
case INFO_CHANNELS:
18670
- mode++;
18626
+ mode++;
1867118627
#ifndef jim_ext_aio
1867218628
Jim_SetResultString(interp, "aio not enabled", -1);
1867318629
return JIM_ERR;
1867418630
#endif
18631
+
1867518632
case INFO_PROCS:
18676
- mode++;
18633
+ mode++;
18634
+
1867718635
case INFO_COMMANDS:
18678
-
18636
+
1867918637
if (argc != 2 && argc != 3) {
1868018638
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
1868118639
return JIM_ERR;
1868218640
}
1868318641
#ifdef jim_ext_namespace
@@ -18689,15 +18647,17 @@
1868918647
#endif
1869018648
Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
1869118649
break;
1869218650
1869318651
case INFO_VARS:
18694
- mode++;
18652
+ mode++;
18653
+
1869518654
case INFO_LOCALS:
18696
- mode++;
18655
+ mode++;
18656
+
1869718657
case INFO_GLOBALS:
18698
-
18658
+
1869918659
if (argc != 2 && argc != 3) {
1870018660
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
1870118661
return JIM_ERR;
1870218662
}
1870318663
#ifdef jim_ext_namespace
@@ -18803,13 +18763,12 @@
1880318763
case INFO_ARGS:
1880418764
Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
1880518765
break;
1880618766
case INFO_STATICS:
1880718767
if (cmdPtr->u.proc.staticVars) {
18808
- int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
1880918768
Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
18810
- NULL, JimVariablesMatch, mode));
18769
+ NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES));
1881118770
}
1881218771
break;
1881318772
}
1881418773
break;
1881518774
}
@@ -18827,27 +18786,25 @@
1882718786
if (argc != 3 && argc != 4) {
1882818787
Jim_WrongNumArgs(interp, 2, argv, "script ?missing?");
1882918788
return JIM_ERR;
1883018789
}
1883118790
else {
18832
- int len;
18833
- const char *s = Jim_GetString(argv[2], &len);
1883418791
char missing;
1883518792
18836
- Jim_SetResultBool(interp, Jim_ScriptIsComplete(s, len, &missing));
18793
+ Jim_SetResultBool(interp, Jim_ScriptIsComplete(interp, argv[2], &missing));
1883718794
if (missing != ' ' && argc == 4) {
1883818795
Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1));
1883918796
}
1884018797
}
1884118798
break;
1884218799
1884318800
case INFO_HOSTNAME:
18844
-
18801
+
1884518802
return Jim_Eval(interp, "os.gethostname");
1884618803
1884718804
case INFO_NAMEOFEXECUTABLE:
18848
-
18805
+
1884918806
return Jim_Eval(interp, "{info nameofexecutable}");
1885018807
1885118808
case INFO_RETURNCODES:
1885218809
if (argc == 2) {
1885318810
int i;
@@ -18924,11 +18881,11 @@
1892418881
1892518882
if (option == OPT_VAR) {
1892618883
result = Jim_GetVariable(interp, objPtr, 0) != NULL;
1892718884
}
1892818885
else {
18929
-
18886
+
1893018887
Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
1893118888
1893218889
if (cmd) {
1893318890
switch (option) {
1893418891
case OPT_COMMAND:
@@ -18967,11 +18924,11 @@
1896718924
if (len == 0) {
1896818925
return JIM_OK;
1896918926
}
1897018927
strLen = Jim_Utf8Length(interp, argv[1]);
1897118928
18972
-
18929
+
1897318930
if (argc == 2) {
1897418931
splitChars = " \n\t\r";
1897518932
splitLen = 4;
1897618933
}
1897718934
else {
@@ -18980,11 +18937,11 @@
1898018937
}
1898118938
1898218939
noMatchStart = str;
1898318940
resObjPtr = Jim_NewListObj(interp, NULL, 0);
1898418941
18985
-
18942
+
1898618943
if (splitLen) {
1898718944
Jim_Obj *objPtr;
1898818945
while (strLen--) {
1898918946
const char *sc = splitChars;
1899018947
int scLen = splitLen;
@@ -19009,11 +18966,11 @@
1900918966
#define NUM_COMMON (128 - 9)
1901018967
while (strLen--) {
1901118968
int n = utf8_tounicode(str, &c);
1901218969
#ifdef JIM_OPTIMIZATION
1901318970
if (c >= 9 && c < 128) {
19014
-
18971
+
1901518972
c -= 9;
1901618973
if (!commonObj) {
1901718974
commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
1901818975
memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
1901918976
}
@@ -19043,11 +19000,11 @@
1904319000
1904419001
if (argc != 2 && argc != 3) {
1904519002
Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
1904619003
return JIM_ERR;
1904719004
}
19048
-
19005
+
1904919006
if (argc == 2) {
1905019007
joinStr = " ";
1905119008
joinStrLen = 1;
1905219009
}
1905319010
else {
@@ -19322,13 +19279,13 @@
1932219279
return -1;
1932319280
else if (step < 0 && end > start)
1932419281
return -1;
1932519282
len = end - start;
1932619283
if (len < 0)
19327
- len = -len;
19284
+ len = -len;
1932819285
if (step < 0)
19329
- step = -step;
19286
+ step = -step;
1933019287
len = 1 + ((len - 1) / step);
1933119288
if (len > INT_MAX)
1933219289
len = INT_MAX;
1933319290
return (int)((len < 0) ? -1 : len);
1933419291
}
@@ -19542,11 +19499,11 @@
1954219499
1954319500
*indexPtr = -1;
1954419501
1954519502
for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
1954619503
if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
19547
-
19504
+
1954819505
*indexPtr = i;
1954919506
return JIM_OK;
1955019507
}
1955119508
if (flags & JIM_ENUM_ABBREV) {
1955219509
if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19560,11 +19517,11 @@
1956019517
match = i;
1956119518
}
1956219519
}
1956319520
}
1956419521
19565
-
19522
+
1956619523
if (match >= 0) {
1956719524
*indexPtr = match;
1956819525
return JIM_OK;
1956919526
}
1957019527
@@ -19597,11 +19554,11 @@
1959719554
return objPtr->typePtr == &listObjType;
1959819555
}
1959919556
1960019557
void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
1960119558
{
19602
-
19559
+
1960319560
int len = strlen(format);
1960419561
int extra = 0;
1960519562
int n = 0;
1960619563
const char *params[5];
1960719564
char *buf;
@@ -19662,11 +19619,11 @@
1966219619
#include <string.h>
1966319620
1966419621
1966519622
static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1966619623
{
19667
-
19624
+
1966819625
return JIM_OK;
1966919626
}
1967019627
1967119628
static const jim_subcmd_type dummy_subcmd = {
1967219629
"dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19741,43 +19698,43 @@
1974119698
return 0;
1974219699
}
1974319700
1974419701
cmd = argv[1];
1974519702
19746
-
19703
+
1974719704
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
1974819705
if (argc == 2) {
19749
-
19706
+
1975019707
show_cmd_usage(interp, command_table, argc, argv);
1975119708
return &dummy_subcmd;
1975219709
}
1975319710
help = 1;
1975419711
19755
-
19712
+
1975619713
cmd = argv[2];
1975719714
}
1975819715
19759
-
19716
+
1976019717
if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
19761
-
19718
+
1976219719
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
1976319720
add_commands(interp, command_table, " ");
1976419721
return &dummy_subcmd;
1976519722
}
1976619723
1976719724
cmdstr = Jim_GetString(cmd, &cmdlen);
1976819725
1976919726
for (ct = command_table; ct->cmd; ct++) {
1977019727
if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
19771
-
19728
+
1977219729
break;
1977319730
}
1977419731
if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
1977519732
if (partial) {
19776
-
19733
+
1977719734
if (help) {
19778
-
19735
+
1977919736
show_cmd_usage(interp, command_table, argc, argv);
1978019737
return &dummy_subcmd;
1978119738
}
1978219739
bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
1978319740
return 0;
@@ -19785,44 +19742,44 @@
1978519742
partial = ct;
1978619743
}
1978719744
continue;
1978819745
}
1978919746
19790
-
19747
+
1979119748
if (partial && !ct->cmd) {
1979219749
ct = partial;
1979319750
}
1979419751
1979519752
if (!ct->cmd) {
19796
-
19753
+
1979719754
if (help) {
19798
-
19755
+
1979919756
show_cmd_usage(interp, command_table, argc, argv);
1980019757
return &dummy_subcmd;
1980119758
}
1980219759
bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
1980319760
return 0;
1980419761
}
1980519762
1980619763
if (help) {
1980719764
Jim_SetResultString(interp, "Usage: ", -1);
19808
-
19765
+
1980919766
add_cmd_usage(interp, ct, argv[0]);
1981019767
return &dummy_subcmd;
1981119768
}
1981219769
19813
-
19770
+
1981419771
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
1981519772
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
19816
-
19773
+
1981719774
add_cmd_usage(interp, ct, argv[0]);
1981819775
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
1981919776
1982019777
return 0;
1982119778
}
1982219779
19823
-
19780
+
1982419781
return ct;
1982519782
}
1982619783
1982719784
int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
1982819785
{
@@ -19873,11 +19830,11 @@
1987319830
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
1987419831
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
1987519832
*p = 0x80 | (uc & 0x3f);
1987619833
return 3;
1987719834
}
19878
-
19835
+
1987919836
else {
1988019837
*p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
1988119838
*p++ = 0x80 | ((uc & 0x3f000) >> 12);
1988219839
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
1988319840
*p = 0x80 | (uc & 0x3f);
@@ -20064,11 +20021,11 @@
2006420021
if (ch == 'h') {
2006520022
useShort = 1;
2006620023
format += step;
2006720024
step = utf8_tounicode(format, &ch);
2006820025
} else if (ch == 'l') {
20069
-
20026
+
2007020027
format += step;
2007120028
step = utf8_tounicode(format, &ch);
2007220029
if (ch == 'l') {
2007320030
format += step;
2007420031
step = utf8_tounicode(format, &ch);
@@ -20091,11 +20048,11 @@
2009120048
goto errorMsg;
2009220049
case 's': {
2009320050
formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
2009420051
formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
2009520052
if (gotPrecision && (precision < formatted_chars)) {
20096
-
20053
+
2009720054
formatted_chars = precision;
2009820055
formatted_bytes = utf8_index(formatted_buf, precision);
2009920056
}
2010020057
break;
2010120058
}
@@ -20103,11 +20060,11 @@
2010320060
jim_wide code;
2010420061
2010520062
if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
2010620063
goto error;
2010720064
}
20108
-
20065
+
2010920066
formatted_bytes = utf8_getchars(spec, code);
2011020067
formatted_buf = spec;
2011120068
formatted_chars = 1;
2011220069
break;
2011320070
}
@@ -20121,11 +20078,11 @@
2012120078
goto error;
2012220079
}
2012320080
length = sizeof(w) * 8;
2012420081
2012520082
20126
-
20083
+
2012720084
if (num_buffer_size < length + 1) {
2012820085
num_buffer_size = length + 1;
2012920086
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
2013020087
}
2013120088
@@ -20149,29 +20106,29 @@
2014920106
case 'E':
2015020107
case 'f':
2015120108
case 'g':
2015220109
case 'G':
2015320110
doubleType = 1;
20154
-
20111
+
2015520112
case 'd':
2015620113
case 'u':
2015720114
case 'o':
2015820115
case 'x':
2015920116
case 'X': {
2016020117
jim_wide w;
2016120118
double d;
2016220119
int length;
2016320120
20164
-
20121
+
2016520122
if (width) {
2016620123
p += sprintf(p, "%ld", width);
2016720124
}
2016820125
if (gotPrecision) {
2016920126
p += sprintf(p, ".%ld", precision);
2017020127
}
2017120128
20172
-
20129
+
2017320130
if (doubleType) {
2017420131
if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
2017520132
goto error;
2017620133
}
2017720134
length = MAX_FLOAT_WIDTH;
@@ -20198,19 +20155,19 @@
2019820155
}
2019920156
2020020157
*p++ = (char) ch;
2020120158
*p = '\0';
2020220159
20203
-
20160
+
2020420161
if (width > length) {
2020520162
length = width;
2020620163
}
2020720164
if (gotPrecision) {
2020820165
length += precision;
2020920166
}
2021020167
20211
-
20168
+
2021220169
if (num_buffer_size < length + 1) {
2021320170
num_buffer_size = length + 1;
2021420171
num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
2021520172
}
2021620173
@@ -20224,11 +20181,11 @@
2022420181
formatted_buf = num_buffer;
2022520182
break;
2022620183
}
2022720184
2022820185
default: {
20229
-
20186
+
2023020187
spec[0] = ch;
2023120188
spec[1] = '\0';
2023220189
Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
2023320190
goto error;
2023420191
}
@@ -20276,36 +20233,37 @@
2027620233
2027720234
#define REG_MAX_PAREN 100
2027820235
2027920236
2028020237
20281
-#define END 0
20282
-#define BOL 1
20283
-#define EOL 2
20284
-#define ANY 3
20285
-#define ANYOF 4
20286
-#define ANYBUT 5
20287
-#define BRANCH 6
20288
-#define BACK 7
20289
-#define EXACTLY 8
20290
-#define NOTHING 9
20291
-#define REP 10
20292
-#define REPMIN 11
20293
-#define REPX 12
20294
-#define REPXMIN 13
20295
-
20296
-#define WORDA 15
20297
-#define WORDZ 16
20298
-
20299
-#define OPENNC 1000
20300
-#define OPEN 1001
20301
-
20302
-
20303
-
20304
-
20305
-#define CLOSENC 2000
20306
-#define CLOSE 2001
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
2030720265
#define CLOSE_END (CLOSE+REG_MAX_PAREN)
2030820266
2030920267
#define REG_MAGIC 0xFADED00D
2031020268
2031120269
@@ -20318,18 +20276,18 @@
2031820276
2031920277
#define FAIL(R,M) { (R)->err = (M); return (M); }
2032020278
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
2032120279
#define META "^$.[()|?{+*"
2032220280
20323
-#define HASWIDTH 1
20324
-#define SIMPLE 2
20325
-#define SPSTART 4
20326
-#define WORST 0
20281
+#define HASWIDTH 1
20282
+#define SIMPLE 2
20283
+#define SPSTART 4
20284
+#define WORST 0
2032720285
2032820286
#define MAX_REP_COUNT 1000000
2032920287
20330
-static int reg(regex_t *preg, int paren , int *flagp );
20288
+static int reg(regex_t *preg, int paren, int *flagp );
2033120289
static int regpiece(regex_t *preg, int *flagp );
2033220290
static int regbranch(regex_t *preg, int *flagp );
2033320291
static int regatom(regex_t *preg, int *flagp );
2033420292
static int regnode(regex_t *preg, int op );
2033520293
static int regnext(regex_t *preg, int p );
@@ -20373,15 +20331,15 @@
2037320331
memset(preg, 0, sizeof(*preg));
2037420332
2037520333
if (exp == NULL)
2037620334
FAIL(preg, REG_ERR_NULL_ARGUMENT);
2037720335
20378
-
20336
+
2037920337
preg->cflags = cflags;
2038020338
preg->regparse = exp;
2038120339
20382
-
20340
+
2038320341
preg->proglen = (strlen(exp) + 1) * 5;
2038420342
preg->program = malloc(preg->proglen * sizeof(int));
2038520343
if (preg->program == NULL)
2038620344
FAIL(preg, REG_ERR_NOMEM);
2038720345
@@ -20388,24 +20346,24 @@
2038820346
regc(preg, REG_MAGIC);
2038920347
if (reg(preg, 0, &flags) == 0) {
2039020348
return preg->err;
2039120349
}
2039220350
20393
-
20394
- if (preg->re_nsub >= REG_MAX_PAREN)
20351
+
20352
+ if (preg->re_nsub >= REG_MAX_PAREN)
2039520353
FAIL(preg,REG_ERR_TOO_BIG);
2039620354
20397
-
20398
- preg->regstart = 0;
20355
+
20356
+ preg->regstart = 0;
2039920357
preg->reganch = 0;
2040020358
preg->regmust = 0;
2040120359
preg->regmlen = 0;
20402
- scan = 1;
20403
- if (OP(preg, regnext(preg, scan)) == END) {
20360
+ scan = 1;
20361
+ if (OP(preg, regnext(preg, scan)) == END) {
2040420362
scan = OPERAND(scan);
2040520363
20406
-
20364
+
2040720365
if (OP(preg, scan) == EXACTLY) {
2040820366
preg->regstart = preg->program[OPERAND(scan)];
2040920367
}
2041020368
else if (OP(preg, scan) == BOL)
2041120369
preg->reganch++;
@@ -20432,24 +20390,24 @@
2043220390
#endif
2043320391
2043420392
return 0;
2043520393
}
2043620394
20437
-static int reg(regex_t *preg, int paren , int *flagp )
20395
+static int reg(regex_t *preg, int paren, int *flagp )
2043820396
{
2043920397
int ret;
2044020398
int br;
2044120399
int ender;
2044220400
int parno = 0;
2044320401
int flags;
2044420402
20445
- *flagp = HASWIDTH;
20403
+ *flagp = HASWIDTH;
2044620404
20447
-
20405
+
2044820406
if (paren) {
2044920407
if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
20450
-
20408
+
2045120409
preg->regparse += 2;
2045220410
parno = -1;
2045320411
}
2045420412
else {
2045520413
parno = ++preg->re_nsub;
@@ -20456,16 +20414,16 @@
2045620414
}
2045720415
ret = regnode(preg, OPEN+parno);
2045820416
} else
2045920417
ret = 0;
2046020418
20461
-
20419
+
2046220420
br = regbranch(preg, &flags);
2046320421
if (br == 0)
2046420422
return 0;
2046520423
if (ret != 0)
20466
- regtail(preg, ret, br);
20424
+ regtail(preg, ret, br);
2046720425
else
2046820426
ret = br;
2046920427
if (!(flags&HASWIDTH))
2047020428
*flagp &= ~HASWIDTH;
2047120429
*flagp |= flags&SPSTART;
@@ -20472,25 +20430,25 @@
2047220430
while (*preg->regparse == '|') {
2047320431
preg->regparse++;
2047420432
br = regbranch(preg, &flags);
2047520433
if (br == 0)
2047620434
return 0;
20477
- regtail(preg, ret, br);
20435
+ regtail(preg, ret, br);
2047820436
if (!(flags&HASWIDTH))
2047920437
*flagp &= ~HASWIDTH;
2048020438
*flagp |= flags&SPSTART;
2048120439
}
2048220440
20483
-
20441
+
2048420442
ender = regnode(preg, (paren) ? CLOSE+parno : END);
2048520443
regtail(preg, ret, ender);
2048620444
20487
-
20445
+
2048820446
for (br = ret; br != 0; br = regnext(preg, br))
2048920447
regoptail(preg, br, ender);
2049020448
20491
-
20449
+
2049220450
if (paren && *preg->regparse++ != ')') {
2049320451
preg->err = REG_ERR_UNMATCHED_PAREN;
2049420452
return 0;
2049520453
} else if (!paren && *preg->regparse != '\0') {
2049620454
if (*preg->regparse == ')') {
@@ -20510,11 +20468,11 @@
2051020468
int ret;
2051120469
int chain;
2051220470
int latest;
2051320471
int flags;
2051420472
20515
- *flagp = WORST;
20473
+ *flagp = WORST;
2051620474
2051720475
ret = regnode(preg, BRANCH);
2051820476
chain = 0;
2051920477
while (*preg->regparse != '\0' && *preg->regparse != ')' &&
2052020478
*preg->regparse != '|') {
@@ -20528,11 +20486,11 @@
2052820486
else {
2052920487
regtail(preg, chain, latest);
2053020488
}
2053120489
chain = latest;
2053220490
}
20533
- if (chain == 0)
20491
+ if (chain == 0)
2053420492
(void) regnode(preg, NOTHING);
2053520493
2053620494
return(ret);
2053720495
}
2053820496
@@ -20558,11 +20516,11 @@
2055820516
if (!(flags&HASWIDTH) && op != '?') {
2055920517
preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
2056020518
return 0;
2056120519
}
2056220520
20563
-
20521
+
2056420522
if (op == '{') {
2056520523
char *end;
2056620524
2056720525
min = strtoul(preg->regparse + 1, &end, 10);
2056820526
if (end == preg->regparse + 1) {
@@ -20630,11 +20588,11 @@
2063020588
static void reg_addrange(regex_t *preg, int lower, int upper)
2063120589
{
2063220590
if (lower > upper) {
2063320591
reg_addrange(preg, upper, lower);
2063420592
}
20635
-
20593
+
2063620594
regc(preg, upper - lower + 1);
2063720595
regc(preg, lower);
2063820596
}
2063920597
2064020598
static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20698,17 +20656,17 @@
2069820656
case 'r': *ch = '\r'; break;
2069920657
case 't': *ch = '\t'; break;
2070020658
case 'v': *ch = '\v'; break;
2070120659
case 'u':
2070220660
if (*s == '{') {
20703
-
20661
+
2070420662
n = parse_hex(s + 1, 6, ch);
2070520663
if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
2070620664
s += n + 2;
2070720665
}
2070820666
else {
20709
-
20667
+
2071020668
*ch = 'u';
2071120669
}
2071220670
}
2071320671
else if ((n = parse_hex(s, 4, ch)) > 0) {
2071420672
s += n;
@@ -20739,15 +20697,15 @@
2073920697
int nocase = (preg->cflags & REG_ICASE);
2074020698
2074120699
int ch;
2074220700
int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
2074320701
20744
- *flagp = WORST;
20702
+ *flagp = WORST;
2074520703
2074620704
preg->regparse += n;
2074720705
switch (ch) {
20748
-
20706
+
2074920707
case '^':
2075020708
ret = regnode(preg, BOL);
2075120709
break;
2075220710
case '$':
2075320711
ret = regnode(preg, EOL);
@@ -20757,24 +20715,24 @@
2075720715
*flagp |= HASWIDTH|SIMPLE;
2075820716
break;
2075920717
case '[': {
2076020718
const char *pattern = preg->regparse;
2076120719
20762
- if (*pattern == '^') {
20720
+ if (*pattern == '^') {
2076320721
ret = regnode(preg, ANYBUT);
2076420722
pattern++;
2076520723
} else
2076620724
ret = regnode(preg, ANYOF);
2076720725
20768
-
20726
+
2076920727
if (*pattern == ']' || *pattern == '-') {
2077020728
reg_addrange(preg, *pattern, *pattern);
2077120729
pattern++;
2077220730
}
2077320731
2077420732
while (*pattern && *pattern != ']') {
20775
-
20733
+
2077620734
int start;
2077720735
int end;
2077820736
2077920737
pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
2078020738
if (start == '\\') {
@@ -20783,11 +20741,11 @@
2078320741
preg->err = REG_ERR_NULL_CHAR;
2078420742
return 0;
2078520743
}
2078620744
}
2078720745
if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
20788
-
20746
+
2078920747
pattern += utf8_tounicode(pattern, &end);
2079020748
pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
2079120749
if (end == '\\') {
2079220750
pattern += reg_decode_escape(pattern, &end);
2079320751
if (end == 0) {
@@ -20797,35 +20755,81 @@
2079720755
}
2079820756
2079920757
reg_addrange(preg, start, end);
2080020758
continue;
2080120759
}
20802
- if (start == '[') {
20803
- if (strncmp(pattern, ":alpha:]", 8) == 0) {
20804
- if ((preg->cflags & REG_ICASE) == 0) {
20805
- reg_addrange(preg, 'a', 'z');
20806
- }
20807
- reg_addrange(preg, 'A', 'Z');
20808
- pattern += 8;
20809
- continue;
20810
- }
20811
- if (strncmp(pattern, ":alnum:]", 8) == 0) {
20812
- if ((preg->cflags & REG_ICASE) == 0) {
20813
- reg_addrange(preg, 'a', 'z');
20814
- }
20815
- reg_addrange(preg, 'A', 'Z');
20816
- reg_addrange(preg, '0', '9');
20817
- pattern += 8;
20818
- continue;
20819
- }
20820
- if (strncmp(pattern, ":space:]", 8) == 0) {
20821
- reg_addrange_str(preg, " \t\r\n\f\v");
20822
- pattern += 8;
20823
- continue;
20824
- }
20825
- }
20826
-
20760
+ if (start == '[' && pattern[0] == ':') {
20761
+ static const char *character_class[] = {
20762
+ ":alpha:", ":alnum:", ":space:", ":blank:", ":upper:", ":lower:",
20763
+ ":digit:", ":xdigit:", ":cntrl:", ":graph:", ":print:", ":punct:",
20764
+ };
20765
+ enum {
20766
+ CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER,
20767
+ CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT,
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');
20790
+ break;
20791
+ case CC_SPACE:
20792
+ reg_addrange_str(preg, " \t\r\n\f\v");
20793
+ break;
20794
+ case CC_BLANK:
20795
+ reg_addrange_str(preg, " \t");
20796
+ break;
20797
+ case CC_UPPER:
20798
+ reg_addrange(preg, 'A', 'Z');
20799
+ break;
20800
+ case CC_LOWER:
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);
20812
+ reg_addrange(preg, 127, 127);
20813
+ break;
20814
+ case CC_PRINT:
20815
+ reg_addrange(preg, ' ', '~');
20816
+ break;
20817
+ case CC_GRAPH:
20818
+ reg_addrange(preg, '!', '~');
20819
+ break;
20820
+ case CC_PUNCT:
20821
+ reg_addrange(preg, '!', '/');
20822
+ reg_addrange(preg, ':', '@');
20823
+ reg_addrange(preg, '[', '`');
20824
+ reg_addrange(preg, '{', '~');
20825
+ break;
20826
+ }
20827
+ continue;
20828
+ }
20829
+ }
20830
+
2082720831
reg_addrange(preg, start, start);
2082820832
}
2082920833
regc(preg, '\0');
2083020834
2083120835
if (*pattern) {
@@ -20844,38 +20848,47 @@
2084420848
break;
2084520849
case '\0':
2084620850
case '|':
2084720851
case ')':
2084820852
preg->err = REG_ERR_INTERNAL;
20849
- return 0;
20853
+ return 0;
2085020854
case '?':
2085120855
case '+':
2085220856
case '*':
2085320857
case '{':
2085420858
preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
2085520859
return 0;
2085620860
case '\\':
20857
- switch (*preg->regparse++) {
20861
+ ch = *preg->regparse++;
20862
+ switch (ch) {
2085820863
case '\0':
2085920864
preg->err = REG_ERR_TRAILING_BACKSLASH;
2086020865
return 0;
20866
+ case 'A':
20867
+ ret = regnode(preg, BOLX);
20868
+ break;
20869
+ case 'Z':
20870
+ ret = regnode(preg, EOLX);
20871
+ break;
2086120872
case '<':
2086220873
case 'm':
2086320874
ret = regnode(preg, WORDA);
2086420875
break;
2086520876
case '>':
2086620877
case 'M':
2086720878
ret = regnode(preg, WORDZ);
2086820879
break;
2086920880
case 'd':
20870
- ret = regnode(preg, ANYOF);
20881
+ case 'D':
20882
+ ret = regnode(preg, ch == 'd' ? ANYOF : ANYBUT);
2087120883
reg_addrange(preg, '0', '9');
2087220884
regc(preg, '\0');
2087320885
*flagp |= HASWIDTH|SIMPLE;
2087420886
break;
2087520887
case 'w':
20876
- ret = regnode(preg, ANYOF);
20888
+ case 'W':
20889
+ ret = regnode(preg, ch == 'w' ? ANYOF : ANYBUT);
2087720890
if ((preg->cflags & REG_ICASE) == 0) {
2087820891
reg_addrange(preg, 'a', 'z');
2087920892
}
2088020893
reg_addrange(preg, 'A', 'Z');
2088120894
reg_addrange(preg, '0', '9');
@@ -20882,39 +20895,40 @@
2088220895
reg_addrange(preg, '_', '_');
2088320896
regc(preg, '\0');
2088420897
*flagp |= HASWIDTH|SIMPLE;
2088520898
break;
2088620899
case 's':
20887
- ret = regnode(preg, ANYOF);
20900
+ case 'S':
20901
+ ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT);
2088820902
reg_addrange_str(preg," \t\r\n\f\v");
2088920903
regc(preg, '\0');
2089020904
*flagp |= HASWIDTH|SIMPLE;
2089120905
break;
20892
-
20906
+
2089320907
default:
20894
-
20895
-
20908
+
20909
+
2089620910
preg->regparse--;
2089720911
goto de_fault;
2089820912
}
2089920913
break;
2090020914
de_fault:
2090120915
default: {
2090220916
int added = 0;
2090320917
20904
-
20918
+
2090520919
preg->regparse -= n;
2090620920
2090720921
ret = regnode(preg, EXACTLY);
2090820922
2090920923
20910
-
20924
+
2091120925
while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
2091220926
n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
2091320927
if (ch == '\\' && preg->regparse[n]) {
20914
- if (strchr("<>mMwds", preg->regparse[n])) {
20915
-
20928
+ if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) {
20929
+
2091620930
break;
2091720931
}
2091820932
n += reg_decode_escape(preg->regparse + n, &ch);
2091920933
if (ch == 0) {
2092020934
preg->err = REG_ERR_NULL_CHAR;
@@ -20922,23 +20936,23 @@
2092220936
}
2092320937
}
2092420938
2092520939
2092620940
if (ISMULT(preg->regparse[n])) {
20927
-
20941
+
2092820942
if (added) {
20929
-
20943
+
2093020944
break;
2093120945
}
20932
-
20946
+
2093320947
regc(preg, ch);
2093420948
added++;
2093520949
preg->regparse += n;
2093620950
break;
2093720951
}
2093820952
20939
-
20953
+
2094020954
regc(preg, ch);
2094120955
added++;
2094220956
preg->regparse += n;
2094320957
}
2094420958
regc(preg, '\0');
@@ -20965,15 +20979,15 @@
2096520979
2096620980
static int regnode(regex_t *preg, int op)
2096720981
{
2096820982
reg_grow(preg, 2);
2096920983
20970
-
20984
+
2097120985
preg->program[preg->p++] = op;
2097220986
preg->program[preg->p++] = 0;
2097320987
20974
-
20988
+
2097520989
return preg->p - 2;
2097620990
}
2097720991
2097820992
static void regc(regex_t *preg, int b )
2097920993
{
@@ -20983,13 +20997,13 @@
2098320997
2098420998
static int reginsert(regex_t *preg, int op, int size, int opnd )
2098520999
{
2098621000
reg_grow(preg, size);
2098721001
20988
-
21002
+
2098921003
memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
20990
-
21004
+
2099121005
memset(preg->program + opnd, 0, sizeof(int) * size);
2099221006
2099321007
preg->program[opnd] = op;
2099421008
2099521009
preg->p += size;
@@ -21001,11 +21015,11 @@
2100121015
{
2100221016
int scan;
2100321017
int temp;
2100421018
int offset;
2100521019
21006
-
21020
+
2100721021
scan = p;
2100821022
for (;;) {
2100921023
temp = regnext(preg, scan);
2101021024
if (temp == 0)
2101121025
break;
@@ -21021,11 +21035,11 @@
2102121035
}
2102221036
2102321037
2102421038
static void regoptail(regex_t *preg, int p, int val )
2102521039
{
21026
-
21040
+
2102721041
if (p != 0 && OP(preg, p) == BRANCH) {
2102821042
regtail(preg, OPERAND(p), val);
2102921043
}
2103021044
}
2103121045
@@ -21037,16 +21051,16 @@
2103721051
int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
2103821052
{
2103921053
const char *s;
2104021054
int scan;
2104121055
21042
-
21056
+
2104321057
if (preg == NULL || preg->program == NULL || string == NULL) {
2104421058
return REG_ERR_NULL_ARGUMENT;
2104521059
}
2104621060
21047
-
21061
+
2104821062
if (*preg->program != REG_MAGIC) {
2104921063
return REG_ERR_CORRUPTED;
2105021064
}
2105121065
2105221066
#ifdef DEBUG
@@ -21055,51 +21069,51 @@
2105521069
#endif
2105621070
2105721071
preg->eflags = eflags;
2105821072
preg->pmatch = pmatch;
2105921073
preg->nmatch = nmatch;
21060
- preg->start = string;
21074
+ preg->start = string;
2106121075
21062
-
21076
+
2106321077
for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
2106421078
int op = OP(preg, scan);
2106521079
if (op == END)
2106621080
break;
2106721081
if (op == REPX || op == REPXMIN)
2106821082
preg->program[scan + 4] = 0;
2106921083
}
2107021084
21071
-
21085
+
2107221086
if (preg->regmust != 0) {
2107321087
s = string;
2107421088
while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
2107521089
if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
2107621090
break;
2107721091
}
2107821092
s++;
2107921093
}
21080
- if (s == NULL)
21094
+ if (s == NULL)
2108121095
return REG_NOMATCH;
2108221096
}
2108321097
21084
-
21098
+
2108521099
preg->regbol = string;
2108621100
21087
-
21101
+
2108821102
if (preg->reganch) {
2108921103
if (eflags & REG_NOTBOL) {
21090
-
21104
+
2109121105
goto nextline;
2109221106
}
2109321107
while (1) {
2109421108
if (regtry(preg, string)) {
2109521109
return REG_NOERROR;
2109621110
}
2109721111
if (*string) {
2109821112
nextline:
2109921113
if (preg->cflags & REG_NEWLINE) {
21100
-
21114
+
2110121115
string = strchr(string, '\n');
2110221116
if (string) {
2110321117
preg->regbol = ++string;
2110421118
continue;
2110521119
}
@@ -21107,22 +21121,22 @@
2110721121
}
2110821122
return REG_NOMATCH;
2110921123
}
2111021124
}
2111121125
21112
-
21126
+
2111321127
s = string;
2111421128
if (preg->regstart != '\0') {
21115
-
21129
+
2111621130
while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
2111721131
if (regtry(preg, s))
2111821132
return REG_NOERROR;
2111921133
s++;
2112021134
}
2112121135
}
2112221136
else
21123
-
21137
+
2112421138
while (1) {
2112521139
if (regtry(preg, s))
2112621140
return REG_NOERROR;
2112721141
if (*s == '\0') {
2112821142
break;
@@ -21131,15 +21145,15 @@
2113121145
int c;
2113221146
s += utf8_tounicode(s, &c);
2113321147
}
2113421148
}
2113521149
21136
-
21150
+
2113721151
return REG_NOMATCH;
2113821152
}
2113921153
21140
-
21154
+
2114121155
static int regtry( regex_t *preg, const char *string )
2114221156
{
2114321157
int i;
2114421158
2114521159
preg->reginput = string;
@@ -21176,11 +21190,11 @@
2117621190
}
2117721191
2117821192
static int reg_range_find(const int *range, int c)
2117921193
{
2118021194
while (*range) {
21181
-
21195
+
2118221196
if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
2118321197
return 1;
2118421198
}
2118521199
range += 2;
2118621200
}
@@ -21188,11 +21202,11 @@
2118821202
}
2118921203
2119021204
static const char *str_find(const char *string, int c, int nocase)
2119121205
{
2119221206
if (nocase) {
21193
-
21207
+
2119421208
c = utf8_upper(c);
2119521209
}
2119621210
while (*string) {
2119721211
int ch;
2119821212
int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21232,15 +21246,15 @@
2123221246
no = regrepeat(preg, scan + 5, max);
2123321247
if (no < min) {
2123421248
return 0;
2123521249
}
2123621250
if (matchmin) {
21237
-
21251
+
2123821252
max = no;
2123921253
no = min;
2124021254
}
21241
-
21255
+
2124221256
while (1) {
2124321257
if (matchmin) {
2124421258
if (no > max) {
2124521259
break;
2124621260
}
@@ -21250,22 +21264,22 @@
2125021264
break;
2125121265
}
2125221266
}
2125321267
preg->reginput = save + utf8_index(save, no);
2125421268
reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21255
-
21269
+
2125621270
if (reg_iseol(preg, nextch) || c == nextch) {
2125721271
if (regmatch(preg, next)) {
2125821272
return(1);
2125921273
}
2126021274
}
2126121275
if (matchmin) {
21262
-
21276
+
2126321277
no++;
2126421278
}
2126521279
else {
21266
-
21280
+
2126721281
no--;
2126821282
}
2126921283
}
2127021284
return(0);
2127121285
}
@@ -21275,13 +21289,13 @@
2127521289
int *scanpt = preg->program + scan;
2127621290
2127721291
int max = scanpt[2];
2127821292
int min = scanpt[3];
2127921293
21280
-
21294
+
2128121295
if (scanpt[4] < min) {
21282
-
21296
+
2128321297
scanpt[4]++;
2128421298
if (regmatch(preg, scan + 5)) {
2128521299
return 1;
2128621300
}
2128721301
scanpt[4]--;
@@ -21290,39 +21304,39 @@
2129021304
if (scanpt[4] > max) {
2129121305
return 0;
2129221306
}
2129321307
2129421308
if (matchmin) {
21295
-
21309
+
2129621310
if (regmatch(preg, regnext(preg, scan))) {
2129721311
return 1;
2129821312
}
21299
-
21313
+
2130021314
scanpt[4]++;
2130121315
if (regmatch(preg, scan + 5)) {
2130221316
return 1;
2130321317
}
2130421318
scanpt[4]--;
2130521319
return 0;
2130621320
}
21307
-
21321
+
2130821322
if (scanpt[4] < max) {
2130921323
scanpt[4]++;
2131021324
if (regmatch(preg, scan + 5)) {
2131121325
return 1;
2131221326
}
2131321327
scanpt[4]--;
2131421328
}
21315
-
21329
+
2131621330
return regmatch(preg, regnext(preg, scan));
2131721331
}
2131821332
2131921333
2132021334
static int regmatch(regex_t *preg, int prog)
2132121335
{
21322
- int scan;
21323
- int next;
21336
+ int scan;
21337
+ int next;
2132421338
const char *save;
2132521339
2132621340
scan = prog;
2132721341
2132821342
#ifdef DEBUG
@@ -21332,48 +21346,60 @@
2133221346
while (scan != 0) {
2133321347
int n;
2133421348
int c;
2133521349
#ifdef DEBUG
2133621350
if (regnarrate) {
21337
- fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
21351
+ fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
2133821352
}
2133921353
#endif
2134021354
next = regnext(preg, scan);
2134121355
n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
2134221356
2134321357
switch (OP(preg, scan)) {
21358
+ case BOLX:
21359
+ if ((preg->eflags & REG_NOTBOL)) {
21360
+ return(0);
21361
+ }
21362
+
2134421363
case BOL:
21345
- if (preg->reginput != preg->regbol)
21364
+ if (preg->reginput != preg->regbol) {
2134621365
return(0);
21366
+ }
21367
+ break;
21368
+ case EOLX:
21369
+ if (c != 0) {
21370
+
21371
+ return 0;
21372
+ }
2134721373
break;
2134821374
case EOL:
2134921375
if (!reg_iseol(preg, c)) {
2135021376
return(0);
2135121377
}
2135221378
break;
2135321379
case WORDA:
21354
-
21380
+
2135521381
if ((!isalnum(UCHAR(c))) && c != '_')
2135621382
return(0);
21357
-
21383
+
2135821384
if (preg->reginput > preg->regbol &&
2135921385
(isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
2136021386
return(0);
2136121387
break;
2136221388
case WORDZ:
21363
-
21389
+
2136421390
if (preg->reginput > preg->regbol) {
21365
-
21391
+
2136621392
if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
2136721393
c = preg->reginput[-1];
21368
-
21394
+
2136921395
if (isalnum(UCHAR(c)) || c == '_') {
2137021396
break;
2137121397
}
2137221398
}
2137321399
}
21374
-
21400
+
2137521401
return(0);
2137621402
2137721403
case ANY:
2137821404
if (reg_iseol(preg, c))
2137921405
return 0;
@@ -21409,12 +21435,12 @@
2140921435
case NOTHING:
2141021436
break;
2141121437
case BACK:
2141221438
break;
2141321439
case BRANCH:
21414
- if (OP(preg, next) != BRANCH)
21415
- next = OPERAND(scan);
21440
+ if (OP(preg, next) != BRANCH)
21441
+ next = OPERAND(scan);
2141621442
else {
2141721443
do {
2141821444
save = preg->reginput;
2141921445
if (regmatch(preg, OPERAND(scan))) {
2142021446
return(1);
@@ -21421,11 +21447,11 @@
2142121447
}
2142221448
preg->reginput = save;
2142321449
scan = regnext(preg, scan);
2142421450
} while (scan != 0 && OP(preg, scan) == BRANCH);
2142521451
return(0);
21426
-
21452
+
2142721453
}
2142821454
break;
2142921455
case REP:
2143021456
case REPMIN:
2143121457
return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21433,11 +21459,11 @@
2143321459
case REPX:
2143421460
case REPXMIN:
2143521461
return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
2143621462
2143721463
case END:
21438
- return 1;
21464
+ return 1;
2143921465
2144021466
case OPENNC:
2144121467
case CLOSENC:
2144221468
return regmatch(preg, next);
2144321469
@@ -21480,11 +21506,11 @@
2148021506
2148121507
scan = preg->reginput;
2148221508
opnd = OPERAND(p);
2148321509
switch (OP(preg, p)) {
2148421510
case ANY:
21485
-
21511
+
2148621512
while (!reg_iseol(preg, *scan) && count < max) {
2148721513
count++;
2148821514
scan++;
2148921515
}
2149021516
break;
@@ -21516,13 +21542,13 @@
2151621542
}
2151721543
count++;
2151821544
scan += n;
2151921545
}
2152021546
break;
21521
- default:
21547
+ default:
2152221548
preg->err = REG_ERR_INTERNAL;
21523
- count = 0;
21549
+ count = 0;
2152421550
break;
2152521551
}
2152621552
preg->reginput = scan;
2152721553
2152821554
return(count);
@@ -21543,11 +21569,11 @@
2154321569
return(p+offset);
2154421570
}
2154521571
2154621572
static int regopsize(regex_t *preg, int p )
2154721573
{
21548
-
21574
+
2154921575
switch (OP(preg, p)) {
2155021576
case REP:
2155121577
case REPMIN:
2155221578
case REPX:
2155321579
case REPXMIN:
@@ -21664,26 +21690,26 @@
2166421690
{
2166521691
DIR *dir = 0;
2166621692
2166721693
if (name && name[0]) {
2166821694
size_t base_length = strlen(name);
21669
- const char *all =
21695
+ const char *all =
2167021696
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
2167121697
2167221698
if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
2167321699
(dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
2167421700
strcat(strcpy(dir->name, name), all);
2167521701
2167621702
if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
2167721703
dir->result.d_name = 0;
21678
- else {
21704
+ else {
2167921705
Jim_Free(dir->name);
2168021706
Jim_Free(dir);
2168121707
dir = 0;
2168221708
}
2168321709
}
21684
- else {
21710
+ else {
2168521711
Jim_Free(dir);
2168621712
dir = 0;
2168721713
errno = ENOMEM;
2168821714
}
2168921715
}
@@ -21701,11 +21727,11 @@
2170121727
if (dir->handle != -1)
2170221728
result = _findclose(dir->handle);
2170321729
Jim_Free(dir->name);
2170421730
Jim_Free(dir);
2170521731
}
21706
- if (result == -1)
21732
+ if (result == -1)
2170721733
errno = EBADF;
2170821734
return result;
2170921735
}
2171021736
2171121737
struct dirent *readdir(DIR * dir)
@@ -21729,11 +21755,13 @@
2172921755
#include <errno.h>
2173021756
#include <string.h>
2173121757
2173221758
2173321759
#ifdef USE_LINENOISE
21734
-#include <unistd.h>
21760
+#ifdef HAVE_UNISTD_H
21761
+ #include <unistd.h>
21762
+#endif
2173521763
#include "linenoise.h"
2173621764
#else
2173721765
#define MAX_LINE_LEN 512
2173821766
#endif
2173921767
@@ -21782,11 +21810,11 @@
2178221810
}
2178321811
2178421812
void Jim_HistoryShow(void)
2178521813
{
2178621814
#ifdef USE_LINENOISE
21787
-
21815
+
2178821816
int i;
2178921817
int len;
2179021818
char **history = linenoiseHistory(&len);
2179121819
for (i = 0; i < len; i++) {
2179221820
printf("%4d %s\n", i + 1, history[i]);
@@ -21817,32 +21845,29 @@
2181721845
while (1) {
2181821846
Jim_Obj *scriptObjPtr;
2181921847
const char *result;
2182021848
int reslen;
2182121849
char prompt[20];
21822
- const char *str;
2182321850
21824
- if (retcode != 0) {
21851
+ if (retcode != JIM_OK) {
2182521852
const char *retcodestr = Jim_ReturnCode(retcode);
2182621853
2182721854
if (*retcodestr == '?') {
21828
- snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode);
21855
+ snprintf(prompt, sizeof(prompt) - 3, "[%d] . ", retcode);
2182921856
}
2183021857
else {
21831
- snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr);
21858
+ snprintf(prompt, sizeof(prompt) - 3, "[%s] . ", retcodestr);
2183221859
}
2183321860
}
2183421861
else {
21835
- prompt[0] = '\0';
21862
+ strcpy(prompt, ". ");
2183621863
}
21837
- strcat(prompt, ". ");
2183821864
2183921865
scriptObjPtr = Jim_NewStringObj(interp, "", 0);
2184021866
Jim_IncrRefCount(scriptObjPtr);
2184121867
while (1) {
2184221868
char state;
21843
- int len;
2184421869
char *line;
2184521870
2184621871
line = Jim_HistoryGetline(prompt);
2184721872
if (line == NULL) {
2184821873
if (errno == EINTR) {
@@ -21851,26 +21876,23 @@
2185121876
Jim_DecrRefCount(interp, scriptObjPtr);
2185221877
retcode = JIM_OK;
2185321878
goto out;
2185421879
}
2185521880
if (Jim_Length(scriptObjPtr) != 0) {
21881
+
2185621882
Jim_AppendString(interp, scriptObjPtr, "\n", 1);
2185721883
}
2185821884
Jim_AppendString(interp, scriptObjPtr, line, -1);
2185921885
free(line);
21860
- str = Jim_GetString(scriptObjPtr, &len);
21861
- if (len == 0) {
21862
- continue;
21863
- }
21864
- if (Jim_ScriptIsComplete(str, len, &state))
21886
+ if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state))
2186521887
break;
2186621888
2186721889
snprintf(prompt, sizeof(prompt), "%c> ", state);
2186821890
}
2186921891
#ifdef USE_LINENOISE
21870
- if (strcmp(str, "h") == 0) {
21871
-
21892
+ if (strcmp(Jim_String(scriptObjPtr), "h") == 0) {
21893
+
2187221894
Jim_HistoryShow();
2187321895
Jim_DecrRefCount(interp, scriptObjPtr);
2187421896
continue;
2187521897
}
2187621898
@@ -21881,11 +21903,10 @@
2188121903
#endif
2188221904
retcode = Jim_EvalObj(interp, scriptObjPtr);
2188321905
Jim_DecrRefCount(interp, scriptObjPtr);
2188421906
2188521907
if (retcode == JIM_EXIT) {
21886
- retcode = JIM_EXIT;
2188721908
break;
2188821909
}
2188921910
if (retcode == JIM_ERR) {
2189021911
Jim_MakeErrorMessage(interp);
2189121912
}
@@ -21910,11 +21931,11 @@
2191021931
static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
2191121932
{
2191221933
int n;
2191321934
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
2191421935
21915
-
21936
+
2191621937
for (n = 0; n < argc; n++) {
2191721938
Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
2191821939
2191921940
Jim_ListAppendElement(interp, listObj, obj);
2192021941
}
@@ -21926,45 +21947,71 @@
2192621947
static void JimPrintErrorMessage(Jim_Interp *interp)
2192721948
{
2192821949
Jim_MakeErrorMessage(interp);
2192921950
fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp)));
2193021951
}
21952
+
21953
+void usage(const char* executable_name)
21954
+{
21955
+ printf("jimsh version %d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
21956
+ printf("Usage: %s\n", executable_name);
21957
+ printf("or : %s [options] [filename]\n", executable_name);
21958
+ printf("\n");
21959
+ printf("Without options: Interactive mode\n");
21960
+ printf("\n");
21961
+ printf("Options:\n");
21962
+ printf(" --version : prints the version string\n");
21963
+ printf(" --help : prints this text\n");
21964
+ printf(" -e CMD : executes command CMD\n");
21965
+ printf(" NOTE: all subsequent options will be passed as arguments to the command\n");
21966
+ printf(" [filename] : executes the script contained in the named file\n");
21967
+ printf(" NOTE: all subsequent options will be passed to the script\n\n");
21968
+}
2193121969
2193221970
int main(int argc, char *const argv[])
2193321971
{
2193421972
int retcode;
2193521973
Jim_Interp *interp;
21974
+ char *const orig_argv0 = argv[0];
21975
+
2193621976
2193721977
if (argc > 1 && strcmp(argv[1], "--version") == 0) {
2193821978
printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
2193921979
return 0;
2194021980
}
21981
+ else if (argc > 1 && strcmp(argv[1], "--help") == 0) {
21982
+ usage(argv[0]);
21983
+ return 0;
21984
+ }
2194121985
21942
-
21986
+
2194321987
interp = Jim_CreateInterp();
2194421988
Jim_RegisterCoreCommands(interp);
2194521989
21946
-
21990
+
2194721991
if (Jim_InitStaticExtensions(interp) != JIM_OK) {
2194821992
JimPrintErrorMessage(interp);
2194921993
}
2195021994
21951
- Jim_SetVariableStrWithStr(interp, "jim::argv0", argv[0]);
21995
+ Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0);
2195221996
Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
2195321997
retcode = Jim_initjimshInit(interp);
2195421998
2195521999
if (argc == 1) {
22000
+
2195622001
if (retcode == JIM_ERR) {
2195722002
JimPrintErrorMessage(interp);
2195822003
}
2195922004
if (retcode != JIM_EXIT) {
2196022005
JimSetArgv(interp, 0, NULL);
2196122006
retcode = Jim_InteractivePrompt(interp);
2196222007
}
2196322008
}
2196422009
else {
22010
+
2196522011
if (argc > 2 && strcmp(argv[1], "-e") == 0) {
22012
+
2196622013
JimSetArgv(interp, argc - 3, argv + 3);
2196722014
retcode = Jim_Eval(interp, argv[2]);
2196822015
if (retcode != JIM_ERR) {
2196922016
printf("%s\n", Jim_String(Jim_GetResult(interp)));
2197022017
}
2197122018
2197222019
ADDED autosetup/pkg-config.tcl
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,20 +1,18 @@
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 "."
10 #define jim_ext_bootstrap
11 #define jim_ext_aio
12 #define jim_ext_readdir
13 #define jim_ext_glob
14 #define jim_ext_regexp
15 #define jim_ext_file
 
16 #define jim_ext_exec
17 #define jim_ext_clock
18 #define jim_ext_array
19 #define jim_ext_stdlib
20 #define jim_ext_tclcompat
@@ -35,20 +33,26 @@
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
@@ -64,11 +68,13 @@
64 int dlclose(void *handle);
65 void *dlsym(void *handle, const char *symbol);
66 char *dlerror(void);
67
68
69 #define JIM_SPRINTF_DOUBLE_NEEDS_FIX
 
 
70
71 #ifdef _MSC_VER
72
73
74 #if _MSC_VER >= 1000
@@ -103,14 +109,14 @@
103 struct dirent {
104 char *d_name;
105 };
106
107 typedef struct DIR {
108 long handle;
109 struct _finddata_t info;
110 struct dirent result;
111 char *name;
112 } DIR;
113
114 DIR *opendir(const char *name);
115 int closedir(DIR *dir);
116 struct dirent *readdir(DIR *dir);
@@ -120,11 +126,11 @@
120 #include <stdlib.h>
121 #define strtod __strtod
122
123 #endif
124
125 #endif
126
127 #ifdef __cplusplus
128 }
129 #endif
130
@@ -173,13 +179,13 @@
173 extern "C" {
174 #endif
175
176 #include <time.h>
177 #include <limits.h>
178 #include <stdio.h>
179 #include <stdlib.h>
180 #include <stdarg.h>
181
182
183 #ifndef HAVE_NO_AUTOCONF
184 #endif
185
@@ -222,31 +228,31 @@
222 #define JIM_SIGNAL 5
223 #define JIM_EXIT 6
224
225 #define JIM_EVAL 7
226
227 #define JIM_MAX_CALLFRAME_DEPTH 1000
228 #define JIM_MAX_EVAL_DEPTH 2000
229
230
231 #define JIM_PRIV_FLAG_SHIFT 20
232
233 #define JIM_NONE 0
234 #define JIM_ERRMSG 1
235 #define JIM_ENUM_ABBREV 2
236 #define JIM_UNSHARED 4
237 #define JIM_MUSTEXIST 8
238
239
240 #define JIM_SUBST_NOVAR 1
241 #define JIM_SUBST_NOCMD 2
242 #define JIM_SUBST_NOESC 4
243 #define JIM_SUBST_FLAG 128
244
245
246 #define JIM_CASESENS 0
247 #define JIM_NOCASE 1
248
249
250 #define JIM_PATH_LEN 1024
251
252
@@ -337,79 +343,79 @@
337 #define Jim_GetHashTableSize(ht) ((ht)->size)
338 #define Jim_GetHashTableUsed(ht) ((ht)->used)
339
340
341 typedef struct Jim_Obj {
342 char *bytes;
343 const struct Jim_ObjType *typePtr;
344 int refCount;
345 int length;
346
347 union {
348
349 jim_wide wideValue;
350
351 int intValue;
352
353 double doubleValue;
354
355 void *ptr;
356
357 struct {
358 void *ptr1;
359 void *ptr2;
360 } twoPtrValue;
361
362 struct {
363 struct Jim_Var *varPtr;
364 unsigned long callFrameId;
365 int global;
366 } varValue;
367
368 struct {
369 struct Jim_Obj *nsObj;
370 struct Jim_Cmd *cmdPtr;
371 unsigned long procEpoch;
372 } cmdValue;
373
374 struct {
375 struct Jim_Obj **ele;
376 int len;
377 int maxLen;
378 } listValue;
379
380 struct {
381 int maxLength;
382 int charLength;
383 } strValue;
384
385 struct {
386 unsigned long id;
387 struct Jim_Reference *refPtr;
388 } refValue;
389
390 struct {
391 struct Jim_Obj *fileNameObj;
392 int lineNumber;
393 } sourceValue;
394
395 struct {
396 struct Jim_Obj *varNameObjPtr;
397 struct Jim_Obj *indexObjPtr;
398 } dictSubstValue;
399
400 struct {
401 void *compre;
402 unsigned flags;
403 } regexpValue;
404 struct {
405 int line;
406 int argc;
407 } scriptLineValue;
408 } internalRep;
409 struct Jim_Obj *prevObjPtr;
410 struct Jim_Obj *nextObjPtr;
411 } Jim_Obj;
412
413
414 #define Jim_IncrRefCount(objPtr) \
415 ++(objPtr)->refCount
@@ -440,43 +446,40 @@
440 typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp,
441 struct Jim_Obj *srcPtr, Jim_Obj *dupPtr);
442 typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr);
443
444 typedef struct Jim_ObjType {
445 const char *name;
446 Jim_FreeInternalRepProc *freeIntRepProc;
447 Jim_DupInternalRepProc *dupIntRepProc;
448 Jim_UpdateStringProc *updateStringProc;
449 int flags;
450 } Jim_ObjType;
451
452
453 #define JIM_TYPE_NONE 0
454 #define JIM_TYPE_REFERENCES 1
455
456 #define JIM_PRIV_FLAG_SHIFT 20
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 int tailcall;
476 struct Jim_Obj *tailcallObj;
477 struct Jim_Cmd *tailcallCmd;
478 } Jim_CallFrame;
479
480 typedef struct Jim_Var {
481 Jim_Obj *objPtr;
482 struct Jim_CallFrame *linkFramePtr;
@@ -488,35 +491,35 @@
488 typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData);
489
490
491
492 typedef struct Jim_Cmd {
493 int inUse;
494 int isproc;
495 struct Jim_Cmd *prevCmd;
496 union {
497 struct {
498
499 Jim_CmdProc *cmdProc;
500 Jim_DelCmdProc *delProc;
501 void *privData;
502 } native;
503 struct {
504
505 Jim_Obj *argListObjPtr;
506 Jim_Obj *bodyObjPtr;
507 Jim_HashTable *staticVars;
508 int argListLen;
509 int reqArity;
510 int optArity;
511 int argsPos;
512 int upcall;
513 struct Jim_ProcArg {
514 Jim_Obj *nameObjPtr;
515 Jim_Obj *defaultObjPtr;
516 } *arglist;
517 Jim_Obj *nsObj;
518 } proc;
519 } u;
520 } Jim_Cmd;
521
522
@@ -524,64 +527,64 @@
524 unsigned char sbox[256];
525 unsigned int i, j;
526 } Jim_PrngState;
527
528 typedef struct Jim_Interp {
529 Jim_Obj *result;
530 int errorLine;
531 Jim_Obj *errorFileNameObj;
532 int addStackTrace;
533 int maxCallFrameDepth;
534 int maxEvalDepth;
535 int evalDepth;
536 int returnCode;
537 int returnLevel;
538 int exitCode;
539 long id;
540 int signal_level;
541 jim_wide sigmask;
542 int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask);
543 Jim_CallFrame *framePtr;
544 Jim_CallFrame *topFramePtr;
545 struct Jim_HashTable commands;
546 unsigned long procEpoch; /* Incremented every time the result
547 of procedures names lookup caching
548 may no longer be valid. */
549 unsigned long callFrameEpoch; /* Incremented every time a new
550 callframe is created. This id is used for the
551 'ID' field contained in the Jim_CallFrame
552 structure. */
553 int local;
554 Jim_Obj *liveList;
555 Jim_Obj *freeList;
556 Jim_Obj *currentScriptObj;
557 Jim_Obj *nullScriptObj;
558 Jim_Obj *emptyObj;
559 Jim_Obj *trueObj;
560 Jim_Obj *falseObj;
561 unsigned long referenceNextId;
562 struct Jim_HashTable references;
563 unsigned long lastCollectId; /* reference max Id of the last GC
564 execution. It's set to -1 while the collection
565 is running as sentinel to avoid to recursive
566 calls via the [collect] command inside
567 finalizers. */
568 time_t lastCollectTime;
569 Jim_Obj *stackTrace;
570 Jim_Obj *errorProc;
571 Jim_Obj *unknown;
572 int unknown_called;
573 int errorFlag;
574 void *cmdPrivData; /* Used to pass the private data pointer to
575 a command. It is set to what the user specified
576 via Jim_CreateCommand(). */
577
578 struct Jim_CallFrame *freeFramesList;
579 struct Jim_HashTable assocData;
580 Jim_PrngState *prngState;
581 struct Jim_HashTable packages;
582 Jim_Stack *loadHandles;
583 } Jim_Interp;
584
585 #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
586 #define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
587 #define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
@@ -737,12 +740,12 @@
737 JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...);
738
739
740 JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp);
741 JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp,
742 const char *cmdName, Jim_CmdProc cmdProc, void *privData,
743 Jim_DelCmdProc delProc);
744 JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp,
745 const char *cmdName);
746 JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp,
747 const char *oldName, const char *newName);
748 JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp,
@@ -832,10 +835,14 @@
832 JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp,
833 Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr);
834 JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp,
835 Jim_Obj *exprObjPtr, int *boolPtr);
836
 
 
 
 
837
838 JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr,
839 jim_wide *widePtr);
840 JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr,
841 long *longPtr);
@@ -853,12 +860,13 @@
853
854 JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc,
855 Jim_Obj *const *argv, const char *msg);
856 JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr,
857 const char * const *tablePtr, int *indexPtr, const char *name, int flags);
858 JIM_EXPORT int Jim_ScriptIsComplete (const char *s, int len,
859 char *stateCharPtr);
 
860 JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len);
861
862
863 typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data);
864 JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key);
@@ -904,11 +912,11 @@
904
905 #ifdef __cplusplus
906 }
907 #endif
908
909 #endif
910
911 #ifndef JIM_SUBCMD_H
912 #define JIM_SUBCMD_H
913
914
@@ -915,24 +923,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
@@ -960,36 +968,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
@@ -997,13 +1005,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,
@@ -1037,11 +1045,20 @@
1037 return JIM_ERR;
1038
1039 return Jim_EvalSource(interp, "bootstrap.tcl", 1,
1040 "\n"
1041 "\n"
1042 "proc package {args} {}\n"
 
 
 
 
 
 
 
 
 
1043 );
1044 }
1045 int Jim_initjimshInit(Jim_Interp *interp)
1046 {
1047 if (Jim_PackageProvide(interp, "initjimsh", "1.0", JIM_ERRMSG))
@@ -1771,10 +1788,11 @@
1771 "}\n"
1772 );
1773 }
1774
1775
 
1776 #include <stdio.h>
1777 #include <string.h>
1778 #include <errno.h>
1779 #include <fcntl.h>
1780 #ifdef HAVE_UNISTD_H
@@ -1793,13 +1811,18 @@
1793 #endif
1794 #else
1795 #define JIM_ANSIC
1796 #endif
1797
 
 
 
 
1798
1799 #define AIO_CMD_LEN 32
1800 #define AIO_BUF_LEN 256
 
1801
1802 #ifndef HAVE_FTELLO
1803 #define ftello ftell
1804 #endif
1805 #ifndef HAVE_FSEEKO
@@ -1815,66 +1838,61 @@
1815 #ifndef PF_INET6
1816 #define PF_INET6 0
1817 #endif
1818 #endif
1819
 
 
 
 
 
 
 
 
 
 
 
 
 
1820
1821 typedef struct AioFile
1822 {
1823 FILE *fp;
1824 Jim_Obj *filename;
1825 int type;
1826 int openFlags;
1827 int fd;
1828 Jim_Obj *rEvent;
1829 Jim_Obj *wEvent;
1830 Jim_Obj *eEvent;
1831 int addr_family;
 
 
1832 } AioFile;
1833
1834 static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
1835 static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
1836 const char *hdlfmt, int family, const char *mode);
1837
1838
1839 static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
1840 {
1841 if (name) {
1842 Jim_SetResultFormatted(interp, "%#s: %s", name, strerror(errno));
1843 }
1844 else {
1845 Jim_SetResultString(interp, strerror(errno), -1);
1846 }
1847 }
1848
1849 static void JimAioDelProc(Jim_Interp *interp, void *privData)
1850 {
1851 AioFile *af = privData;
1852
1853 JIM_NOTUSED(interp);
1854
1855 Jim_DecrRefCount(interp, af->filename);
1856
1857 #ifdef jim_ext_eventloop
1858
1859 Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION);
1860 #endif
1861
1862 if (!(af->openFlags & AIO_KEEPOPEN)) {
1863 fclose(af->fp);
1864 }
1865
1866 Jim_Free(af);
1867 }
1868
1869 static int JimCheckStreamError(Jim_Interp *interp, AioFile *af)
1870 {
1871 if (!ferror(af->fp)) {
1872 return JIM_OK;
1873 }
1874 clearerr(af->fp);
1875
1876 if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
1877 return JIM_OK;
1878 }
1879 #ifdef ECONNRESET
1880 if (errno == ECONNRESET) {
@@ -1884,21 +1902,86 @@
1884 #ifdef ECONNABORTED
1885 if (errno != ECONNABORTED) {
1886 return JIM_OK;
1887 }
1888 #endif
1889 JimAioSetError(interp, af->filename);
1890 return JIM_ERR;
1891 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1892
1893 static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1894 {
1895 AioFile *af = Jim_CmdPrivData(interp);
1896 char buf[AIO_BUF_LEN];
1897 Jim_Obj *objPtr;
1898 int nonewline = 0;
1899 jim_wide neededLen = -1;
1900
1901 if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
1902 nonewline = 1;
1903 argv++;
1904 argc--;
@@ -1923,21 +2006,21 @@
1923 readlen = AIO_BUF_LEN;
1924 }
1925 else {
1926 readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen);
1927 }
1928 retval = fread(buf, 1, readlen, af->fp);
1929 if (retval > 0) {
1930 Jim_AppendString(interp, objPtr, buf, retval);
1931 if (neededLen != -1) {
1932 neededLen -= retval;
1933 }
1934 }
1935 if (retval != readlen)
1936 break;
1937 }
1938
1939 if (JimCheckStreamError(interp, af)) {
1940 Jim_FreeNewObj(interp, objPtr);
1941 return JIM_ERR;
1942 }
1943 if (nonewline) {
@@ -1950,19 +2033,43 @@
1950 }
1951 }
1952 Jim_SetResult(interp, objPtr);
1953 return JIM_OK;
1954 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1955
1956 static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1957 {
1958 AioFile *af = Jim_CmdPrivData(interp);
1959 jim_wide count = 0;
1960 jim_wide maxlen = JIM_WIDE_MAX;
1961 FILE *outfh = Jim_AioFilehandle(interp, argv[0]);
1962
1963 if (outfh == NULL) {
1964 return JIM_ERR;
1965 }
1966
1967 if (argc == 2) {
1968 if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) {
@@ -1969,27 +2076,22 @@
1969 return JIM_ERR;
1970 }
1971 }
1972
1973 while (count < maxlen) {
1974 int ch = fgetc(af->fp);
1975
1976 if (ch == EOF || fputc(ch, outfh) == EOF) {
 
 
 
1977 break;
1978 }
1979 count++;
1980 }
1981
1982 if (ferror(af->fp)) {
1983 Jim_SetResultFormatted(interp, "error while reading: %s", strerror(errno));
1984 clearerr(af->fp);
1985 return JIM_ERR;
1986 }
1987
1988 if (ferror(outfh)) {
1989 Jim_SetResultFormatted(interp, "error while writing: %s", strerror(errno));
1990 clearerr(outfh);
1991 return JIM_ERR;
1992 }
1993
1994 Jim_SetResultInt(interp, count);
1995
@@ -2006,30 +2108,32 @@
2006 errno = 0;
2007
2008 objPtr = Jim_NewStringObj(interp, NULL, 0);
2009 while (1) {
2010 buf[AIO_BUF_LEN - 1] = '_';
2011 if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL)
 
2012 break;
2013
2014 if (buf[AIO_BUF_LEN - 1] == '\0' && buf[AIO_BUF_LEN - 2] != '\n') {
2015 Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN - 1);
2016 }
2017 else {
2018 len = strlen(buf);
2019
2020 if (len && (buf[len - 1] == '\n')) {
2021
2022 len--;
2023 }
2024
2025 Jim_AppendString(interp, objPtr, buf, len);
2026 break;
2027 }
2028 }
 
2029 if (JimCheckStreamError(interp, af)) {
2030
2031 Jim_FreeNewObj(interp, objPtr);
2032 return JIM_ERR;
2033 }
2034
2035 if (argc) {
@@ -2039,11 +2143,11 @@
2039 }
2040
2041 len = Jim_Length(objPtr);
2042
2043 if (len == 0 && feof(af->fp)) {
2044
2045 len = -1;
2046 }
2047 Jim_SetResultInt(interp, len);
2048 }
2049 else {
@@ -2068,12 +2172,12 @@
2068 else {
2069 strObj = argv[0];
2070 }
2071
2072 wdata = Jim_GetString(strObj, &wlen);
2073 if (fwrite(wdata, 1, wlen, af->fp) == (unsigned)wlen) {
2074 if (argc == 2 || putc('\n', af->fp) != EOF) {
2075 return JIM_OK;
2076 }
2077 }
2078 JimAioSetError(interp, af->filename);
2079 return JIM_ERR;
@@ -2202,10 +2306,21 @@
2202 }
2203 Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0);
2204 return JIM_OK;
2205 }
2206 #endif
 
 
 
 
 
 
 
 
 
 
 
2207
2208 static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2209 {
2210 AioFile *af = Jim_CmdPrivData(interp);
2211
@@ -2258,33 +2373,33 @@
2258
2259 static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj,
2260 int argc, Jim_Obj * const *argv)
2261 {
2262 if (argc == 0) {
2263
2264 if (*scriptHandlerObj) {
2265 Jim_SetResult(interp, *scriptHandlerObj);
2266 }
2267 return JIM_OK;
2268 }
2269
2270 if (*scriptHandlerObj) {
2271
2272 Jim_DeleteFileHandler(interp, af->fp, mask);
2273 }
2274
2275
2276 if (Jim_Length(argv[0]) == 0) {
2277
2278 return JIM_OK;
2279 }
2280
2281
2282 Jim_IncrRefCount(argv[0]);
2283 *scriptHandlerObj = argv[0];
2284
2285 Jim_CreateFileHandler(interp, af->fp, mask,
2286 JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer);
2287
2288 return JIM_OK;
2289 }
2290
@@ -2307,127 +2422,138 @@
2307 AioFile *af = Jim_CmdPrivData(interp);
2308
2309 return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv);
2310 }
2311 #endif
 
 
2312
2313 static const jim_subcmd_type aio_command_table[] = {
2314 { "read",
2315 "?-nonewline? ?len?",
2316 aio_cmd_read,
2317 0,
2318 2,
2319
2320 },
2321 { "copyto",
2322 "handle ?size?",
2323 aio_cmd_copy,
2324 1,
2325 2,
2326
2327 },
2328 { "gets",
2329 "?var?",
2330 aio_cmd_gets,
2331 0,
2332 1,
2333
2334 },
2335 { "puts",
2336 "?-nonewline? str",
2337 aio_cmd_puts,
2338 1,
2339 2,
2340
2341 },
2342 { "isatty",
2343 NULL,
2344 aio_cmd_isatty,
2345 0,
2346 0,
2347
2348 },
2349 { "flush",
2350 NULL,
2351 aio_cmd_flush,
2352 0,
2353 0,
2354
2355 },
2356 { "eof",
2357 NULL,
2358 aio_cmd_eof,
2359 0,
2360 0,
2361
2362 },
2363 { "close",
2364 "?r(ead)|w(rite)?",
2365 aio_cmd_close,
2366 0,
2367 1,
2368 JIM_MODFLAG_FULLARGV,
2369
2370 },
2371 { "seek",
2372 "offset ?start|current|end",
2373 aio_cmd_seek,
2374 1,
2375 2,
2376
2377 },
2378 { "tell",
2379 NULL,
2380 aio_cmd_tell,
2381 0,
2382 0,
2383
2384 },
2385 { "filename",
2386 NULL,
2387 aio_cmd_filename,
2388 0,
2389 0,
2390
2391 },
2392 #ifdef O_NDELAY
2393 { "ndelay",
2394 "?0|1?",
2395 aio_cmd_ndelay,
2396 0,
2397 1,
2398
 
 
 
 
 
 
 
 
 
2399 },
2400 #endif
2401 { "buffering",
2402 "none|line|full",
2403 aio_cmd_buffering,
2404 1,
2405 1,
2406
2407 },
2408 #ifdef jim_ext_eventloop
2409 { "readable",
2410 "?readable-script?",
2411 aio_cmd_readable,
2412 0,
2413 1,
2414
2415 },
2416 { "writable",
2417 "?writable-script?",
2418 aio_cmd_writable,
2419 0,
2420 1,
2421
2422 },
2423 { "onexception",
2424 "?exception-script?",
2425 aio_cmd_onexception,
2426 0,
2427 1,
2428
2429 },
2430 #endif
2431 { NULL }
2432 };
2433
@@ -2450,11 +2576,11 @@
2450
2451 #ifdef jim_ext_tclcompat
2452 {
2453 const char *filename = Jim_String(argv[1]);
2454
2455
2456 if (*filename == '|') {
2457 Jim_Obj *evalObj[3];
2458
2459 evalObj[0] = Jim_NewStringObj(interp, "::popen", -1);
2460 evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1);
@@ -2462,24 +2588,31 @@
2462
2463 return Jim_EvalObjVector(interp, 3, evalObj);
2464 }
2465 }
2466 #endif
2467 return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode);
2468 }
2469
2470 static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
 
2471 const char *hdlfmt, int family, const char *mode)
2472 {
2473 AioFile *af;
2474 char buf[AIO_CMD_LEN];
2475 int openFlags = 0;
2476
 
 
2477 if (fh) {
2478 filename = Jim_NewStringObj(interp, hdlfmt, -1);
2479 openFlags = AIO_KEEPOPEN;
2480 }
 
 
 
 
 
2481
2482 Jim_IncrRefCount(filename);
2483
2484 if (fh == NULL) {
2485 #if !defined(JIM_ANSIC)
@@ -2496,15 +2629,15 @@
2496 if (fd >= 0) {
2497 close(fd);
2498 }
2499 #endif
2500 Jim_DecrRefCount(interp, filename);
2501 return JIM_ERR;
2502 }
2503 }
2504
2505
2506 af = Jim_Alloc(sizeof(*af));
2507 memset(af, 0, sizeof(*af));
2508 af->fp = fh;
2509 af->fd = fileno(fh);
2510 af->filename = filename;
@@ -2513,34 +2646,36 @@
2513 (void)fcntl(af->fd, F_SETFD, FD_CLOEXEC);
2514 }
2515 #endif
2516 af->openFlags = openFlags;
2517 af->addr_family = family;
2518 snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
 
 
2519 Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc);
2520
2521 Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
2522
2523 return JIM_OK;
2524 }
2525
2526 #if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H))
2527 static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename,
2528 const char *hdlfmt, int family, const char *mode[2])
2529 {
2530 if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) {
2531 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
2532 Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
2533
2534 if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1]) == JIM_OK) {
2535 Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
2536 Jim_SetResult(interp, objPtr);
2537 return JIM_OK;
2538 }
2539 }
2540
2541
2542 close(p[0]);
2543 close(p[1]);
2544 JimAioSetError(interp, NULL);
2545 return JIM_ERR;
2546 }
@@ -2567,13 +2702,18 @@
2567 }
2568 else {
2569 filenameObj = Jim_NewStringObj(interp, template, -1);
2570 }
2571
 
2572 mask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
 
2573
2574
 
 
 
2575 fd = mkstemp(filenameObj->bytes);
2576 umask(mask);
2577 if (fd < 0) {
2578 JimAioSetError(interp, filenameObj);
2579 Jim_FreeNewObj(interp, filenameObj);
@@ -2586,33 +2726,26 @@
2586 Jim_SetResultString(interp, "platform has no tempfile support", -1);
2587 return -1;
2588 #endif
2589 }
2590
2591 FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
2592 {
2593 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG);
2594
2595
2596 if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) {
2597 return ((AioFile *) cmdPtr->u.native.privData)->fp;
2598 }
2599 Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command);
2600 return NULL;
2601 }
2602
2603 int Jim_aioInit(Jim_Interp *interp)
2604 {
2605 if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG))
2606 return JIM_ERR;
 
 
 
 
2607
2608 Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL);
2609 #ifndef JIM_ANSIC
2610 Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL);
2611 #endif
2612
2613
2614 JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r");
2615 JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w");
2616 JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w");
2617
2618 return JIM_OK;
@@ -2708,20 +2841,20 @@
2708 {
2709 regex_t *compre;
2710 const char *pattern;
2711 int ret;
2712
2713
2714 if (objPtr->typePtr == &regexpObjType &&
2715 objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) {
2716
2717 return objPtr->internalRep.regexpValue.compre;
2718 }
2719
2720
2721
2722
 
2723 pattern = Jim_String(objPtr);
2724 compre = Jim_Alloc(sizeof(regex_t));
2725
2726 if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) {
2727 char buf[100];
@@ -2769,11 +2902,11 @@
2769 };
2770
2771 if (argc < 3) {
2772 wrongNumArgs:
2773 Jim_WrongNumArgs(interp, 1, argv,
2774 "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
2775 return JIM_ERR;
2776 }
2777
2778 for (i = 1; i < argc; i++) {
2779 const char *opt = Jim_String(argv[i]);
@@ -2878,11 +3011,11 @@
2878 }
2879
2880 num_matches++;
2881
2882 if (opt_all && !opt_inline) {
2883
2884 goto try_next_match;
2885 }
2886
2887
2888 j = 0;
@@ -2918,11 +3051,11 @@
2918
2919 if (opt_inline) {
2920 Jim_ListAppendElement(interp, resultListObj, resultObj);
2921 }
2922 else {
2923
2924 result = Jim_SetVariable(interp, argv[i], resultObj);
2925
2926 if (result != JIM_OK) {
2927 Jim_FreeObj(interp, resultObj);
2928 break;
@@ -2991,11 +3124,11 @@
2991 };
2992
2993 if (argc < 4) {
2994 wrongNumArgs:
2995 Jim_WrongNumArgs(interp, 1, argv,
2996 "?switches? exp string subSpec ?varName?");
2997 return JIM_ERR;
2998 }
2999
3000 for (i = 1; i < argc; i++) {
3001 const char *opt = Jim_String(argv[i]);
@@ -3045,11 +3178,11 @@
3045
3046 source_str = Jim_GetString(argv[i + 1], &source_len);
3047 replace_str = Jim_GetString(argv[i + 2], &replace_len);
3048 varname = argv[i + 3];
3049
3050
3051 resultObj = Jim_NewStringObj(interp, "", 0);
3052
3053 if (offset) {
3054 if (offset < 0) {
3055 offset += source_len + 1;
@@ -3060,11 +3193,11 @@
3060 else if (offset < 0) {
3061 offset = 0;
3062 }
3063 }
3064
3065
3066 Jim_AppendString(interp, resultObj, source_str, offset);
3067
3068
3069 n = source_len - offset;
3070 p = source_str + offset;
@@ -3102,11 +3235,11 @@
3102 else if ((c == '\\') || (c == '&')) {
3103 Jim_AppendString(interp, resultObj, replace_str + j, 1);
3104 continue;
3105 }
3106 else {
3107 Jim_AppendString(interp, resultObj, replace_str + j - 1, 2);
3108 continue;
3109 }
3110 }
3111 else {
3112 Jim_AppendString(interp, resultObj, replace_str + j, 1);
@@ -3119,23 +3252,23 @@
3119 }
3120
3121 p += pmatch[0].rm_eo;
3122 n -= pmatch[0].rm_eo;
3123
3124
3125 if (!opt_all || n == 0) {
3126 break;
3127 }
3128
3129
3130 if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') {
3131 break;
3132 }
3133
3134
3135 if (pattern[0] == '\0' && n) {
3136
3137 Jim_AppendString(interp, resultObj, p, 1);
3138 p++;
3139 n--;
3140 }
3141
@@ -3142,11 +3275,11 @@
3142 regexec_flags |= REG_NOTBOL;
3143 } while (n);
3144
3145 Jim_AppendString(interp, resultObj, p, -1);
3146
3147
3148 if (argc - i == 4) {
3149 result = Jim_SetVariable(interp, varname, resultObj);
3150
3151 if (result == JIM_OK) {
3152 Jim_SetResultInt(interp, num_matches);
@@ -3248,11 +3381,11 @@
3248 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value));
3249 }
3250
3251 static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
3252 {
3253
3254 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
3255
3256 AppendStatElement(interp, listObj, "dev", sb->st_dev);
3257 AppendStatElement(interp, listObj, "ino", sb->st_ino);
3258 AppendStatElement(interp, listObj, "mode", sb->st_mode);
@@ -3264,25 +3397,25 @@
3264 AppendStatElement(interp, listObj, "mtime", sb->st_mtime);
3265 AppendStatElement(interp, listObj, "ctime", sb->st_ctime);
3266 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1));
3267 Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1));
3268
3269
3270 if (varName) {
3271 Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE);
3272 if (objPtr) {
3273 if (Jim_DictSize(interp, objPtr) < 0) {
3274
3275 Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
3276 Jim_FreeNewObj(interp, listObj);
3277 return JIM_ERR;
3278 }
3279
3280 if (Jim_IsShared(objPtr))
3281 objPtr = Jim_DuplicateObj(interp, objPtr);
3282
3283
3284 Jim_ListAppendList(interp, objPtr, listObj);
3285 Jim_DictSize(interp, objPtr);
3286 Jim_InvalidateStringRep(objPtr);
3287
3288 Jim_FreeNewObj(interp, listObj);
@@ -3289,11 +3422,11 @@
3289 listObj = objPtr;
3290 }
3291 Jim_SetVariable(interp, varName, listObj);
3292 }
3293
3294
3295 Jim_SetResult(interp, listObj);
3296
3297 return JIM_OK;
3298 }
3299
@@ -3309,11 +3442,11 @@
3309 }
3310 else if (p == path) {
3311 Jim_SetResultString(interp, "/", -1);
3312 }
3313 else if (ISWINDOWS && p[-1] == ':') {
3314
3315 Jim_SetResultString(interp, path, p - path + 1);
3316 }
3317 else {
3318 Jim_SetResultString(interp, path, p - path);
3319 }
@@ -3389,35 +3522,35 @@
3389 char *newname = Jim_Alloc(MAXPATHLEN + 1);
3390 char *last = newname;
3391
3392 *newname = 0;
3393
3394
3395 for (i = 0; i < argc; i++) {
3396 int len;
3397 const char *part = Jim_GetString(argv[i], &len);
3398
3399 if (*part == '/') {
3400
3401 last = newname;
3402 }
3403 else if (ISWINDOWS && strchr(part, ':')) {
3404
3405 last = newname;
3406 }
3407 else if (part[0] == '.') {
3408 if (part[1] == '/') {
3409 part += 2;
3410 len -= 2;
3411 }
3412 else if (part[1] == 0 && last != newname) {
3413
3414 continue;
3415 }
3416 }
3417
3418
3419 if (last != newname && last[-1] != '/') {
3420 *last++ = '/';
3421 }
3422
3423 if (len) {
@@ -3428,22 +3561,22 @@
3428 }
3429 memcpy(last, part, len);
3430 last += len;
3431 }
3432
3433
3434 if (last > newname + 1 && last[-1] == '/') {
3435
3436 if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) {
3437 *--last = 0;
3438 }
3439 }
3440 }
3441
3442 *last = 0;
3443
3444
3445
3446 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname));
3447
3448 return JIM_OK;
3449 }
@@ -3468,11 +3601,11 @@
3468 static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3469 {
3470 #ifdef X_OK
3471 return file_access(interp, argv[0], X_OK);
3472 #else
3473
3474 Jim_SetResultBool(interp, 1);
3475 return JIM_OK;
3476 #endif
3477 }
3478
@@ -3493,11 +3626,11 @@
3493 while (argc--) {
3494 const char *path = Jim_String(argv[0]);
3495
3496 if (unlink(path) == -1 && errno != ENOENT) {
3497 if (rmdir(path) == -1) {
3498
3499 if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) {
3500 Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path,
3501 strerror(errno));
3502 return JIM_ERR;
3503 }
@@ -3516,15 +3649,15 @@
3516
3517 static int mkdir_all(char *path)
3518 {
3519 int ok = 1;
3520
3521
3522 goto first;
3523
3524 while (ok--) {
3525
3526 {
3527 char *slash = strrchr(path, '/');
3528
3529 if (slash && slash != path) {
3530 *slash = 0;
@@ -3537,24 +3670,24 @@
3537 first:
3538 if (MKDIR_DEFAULT(path) == 0) {
3539 return 0;
3540 }
3541 if (errno == ENOENT) {
3542
3543 continue;
3544 }
3545
3546 if (errno == EEXIST) {
3547 struct stat sb;
3548
3549 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
3550 return 0;
3551 }
3552
3553 errno = EEXIST;
3554 }
3555
3556 break;
3557 }
3558 return -1;
3559 }
3560
@@ -3839,192 +3972,192 @@
3839 { "atime",
3840 "name",
3841 file_cmd_atime,
3842 1,
3843 1,
3844
3845 },
3846 { "mtime",
3847 "name ?time?",
3848 file_cmd_mtime,
3849 1,
3850 2,
3851
3852 },
3853 { "copy",
3854 "?-force? source dest",
3855 file_cmd_copy,
3856 2,
3857 3,
3858
3859 },
3860 { "dirname",
3861 "name",
3862 file_cmd_dirname,
3863 1,
3864 1,
3865
3866 },
3867 { "rootname",
3868 "name",
3869 file_cmd_rootname,
3870 1,
3871 1,
3872
3873 },
3874 { "extension",
3875 "name",
3876 file_cmd_extension,
3877 1,
3878 1,
3879
3880 },
3881 { "tail",
3882 "name",
3883 file_cmd_tail,
3884 1,
3885 1,
3886
3887 },
3888 { "normalize",
3889 "name",
3890 file_cmd_normalize,
3891 1,
3892 1,
3893
3894 },
3895 { "join",
3896 "name ?name ...?",
3897 file_cmd_join,
3898 1,
3899 -1,
3900
3901 },
3902 { "readable",
3903 "name",
3904 file_cmd_readable,
3905 1,
3906 1,
3907
3908 },
3909 { "writable",
3910 "name",
3911 file_cmd_writable,
3912 1,
3913 1,
3914
3915 },
3916 { "executable",
3917 "name",
3918 file_cmd_executable,
3919 1,
3920 1,
3921
3922 },
3923 { "exists",
3924 "name",
3925 file_cmd_exists,
3926 1,
3927 1,
3928
3929 },
3930 { "delete",
3931 "?-force|--? name ...",
3932 file_cmd_delete,
3933 1,
3934 -1,
3935
3936 },
3937 { "mkdir",
3938 "dir ...",
3939 file_cmd_mkdir,
3940 1,
3941 -1,
3942
3943 },
3944 { "tempfile",
3945 "?template?",
3946 file_cmd_tempfile,
3947 0,
3948 1,
3949
3950 },
3951 { "rename",
3952 "?-force? source dest",
3953 file_cmd_rename,
3954 2,
3955 3,
3956
3957 },
3958 #if defined(HAVE_LINK) && defined(HAVE_SYMLINK)
3959 { "link",
3960 "?-symbolic|-hard? newname target",
3961 file_cmd_link,
3962 2,
3963 3,
3964
3965 },
3966 #endif
3967 #if defined(HAVE_READLINK)
3968 { "readlink",
3969 "name",
3970 file_cmd_readlink,
3971 1,
3972 1,
3973
3974 },
3975 #endif
3976 { "size",
3977 "name",
3978 file_cmd_size,
3979 1,
3980 1,
3981
3982 },
3983 { "stat",
3984 "name ?var?",
3985 file_cmd_stat,
3986 1,
3987 2,
3988
3989 },
3990 { "lstat",
3991 "name ?var?",
3992 file_cmd_lstat,
3993 1,
3994 2,
3995
3996 },
3997 { "type",
3998 "name",
3999 file_cmd_type,
4000 1,
4001 1,
4002
4003 },
4004 #ifdef HAVE_GETEUID
4005 { "owned",
4006 "name",
4007 file_cmd_owned,
4008 1,
4009 1,
4010
4011 },
4012 #endif
4013 { "isdirectory",
4014 "name",
4015 file_cmd_isdirectory,
4016 1,
4017 1,
4018
4019 },
4020 { "isfile",
4021 "name",
4022 file_cmd_isfile,
4023 1,
4024 1,
4025
4026 },
4027 {
4028 NULL
4029 }
4030 };
@@ -4056,11 +4189,11 @@
4056 Jim_SetResultString(interp, "Failed to get pwd", -1);
4057 Jim_Free(cwd);
4058 return JIM_ERR;
4059 }
4060 else if (ISWINDOWS) {
4061
4062 char *p = cwd;
4063 while ((p = strchr(p, '\\')) != NULL) {
4064 *p++ = '/';
4065 }
4066 }
@@ -4080,10 +4213,11 @@
4080 Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL);
4081 Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL);
4082 return JIM_OK;
4083 }
4084
 
4085 #include <string.h>
4086 #include <ctype.h>
4087
4088
4089 #if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__)
@@ -4091,20 +4225,20 @@
4091 {
4092 Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp);
4093 int i, j;
4094 int rc;
4095
4096
4097 for (i = 1; i < argc; i++) {
4098 int len;
4099 const char *arg = Jim_GetString(argv[i], &len);
4100
4101 if (i > 1) {
4102 Jim_AppendString(interp, cmdlineObj, " ", 1);
4103 }
4104 if (strpbrk(arg, "\\\" ") == NULL) {
4105
4106 Jim_AppendString(interp, cmdlineObj, arg, len);
4107 continue;
4108 }
4109
4110 Jim_AppendString(interp, cmdlineObj, "\"", 1);
@@ -4145,11 +4279,11 @@
4145
4146 #include <errno.h>
4147 #include <signal.h>
4148
4149 #if defined(__MINGW32__)
4150
4151 #ifndef STRICT
4152 #define STRICT
4153 #endif
4154 #define WIN32_LEAN_AND_MEAN
4155 #include <windows.h>
@@ -4205,11 +4339,11 @@
4205 static char **JimSaveEnv(char **env);
4206 static void JimRestoreEnv(char **env);
4207 static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv,
4208 pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr);
4209 static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr);
4210 static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId);
4211 static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len);
4212 static fdtype JimOpenForWrite(const char *filename, int append);
4213 static int JimRewindFd(fdtype fd);
4214
4215 static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
@@ -4235,26 +4369,28 @@
4235
4236 static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj)
4237 {
4238 char buf[256];
4239 FILE *fh = JimFdOpenForRead(fd);
 
 
4240 if (fh == NULL) {
4241 return JIM_ERR;
4242 }
4243
4244 while (1) {
4245 int retval = fread(buf, 1, sizeof(buf), fh);
4246 if (retval > 0) {
 
4247 Jim_AppendString(interp, strObj, buf, retval);
4248 }
4249 if (retval != sizeof(buf)) {
4250 break;
4251 }
4252 }
4253 Jim_RemoveTrailingNewline(strObj);
4254 fclose(fh);
4255 return JIM_OK;
4256 }
4257
4258 static char **JimBuildEnv(Jim_Interp *interp)
4259 {
4260 int i;
@@ -4269,14 +4405,14 @@
4269 if (!objPtr) {
4270 return Jim_GetEnviron();
4271 }
4272
4273
4274
4275 num = Jim_ListLength(interp, objPtr);
4276 if (num % 2) {
4277
4278 num--;
4279 }
4280 size = Jim_Length(objPtr) + 2;
4281
4282 envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
@@ -4308,25 +4444,38 @@
4308 if (env != original_environ) {
4309 Jim_Free(env);
4310 }
4311 }
4312
4313 static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus)
 
 
4314 {
4315 Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0);
4316 int rc = JIM_ERR;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4317
4318 if (WIFEXITED(waitStatus)) {
4319 if (WEXITSTATUS(waitStatus) == 0) {
4320 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1));
4321 rc = JIM_OK;
4322 }
4323 else {
4324 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
4325 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4326 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
4327 }
4328 }
4329 else {
4330 const char *type;
4331 const char *action;
4332
@@ -4339,38 +4488,35 @@
4339 action = "suspended";
4340 }
4341
4342 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));
4343
4344 #ifdef jim_ext_signal
4345 Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus)));
 
 
 
4346 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
4347 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid));
4348 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
4349 #else
4350 Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus));
4351 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
4352 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4353 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
4354 #endif
4355 }
4356 Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
4357 return rc;
 
4358 }
4359
4360
4361 struct WaitInfo
4362 {
4363 pidtype pid;
4364 int status;
4365 int flags;
4366 };
4367
4368 struct WaitInfoTable {
4369 struct WaitInfo *info;
4370 int size;
4371 int used;
4372 };
4373
4374
4375 #define WI_DETACHED 2
4376
@@ -4393,14 +4539,17 @@
4393 return table;
4394 }
4395
4396 static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
4397 {
4398 fdtype outputId;
4399 fdtype errorId;
4400 pidtype *pidPtr;
4401 int numPids, result;
 
 
 
4402
4403 if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) {
4404 Jim_Obj *listObj;
4405 int i;
4406
@@ -4407,11 +4556,11 @@
4407 argc--;
4408 numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL);
4409 if (numPids < 0) {
4410 return JIM_ERR;
4411 }
4412
4413 listObj = Jim_NewListObj(interp, NULL, 0);
4414 for (i = 0; i < numPids; i++) {
4415 Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i]));
4416 }
4417 Jim_SetResult(interp, listObj);
@@ -4425,23 +4574,56 @@
4425
4426 if (numPids < 0) {
4427 return JIM_ERR;
4428 }
4429
4430 Jim_SetResultString(interp, "", 0);
4431
4432 result = JIM_OK;
 
 
 
 
4433 if (outputId != JIM_BAD_FD) {
4434 result = JimAppendStreamToString(interp, outputId, Jim_GetResult(interp));
4435 if (result < 0) {
4436 Jim_SetResultErrno(interp, "error reading from output pipe");
4437 }
4438 }
4439
4440 if (JimCleanupChildren(interp, numPids, pidPtr, errorId) != JIM_OK) {
 
 
 
 
4441 result = JIM_ERR;
4442 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4443 return result;
4444 }
4445
4446 static void JimReapDetachedPids(struct WaitInfoTable *table)
4447 {
@@ -4458,11 +4640,11 @@
4458 for (count = table->used; count > 0; waitPtr++, count--) {
4459 if (waitPtr->flags & WI_DETACHED) {
4460 int status;
4461 pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG);
4462 if (pid == waitPtr->pid) {
4463
4464 table->used--;
4465 continue;
4466 }
4467 }
4468 if (waitPtr != &table->info[dest]) {
@@ -4474,36 +4656,36 @@
4474
4475 static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr)
4476 {
4477 int i;
4478
4479
4480 for (i = 0; i < table->used; i++) {
4481 if (pid == table->info[i].pid) {
4482
4483 JimWaitPid(pid, statusPtr, 0);
4484
4485
4486 if (i != table->used - 1) {
4487 table->info[i] = table->info[table->used - 1];
4488 }
4489 table->used--;
4490 return pid;
4491 }
4492 }
4493
4494
4495 return JIM_BAD_PID;
4496 }
4497
4498 static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr)
4499 {
4500 int j;
4501 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4502
4503 for (j = 0; j < numPids; j++) {
4504
4505 int i;
4506 for (i = 0; i < table->used; i++) {
4507 if (pidPtr[j] == table->info[i].pid) {
4508 table->info[i].flags |= WI_DETACHED;
4509 break;
@@ -4536,16 +4718,16 @@
4536 int cmdCount; /* Count of number of distinct commands
4537 * found in argc/argv. */
4538 const char *input = NULL; /* Describes input for pipeline, depending
4539 * on "inputFile". NULL means take input
4540 * from stdin/pipe. */
4541 int input_len = 0;
4542
4543 #define FILE_NAME 0
4544 #define FILE_APPEND 1
4545 #define FILE_HANDLE 2
4546 #define FILE_TEXT 3
4547
4548 int inputFile = FILE_NAME; /* 1 means input is name of input file.
4549 * 2 means input is filehandle name.
4550 * 0 means input holds actual
4551 * text to be input to command. */
@@ -4566,20 +4748,20 @@
4566 * or NULL if stderr goes to stderr/pipe. */
4567 fdtype inputId = JIM_BAD_FD;
4568 fdtype outputId = JIM_BAD_FD;
4569 fdtype errorId = JIM_BAD_FD;
4570 fdtype lastOutputId = JIM_BAD_FD;
4571 fdtype pipeIds[2];
4572 int firstArg, lastArg; /* Indexes of first and last arguments in
4573 * current command. */
4574 int lastBar;
4575 int i;
4576 pidtype pid;
4577 char **save_environ;
4578 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4579
4580
4581 char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1));
4582 int arg_count = 0;
4583
4584 JimReapDetachedPids(table);
4585
@@ -4625,11 +4807,11 @@
4625 if (*output == '>') {
4626 outputFile = FILE_APPEND;
4627 output++;
4628 }
4629 if (*output == '&') {
4630
4631 output++;
4632 dup_error = 1;
4633 }
4634 if (*output == '@') {
4635 outputFile = FILE_HANDLE;
@@ -4666,11 +4848,11 @@
4666 goto badargs;
4667 }
4668 lastBar = i;
4669 cmdCount++;
4670 }
4671
4672 arg_array[arg_count++] = (char *)arg;
4673 continue;
4674 }
4675
4676 if (i >= argc) {
@@ -4684,11 +4866,11 @@
4684 badargs:
4685 Jim_Free(arg_array);
4686 return -1;
4687 }
4688
4689
4690 save_environ = JimSaveEnv(JimBuildEnv(interp));
4691
4692 if (input != NULL) {
4693 if (inputFile == FILE_TEXT) {
4694 inputId = JimCreateTemp(interp, input, input_len);
@@ -4695,11 +4877,11 @@
4695 if (inputId == JIM_BAD_FD) {
4696 goto error;
4697 }
4698 }
4699 else if (inputFile == FILE_HANDLE) {
4700
4701 FILE *fh = JimGetAioFilehandle(interp, input);
4702
4703 if (fh == NULL) {
4704 goto error;
4705 }
@@ -4747,20 +4929,20 @@
4747 }
4748 lastOutputId = pipeIds[1];
4749 *outPipePtr = pipeIds[0];
4750 pipeIds[0] = pipeIds[1] = JIM_BAD_FD;
4751 }
4752
4753 if (error != NULL) {
4754 if (errorFile == FILE_HANDLE) {
4755 if (strcmp(error, "1") == 0) {
4756
4757 if (lastOutputId != JIM_BAD_FD) {
4758 errorId = JimDupFd(lastOutputId);
4759 }
4760 else {
4761
4762 error = "stdout";
4763 }
4764 }
4765 if (errorId == JIM_BAD_FD) {
4766 FILE *fh = JimGetAioFilehandle(interp, error);
@@ -4802,11 +4984,11 @@
4802 pipe_dup_err = 1;
4803 }
4804 break;
4805 }
4806 }
4807
4808 arg_array[lastArg] = NULL;
4809 if (lastArg == arg_count) {
4810 outputId = lastOutputId;
4811 }
4812 else {
@@ -4815,16 +4997,16 @@
4815 goto error;
4816 }
4817 outputId = pipeIds[1];
4818 }
4819
4820
4821 if (pipe_dup_err) {
4822 errorId = outputId;
4823 }
4824
4825
4826
4827 #ifdef __MINGW32__
4828 pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId);
4829 if (pid == JIM_BAD_PID) {
4830 Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -4835,32 +5017,32 @@
4835 if (pid < 0) {
4836 Jim_SetResultErrno(interp, "couldn't fork child process");
4837 goto error;
4838 }
4839 if (pid == 0) {
4840
4841
4842 if (inputId != -1) dup2(inputId, 0);
4843 if (outputId != -1) dup2(outputId, 1);
4844 if (errorId != -1) dup2(errorId, 2);
4845
4846 for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) {
4847 close(i);
4848 }
4849
4850
4851 (void)signal(SIGPIPE, SIG_DFL);
4852
4853 execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
4854
4855
4856 fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]);
4857 _exit(127);
4858 }
4859 #endif
4860
4861
4862
4863 if (table->used == table->size) {
4864 table->size += WAIT_TABLE_GROW_BY;
4865 table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info));
4866 }
@@ -4869,11 +5051,11 @@
4869 table->info[table->used].flags = 0;
4870 table->used++;
4871
4872 pidPtr[numPids] = pid;
4873
4874
4875 errorId = origErrorId;
4876
4877
4878 if (inputId != JIM_BAD_FD) {
4879 JimCloseFd(inputId);
@@ -4934,35 +5116,27 @@
4934 numPids = -1;
4935 goto cleanup;
4936 }
4937
4938
4939 static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, fdtype errorId)
4940 {
4941 struct WaitInfoTable *table = Jim_CmdPrivData(interp);
4942 int result = JIM_OK;
4943 int i;
 
4944
4945 for (i = 0; i < numPids; i++) {
4946 int waitStatus = 0;
4947 if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) {
4948 if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus) != JIM_OK) {
4949 result = JIM_ERR;
4950 }
4951 }
4952 }
4953 Jim_Free(pidPtr);
4954
4955 if (errorId != JIM_BAD_FD) {
4956 JimRewindFd(errorId);
4957 if (JimAppendStreamToString(interp, errorId, Jim_GetResult(interp)) != JIM_OK) {
4958 result = JIM_ERR;
4959 }
4960 }
4961
4962 Jim_RemoveTrailingNewline(Jim_GetResult(interp));
4963
4964 return result;
4965 }
4966
4967 int Jim_execInit(Jim_Interp *interp)
4968 {
@@ -5121,17 +5295,21 @@
5121 }
5122
5123 static fdtype JimOpenForRead(const char *filename)
5124 {
5125 return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
5126 JimStdSecAttrs(), OPEN_EXISTING, 0, NULL);
5127 }
5128
5129 static fdtype JimOpenForWrite(const char *filename, int append)
5130 {
5131 return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
5132 JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL);
 
 
 
 
5133 }
5134
5135 static FILE *JimFdOpenForWrite(fdtype fd)
5136 {
5137 return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w");
@@ -5139,11 +5317,11 @@
5139
5140 static pidtype JimWaitPid(pidtype pid, int *status, int nohang)
5141 {
5142 DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE);
5143 if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) {
5144
5145 return JIM_BAD_PID;
5146 }
5147 GetExitCodeProcess(pid, &ret);
5148 *status = ret;
5149 CloseHandle(pid);
@@ -5166,11 +5344,11 @@
5166 if (handle == INVALID_HANDLE_VALUE) {
5167 goto error;
5168 }
5169
5170 if (contents != NULL) {
5171
5172 FILE *fh = JimFdOpenForWrite(JimDupFd(handle));
5173 if (fh == NULL) {
5174 goto error;
5175 }
5176
@@ -5195,12 +5373,11 @@
5195 {
5196 int i;
5197 static char extensions[][5] = {".exe", "", ".bat"};
5198
5199 for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
5200 lstrcpyn(fullPath, originalName, MAX_PATH - 5);
5201 lstrcat(fullPath, extensions[i]);
5202
5203 if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) {
5204 continue;
5205 }
5206 if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) {
@@ -5439,11 +5616,11 @@
5439 #include <sys/time.h>
5440 #endif
5441
5442 static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5443 {
5444
5445 char buf[100];
5446 time_t t;
5447 long seconds;
5448
5449 const char *format = "%a %b %d %H:%M:%S %Z %Y";
@@ -5480,20 +5657,20 @@
5480
5481 if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) {
5482 return -1;
5483 }
5484
5485
5486 localtime_r(&now, &tm);
5487
5488 pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm);
5489 if (pt == 0 || *pt != 0) {
5490 Jim_SetResultString(interp, "Failed to parse time according to format", -1);
5491 return JIM_ERR;
5492 }
5493
5494
5495 Jim_SetResultInt(interp, mktime(&tm));
5496
5497 return JIM_OK;
5498 }
5499 #endif
@@ -5531,47 +5708,47 @@
5531 { "seconds",
5532 NULL,
5533 clock_cmd_seconds,
5534 0,
5535 0,
5536
5537 },
5538 { "clicks",
5539 NULL,
5540 clock_cmd_micros,
5541 0,
5542 0,
5543
5544 },
5545 { "microseconds",
5546 NULL,
5547 clock_cmd_micros,
5548 0,
5549 0,
5550
5551 },
5552 { "milliseconds",
5553 NULL,
5554 clock_cmd_millis,
5555 0,
5556 0,
5557
5558 },
5559 { "format",
5560 "seconds ?-format format?",
5561 clock_cmd_format,
5562 1,
5563 3,
5564
5565 },
5566 #ifdef HAVE_STRPTIME
5567 { "scan",
5568 "str -format format",
5569 clock_cmd_scan,
5570 3,
5571 3,
5572
5573 },
5574 #endif
5575 { NULL }
5576 };
5577
@@ -5591,11 +5768,11 @@
5591 #include <errno.h>
5592
5593
5594 static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5595 {
5596
5597 Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
5598 return JIM_OK;
5599 }
5600
5601 static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5607,20 +5784,20 @@
5607 return JIM_OK;
5608 }
5609
5610 patternObj = (argc == 1) ? NULL : argv[1];
5611
5612
5613 if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) {
5614 if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) {
5615
5616 Jim_SetResult(interp, objPtr);
5617 return JIM_OK;
5618 }
5619 }
5620
5621
5622 return Jim_DictValues(interp, objPtr, patternObj);
5623 }
5624
5625 static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5626 {
@@ -5640,27 +5817,27 @@
5640 Jim_Obj *resultObj;
5641 Jim_Obj *objPtr;
5642 Jim_Obj **dictValuesObj;
5643
5644 if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
5645
5646 Jim_UnsetVariable(interp, argv[0], JIM_NONE);
5647 return JIM_OK;
5648 }
5649
5650 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5651
5652 if (objPtr == NULL) {
5653
5654 return JIM_OK;
5655 }
5656
5657 if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
5658 return JIM_ERR;
5659 }
5660
5661
5662 resultObj = Jim_NewDictObj(interp, NULL, 0);
5663
5664 for (i = 0; i < len; i += 2) {
5665 if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
5666 Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
@@ -5675,11 +5852,11 @@
5675 static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
5676 {
5677 Jim_Obj *objPtr;
5678 int len = 0;
5679
5680
5681 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
5682 if (objPtr) {
5683 len = Jim_DictSize(interp, objPtr);
5684 if (len < 0) {
5685 return JIM_ERR;
@@ -5714,11 +5891,11 @@
5714 return JIM_ERR;
5715 }
5716
5717 dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
5718 if (!dictObj) {
5719
5720 return Jim_SetVariable(interp, argv[0], listObj);
5721 }
5722 else if (Jim_DictSize(interp, dictObj) < 0) {
5723 return JIM_ERR;
5724 }
@@ -5743,53 +5920,53 @@
5743 { "exists",
5744 "arrayName",
5745 array_cmd_exists,
5746 1,
5747 1,
5748
5749 },
5750 { "get",
5751 "arrayName ?pattern?",
5752 array_cmd_get,
5753 1,
5754 2,
5755
5756 },
5757 { "names",
5758 "arrayName ?pattern?",
5759 array_cmd_names,
5760 1,
5761 2,
5762
5763 },
5764 { "set",
5765 "arrayName list",
5766 array_cmd_set,
5767 2,
5768 2,
5769
5770 },
5771 { "size",
5772 "arrayName",
5773 array_cmd_size,
5774 1,
5775 1,
5776
5777 },
5778 { "stat",
5779 "arrayName",
5780 array_cmd_stat,
5781 1,
5782 1,
5783
5784 },
5785 { "unset",
5786 "arrayName ?pattern?",
5787 array_cmd_unset,
5788 1,
5789 2,
5790
5791 },
5792 { NULL
5793 }
5794 };
5795
@@ -5804,32 +5981,33 @@
5804 int Jim_InitStaticExtensions(Jim_Interp *interp)
5805 {
5806 extern int Jim_bootstrapInit(Jim_Interp *);
5807 extern int Jim_aioInit(Jim_Interp *);
5808 extern int Jim_readdirInit(Jim_Interp *);
5809 extern int Jim_globInit(Jim_Interp *);
5810 extern int Jim_regexpInit(Jim_Interp *);
5811 extern int Jim_fileInit(Jim_Interp *);
 
5812 extern int Jim_execInit(Jim_Interp *);
5813 extern int Jim_clockInit(Jim_Interp *);
5814 extern int Jim_arrayInit(Jim_Interp *);
5815 extern int Jim_stdlibInit(Jim_Interp *);
5816 extern int Jim_tclcompatInit(Jim_Interp *);
5817 Jim_bootstrapInit(interp);
5818 Jim_aioInit(interp);
5819 Jim_readdirInit(interp);
5820 Jim_globInit(interp);
5821 Jim_regexpInit(interp);
5822 Jim_fileInit(interp);
 
5823 Jim_execInit(interp);
5824 Jim_clockInit(interp);
5825 Jim_arrayInit(interp);
5826 Jim_stdlibInit(interp);
5827 Jim_tclcompatInit(interp);
5828 return JIM_OK;
5829 }
5830 #define JIM_OPTIMIZATION
 
5831
5832 #include <stdio.h>
5833 #include <stdlib.h>
5834
5835 #include <string.h>
@@ -5894,10 +6072,16 @@
5894 #define JimPanic(X) JimPanicDump X
5895 #else
5896 #define JimPanic(X)
5897 #endif
5898
 
 
 
 
 
 
5899
5900 static char JimEmptyStringRep[] = "";
5901
5902 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action);
5903 static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
@@ -5950,34 +6134,34 @@
5950 if (*pattern == '^') {
5951 not++;
5952 pattern++;
5953 }
5954
5955
5956 if (*pattern == ']') {
5957 goto first;
5958 }
5959 }
5960
5961 while (*pattern && *pattern != ']') {
5962
5963 if (pattern[0] == '\\') {
5964 first:
5965 pattern += utf8_tounicode_case(pattern, &pchar, nocase);
5966 }
5967 else {
5968
5969 int start;
5970 int end;
5971
5972 pattern += utf8_tounicode_case(pattern, &start, nocase);
5973 if (pattern[0] == '-' && pattern[1]) {
5974
5975 pattern += utf8_tounicode(pattern, &pchar);
5976 pattern += utf8_tounicode_case(pattern, &end, nocase);
5977
5978
5979 if ((c >= start && c <= end) || (c >= end && c <= start)) {
5980 match = 1;
5981 }
5982 continue;
5983 }
@@ -6007,19 +6191,19 @@
6007 while (pattern[1] == '*') {
6008 pattern++;
6009 }
6010 pattern++;
6011 if (!pattern[0]) {
6012 return 1;
6013 }
6014 while (*string) {
6015
6016 if (JimGlobMatch(pattern, string, nocase))
6017 return 1;
6018 string += utf8_tounicode(string, &c);
6019 }
6020 return 0;
6021
6022 case '?':
6023 string += utf8_tounicode(string, &c);
6024 break;
6025
@@ -6028,20 +6212,20 @@
6028 pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0);
6029 if (!pattern) {
6030 return 0;
6031 }
6032 if (!*pattern) {
6033
6034 continue;
6035 }
6036 break;
6037 }
6038 case '\\':
6039 if (pattern[1]) {
6040 pattern++;
6041 }
6042
6043 default:
6044 string += utf8_tounicode_case(string, &c, nocase);
6045 utf8_tounicode_case(pattern, &pchar, nocase);
6046 if (pchar != c) {
6047 return 0;
@@ -6087,11 +6271,11 @@
6087 maxchars--;
6088 }
6089 if (!maxchars) {
6090 return 0;
6091 }
6092
6093 if (*s1) {
6094 return 1;
6095 }
6096 if (*s2) {
6097 return -1;
@@ -6128,11 +6312,11 @@
6128 const char *p;
6129
6130 if (!l1 || !l2 || l1 > l2)
6131 return -1;
6132
6133
6134 for (p = s2 + l2 - 1; p != s2 - 1; p--) {
6135 if (*p == *s1 && memcmp(s1, p, l1) == 0) {
6136 return p - s2;
6137 }
6138 }
@@ -6187,28 +6371,28 @@
6187 }
6188 *sign = 1;
6189 }
6190
6191 if (str[i] != '0') {
6192
6193 return 0;
6194 }
6195
6196
6197 switch (str[i + 1]) {
6198 case 'x': case 'X': *base = 16; break;
6199 case 'o': case 'O': *base = 8; break;
6200 case 'b': case 'B': *base = 2; break;
6201 default: return 0;
6202 }
6203 i += 2;
6204
6205 if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
6206
6207 return i;
6208 }
6209
6210 *base = 10;
6211 return 0;
6212 }
6213
6214 static long jim_strtol(const char *str, char **endptr)
@@ -6222,11 +6406,11 @@
6222 if (endptr == NULL || *endptr != str + i) {
6223 return value * sign;
6224 }
6225 }
6226
6227
6228 return strtol(str, endptr, 10);
6229 }
6230
6231
6232 static jim_wide jim_strtoull(const char *str, char **endptr)
@@ -6241,11 +6425,11 @@
6241 if (endptr == NULL || *endptr != str + i) {
6242 return value * sign;
6243 }
6244 }
6245
6246
6247 return strtoull(str, endptr, 10);
6248 #else
6249 return (unsigned long)jim_strtol(str, endptr);
6250 #endif
6251 }
@@ -6266,26 +6450,40 @@
6266
6267 int Jim_StringToDouble(const char *str, double *doublePtr)
6268 {
6269 char *endptr;
6270
6271
6272 errno = 0;
6273
6274 *doublePtr = strtod(str, &endptr);
6275
6276 return JimCheckConversion(str, endptr);
6277 }
6278
6279 static jim_wide JimPowWide(jim_wide b, jim_wide e)
6280 {
6281 jim_wide i, res = 1;
6282
6283 if ((b == 0 && e != 0) || (e < 0))
6284 return 0;
6285 for (i = 0; i < e; i++) {
6286 res *= b;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6287 }
6288 return res;
6289 }
6290
6291 #ifdef JIM_DEBUG_PANIC
@@ -6347,11 +6545,11 @@
6347 char *Jim_StrDupLen(const char *s, int l)
6348 {
6349 char *copy = Jim_Alloc(l + 1);
6350
6351 memcpy(copy, s, l + 1);
6352 copy[l] = 0;
6353 return copy;
6354 }
6355
6356
6357
@@ -6436,52 +6634,52 @@
6436 }
6437
6438
6439 void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
6440 {
6441 Jim_HashTable n;
6442 unsigned int realsize = JimHashTableNextPower(size), i;
6443
6444 if (size <= ht->used)
6445 return;
6446
6447 Jim_InitHashTable(&n, ht->type, ht->privdata);
6448 n.size = realsize;
6449 n.sizemask = realsize - 1;
6450 n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *));
6451
6452 n.uniq = ht->uniq;
6453
6454
6455 memset(n.table, 0, realsize * sizeof(Jim_HashEntry *));
6456
6457 n.used = ht->used;
6458 for (i = 0; ht->used > 0; i++) {
6459 Jim_HashEntry *he, *nextHe;
6460
6461 if (ht->table[i] == NULL)
6462 continue;
6463
6464
6465 he = ht->table[i];
6466 while (he) {
6467 unsigned int h;
6468
6469 nextHe = he->next;
6470
6471 h = Jim_HashKey(ht, he->key) & n.sizemask;
6472 he->next = n.table[h];
6473 n.table[h] = he;
6474 ht->used--;
6475
6476 he = nextHe;
6477 }
6478 }
6479 assert(ht->used == 0);
6480 Jim_Free(ht->table);
6481
6482
6483 *ht = n;
6484 }
6485
6486
6487 int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
@@ -6490,11 +6688,11 @@
6490
6491 entry = JimInsertHashEntry(ht, key, 0);
6492 if (entry == NULL)
6493 return JIM_ERR;
6494
6495
6496 Jim_SetHashKey(ht, entry, key);
6497 Jim_SetHashVal(ht, entry, val);
6498 return JIM_OK;
6499 }
6500
@@ -6516,11 +6714,11 @@
6516 Jim_SetHashVal(ht, entry, val);
6517 }
6518 existed = 1;
6519 }
6520 else {
6521
6522 Jim_SetHashKey(ht, entry, key);
6523 Jim_SetHashVal(ht, entry, val);
6524 existed = 0;
6525 }
6526
@@ -6539,11 +6737,11 @@
6539 he = ht->table[h];
6540
6541 prevHe = NULL;
6542 while (he) {
6543 if (Jim_CompareHashKeys(ht, key, he->key)) {
6544
6545 if (prevHe)
6546 prevHe->next = he->next;
6547 else
6548 ht->table[h] = he->next;
6549 Jim_FreeEntryKey(ht, he);
@@ -6553,19 +6751,19 @@
6553 return JIM_OK;
6554 }
6555 prevHe = he;
6556 he = he->next;
6557 }
6558 return JIM_ERR;
6559 }
6560
6561
6562 int Jim_FreeHashTable(Jim_HashTable *ht)
6563 {
6564 unsigned int i;
6565
6566
6567 for (i = 0; ht->used > 0; i++) {
6568 Jim_HashEntry *he, *nextHe;
6569
6570 if ((he = ht->table[i]) == NULL)
6571 continue;
@@ -6576,15 +6774,15 @@
6576 Jim_Free(he);
6577 ht->used--;
6578 he = nextHe;
6579 }
6580 }
6581
6582 Jim_Free(ht->table);
6583
6584 JimResetHashTable(ht);
6585 return JIM_OK;
6586 }
6587
6588 Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key)
6589 {
6590 Jim_HashEntry *he;
@@ -6657,24 +6855,24 @@
6657 static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
6658 {
6659 unsigned int h;
6660 Jim_HashEntry *he;
6661
6662
6663 JimExpandHashTableIfNeeded(ht);
6664
6665
6666 h = Jim_HashKey(ht, key) & ht->sizemask;
6667
6668 he = ht->table[h];
6669 while (he) {
6670 if (Jim_CompareHashKeys(ht, key, he->key))
6671 return replace ? he : NULL;
6672 he = he->next;
6673 }
6674
6675
6676 he = Jim_Alloc(sizeof(*he));
6677 he->next = ht->table[h];
6678 ht->table[h] = he;
6679 ht->used++;
6680 he->key = NULL;
@@ -6703,16 +6901,16 @@
6703 {
6704 Jim_Free(key);
6705 }
6706
6707 static const Jim_HashTableType JimPackageHashTableType = {
6708 JimStringCopyHTHashFunction,
6709 JimStringCopyHTDup,
6710 NULL,
6711 JimStringCopyHTKeyCompare,
6712 JimStringCopyHTKeyDestructor,
6713 NULL
6714 };
6715
6716 typedef struct AssocDataValue
6717 {
6718 Jim_InterpDeleteProc *delProc;
@@ -6727,16 +6925,16 @@
6727 assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data);
6728 Jim_Free(data);
6729 }
6730
6731 static const Jim_HashTableType JimAssocDataHashTableType = {
6732 JimStringCopyHTHashFunction,
6733 JimStringCopyHTDup,
6734 NULL,
6735 JimStringCopyHTKeyCompare,
6736 JimStringCopyHTKeyDestructor,
6737 JimAssocDataHashTableValueDestructor
6738 };
6739
6740 void Jim_InitStack(Jim_Stack *stack)
6741 {
6742 stack->len = 0;
@@ -6789,61 +6987,61 @@
6789 freeFunc(stack->vector[i]);
6790 }
6791
6792
6793
6794 #define JIM_TT_NONE 0
6795 #define JIM_TT_STR 1
6796 #define JIM_TT_ESC 2
6797 #define JIM_TT_VAR 3
6798 #define JIM_TT_DICTSUGAR 4
6799 #define JIM_TT_CMD 5
6800
6801 #define JIM_TT_SEP 6
6802 #define JIM_TT_EOL 7
6803 #define JIM_TT_EOF 8
6804
6805 #define JIM_TT_LINE 9
6806 #define JIM_TT_WORD 10
6807
6808
6809 #define JIM_TT_SUBEXPR_START 11
6810 #define JIM_TT_SUBEXPR_END 12
6811 #define JIM_TT_SUBEXPR_COMMA 13
6812 #define JIM_TT_EXPR_INT 14
6813 #define JIM_TT_EXPR_DOUBLE 15
 
6814
6815 #define JIM_TT_EXPRSUGAR 16
6816
6817
6818 #define JIM_TT_EXPR_OP 20
6819
6820 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF)
6821
 
6822
6823 #define JIM_PS_DEF 0
6824 #define JIM_PS_QUOTE 1
6825 #define JIM_PS_DICTSUGAR 2
6826
6827 struct JimParseMissing {
6828 int ch;
6829 int line;
6830 };
6831
6832 struct JimParserCtx
6833 {
6834 const char *p;
6835 int len;
6836 int linenr;
6837 const char *tstart;
6838 const char *tend;
6839 int tline;
6840 int tt;
6841 int eof;
6842 int state;
6843 int comment;
6844 struct JimParseMissing missing;
6845 };
6846
6847 static int JimParseScript(struct JimParserCtx *pc);
6848 static int JimParseSep(struct JimParserCtx *pc);
6849 static int JimParseEol(struct JimParserCtx *pc);
@@ -6864,20 +7062,20 @@
6864 pc->tstart = NULL;
6865 pc->tend = NULL;
6866 pc->tline = 0;
6867 pc->tt = JIM_TT_NONE;
6868 pc->eof = 0;
6869 pc->state = JIM_PS_DEF;
6870 pc->linenr = linenr;
6871 pc->comment = 1;
6872 pc->missing.ch = ' ';
6873 pc->missing.line = linenr;
6874 }
6875
6876 static int JimParseScript(struct JimParserCtx *pc)
6877 {
6878 while (1) {
6879 if (!pc->len) {
6880 pc->tstart = pc->p;
6881 pc->tend = pc->p - 1;
6882 pc->tline = pc->linenr;
6883 pc->tt = JIM_TT_EOL;
@@ -6884,36 +7082,36 @@
6884 pc->eof = 1;
6885 return JIM_OK;
6886 }
6887 switch (*(pc->p)) {
6888 case '\\':
6889 if (*(pc->p + 1) == '\n' && pc->state == JIM_PS_DEF) {
6890 return JimParseSep(pc);
6891 }
6892 pc->comment = 0;
6893 return JimParseStr(pc);
6894 case ' ':
6895 case '\t':
6896 case '\r':
6897 case '\f':
6898 if (pc->state == JIM_PS_DEF)
6899 return JimParseSep(pc);
6900 pc->comment = 0;
6901 return JimParseStr(pc);
6902 case '\n':
6903 case ';':
6904 pc->comment = 1;
6905 if (pc->state == JIM_PS_DEF)
6906 return JimParseEol(pc);
6907 return JimParseStr(pc);
6908 case '[':
6909 pc->comment = 0;
6910 return JimParseCmd(pc);
6911 case '$':
6912 pc->comment = 0;
6913 if (JimParseVar(pc) == JIM_ERR) {
6914
6915 pc->tstart = pc->tend = pc->p++;
6916 pc->len--;
6917 pc->tt = JIM_TT_ESC;
6918 }
6919 return JIM_OK;
@@ -6970,11 +7168,11 @@
6970
6971 static void JimParseSubBrace(struct JimParserCtx *pc)
6972 {
6973 int level = 1;
6974
6975
6976 pc->p++;
6977 pc->len--;
6978 while (pc->len) {
6979 switch (*pc->p) {
6980 case '\\':
@@ -7014,11 +7212,11 @@
7014 static int JimParseSubQuote(struct JimParserCtx *pc)
7015 {
7016 int tt = JIM_TT_STR;
7017 int line = pc->tline;
7018
7019
7020 pc->p++;
7021 pc->len--;
7022 while (pc->len) {
7023 switch (*pc->p) {
7024 case '\\':
@@ -7063,11 +7261,11 @@
7063 {
7064 int level = 1;
7065 int startofword = 1;
7066 int line = pc->tline;
7067
7068
7069 pc->p++;
7070 pc->len--;
7071 while (pc->len) {
7072 switch (*pc->p) {
7073 case '\\':
@@ -7143,17 +7341,17 @@
7143 return JIM_OK;
7144 }
7145
7146 static int JimParseVar(struct JimParserCtx *pc)
7147 {
7148
7149 pc->p++;
7150 pc->len--;
7151
7152 #ifdef EXPRSUGAR_BRACKET
7153 if (*pc->p == '[') {
7154
7155 JimParseCmd(pc);
7156 pc->tt = JIM_TT_EXPRSUGAR;
7157 return JIM_OK;
7158 }
7159 #endif
@@ -7179,11 +7377,11 @@
7179 pc->len--;
7180 }
7181 }
7182 else {
7183 while (1) {
7184
7185 if (pc->p[0] == ':' && pc->p[1] == ':') {
7186 while (*pc->p == ':') {
7187 pc->p++;
7188 pc->len--;
7189 }
@@ -7194,11 +7392,11 @@
7194 pc->len--;
7195 continue;
7196 }
7197 break;
7198 }
7199
7200 if (*pc->p == '(') {
7201 int count = 1;
7202 const char *paren = NULL;
7203
7204 pc->tt = JIM_TT_DICTSUGAR;
@@ -7221,11 +7419,11 @@
7221 if (count == 0) {
7222 pc->p++;
7223 pc->len--;
7224 }
7225 else if (paren) {
7226
7227 paren++;
7228 pc->len += (pc->p - paren);
7229 pc->p = paren;
7230 }
7231 #ifndef EXPRSUGAR_BRACKET
@@ -7246,36 +7444,36 @@
7246
7247 static int JimParseStr(struct JimParserCtx *pc)
7248 {
7249 if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
7250 pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
7251
7252 if (*pc->p == '{') {
7253 return JimParseBrace(pc);
7254 }
7255 if (*pc->p == '"') {
7256 pc->state = JIM_PS_QUOTE;
7257 pc->p++;
7258 pc->len--;
7259
7260 pc->missing.line = pc->tline;
7261 }
7262 }
7263 pc->tstart = pc->p;
7264 pc->tline = pc->linenr;
7265 while (1) {
7266 if (pc->len == 0) {
7267 if (pc->state == JIM_PS_QUOTE) {
7268 pc->missing.ch = '"';
7269 }
7270 pc->tend = pc->p - 1;
7271 pc->tt = JIM_TT_ESC;
7272 return JIM_OK;
7273 }
7274 switch (*pc->p) {
7275 case '\\':
7276 if (pc->state == JIM_PS_DEF && *(pc->p + 1) == '\n') {
7277 pc->tend = pc->p - 1;
7278 pc->tt = JIM_TT_ESC;
7279 return JIM_OK;
7280 }
7281 if (pc->len >= 2) {
@@ -7284,24 +7482,25 @@
7284 }
7285 pc->p++;
7286 pc->len--;
7287 }
7288 else if (pc->len == 1) {
7289
7290 pc->missing.ch = '\\';
7291 }
7292 break;
7293 case '(':
7294
7295 if (pc->len > 1 && pc->p[1] != '$') {
7296 break;
7297 }
 
7298 case ')':
7299
7300 if (*pc->p == '(' || pc->tt == JIM_TT_VAR) {
7301 if (pc->p == pc->tstart) {
7302
7303 pc->p++;
7304 pc->len--;
7305 }
7306 pc->tend = pc->p - 1;
7307 pc->tt = JIM_TT_ESC;
@@ -7318,34 +7517,34 @@
7318 case '\t':
7319 case '\n':
7320 case '\r':
7321 case '\f':
7322 case ';':
7323 if (pc->state == JIM_PS_DEF) {
7324 pc->tend = pc->p - 1;
7325 pc->tt = JIM_TT_ESC;
7326 return JIM_OK;
7327 }
7328 else if (*pc->p == '\n') {
7329 pc->linenr++;
7330 }
7331 break;
7332 case '"':
7333 if (pc->state == JIM_PS_QUOTE) {
7334 pc->tend = pc->p - 1;
7335 pc->tt = JIM_TT_ESC;
7336 pc->p++;
7337 pc->len--;
7338 pc->state = JIM_PS_DEF;
7339 return JIM_OK;
7340 }
7341 break;
7342 }
7343 pc->p++;
7344 pc->len--;
7345 }
7346 return JIM_OK;
7347 }
7348
7349 static int JimParseComment(struct JimParserCtx *pc)
7350 {
7351 while (*pc->p) {
@@ -7394,13 +7593,10 @@
7394 static int JimEscape(char *dest, const char *s, int slen)
7395 {
7396 char *p = dest;
7397 int i, len;
7398
7399 if (slen == -1)
7400 slen = strlen(s);
7401
7402 for (i = 0; i < slen; i++) {
7403 switch (s[i]) {
7404 case '\\':
7405 switch (s[i + 1]) {
7406 case 'a':
@@ -7455,34 +7651,34 @@
7455 if (c == -1) {
7456 break;
7457 }
7458 val = (val << 4) | c;
7459 }
7460
7461 if (s[i] == '{') {
7462 if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
7463
7464 i--;
7465 k = 0;
7466 }
7467 else {
7468
7469 k++;
7470 }
7471 }
7472 if (k) {
7473
7474 if (s[i] == 'x') {
7475 *p++ = val;
7476 }
7477 else {
7478 p += utf8_fromunicode(p, val);
7479 }
7480 i += k;
7481 break;
7482 }
7483
7484 *p++ = s[i];
7485 }
7486 break;
7487 case 'v':
7488 *p++ = 0xb;
@@ -7491,11 +7687,11 @@
7491 case '\0':
7492 *p++ = '\\';
7493 i++;
7494 break;
7495 case '\n':
7496
7497 *p++ = ' ';
7498 do {
7499 i++;
7500 } while (s[i + 1] == ' ' || s[i + 1] == '\t');
7501 break;
@@ -7505,11 +7701,11 @@
7505 case '3':
7506 case '4':
7507 case '5':
7508 case '6':
7509 case '7':
7510
7511 {
7512 int val = 0;
7513 int c = odigitval(s[i + 1]);
7514
7515 val = c;
@@ -7562,37 +7758,23 @@
7562 }
7563 else {
7564 len = (end - start) + 1;
7565 token = Jim_Alloc(len + 1);
7566 if (pc->tt != JIM_TT_ESC) {
7567
7568 memcpy(token, start, len);
7569 token[len] = '\0';
7570 }
7571 else {
7572
7573 len = JimEscape(token, start, len);
7574 }
7575 }
7576
7577 return Jim_NewStringObjNoAlloc(interp, token, len);
7578 }
7579
7580 int Jim_ScriptIsComplete(const char *s, int len, char *stateCharPtr)
7581 {
7582 struct JimParserCtx parser;
7583
7584 JimParserInit(&parser, s, len, 1);
7585 while (!parser.eof) {
7586 JimParseScript(&parser);
7587 }
7588 if (stateCharPtr) {
7589 *stateCharPtr = parser.missing.ch;
7590 }
7591 return parser.missing.ch == ' ';
7592 }
7593
7594 static int JimParseListSep(struct JimParserCtx *pc);
7595 static int JimParseListStr(struct JimParserCtx *pc);
7596 static int JimParseListQuote(struct JimParserCtx *pc);
7597
7598 static int JimParseList(struct JimParserCtx *pc)
@@ -7649,11 +7831,11 @@
7649 while (pc->len) {
7650 switch (*pc->p) {
7651 case '\\':
7652 pc->tt = JIM_TT_ESC;
7653 if (--pc->len == 0) {
7654
7655 pc->tend = pc->p;
7656 return JIM_OK;
7657 }
7658 pc->p++;
7659 break;
@@ -7685,11 +7867,11 @@
7685 pc->tend = pc->p - 1;
7686 return JIM_OK;
7687 }
7688 if (*pc->p == '\\') {
7689 if (--pc->len == 0) {
7690
7691 pc->tend = pc->p;
7692 return JIM_OK;
7693 }
7694 pc->tt = JIM_TT_ESC;
7695 pc->p++;
@@ -7705,24 +7887,24 @@
7705
7706 Jim_Obj *Jim_NewObj(Jim_Interp *interp)
7707 {
7708 Jim_Obj *objPtr;
7709
7710
7711 if (interp->freeList != NULL) {
7712
7713 objPtr = interp->freeList;
7714 interp->freeList = objPtr->nextObjPtr;
7715 }
7716 else {
7717
7718 objPtr = Jim_Alloc(sizeof(*objPtr));
7719 }
7720
7721 objPtr->refCount = 0;
7722
7723
7724 objPtr->prevObjPtr = NULL;
7725 objPtr->nextObjPtr = interp->liveList;
7726 if (interp->liveList)
7727 interp->liveList->prevObjPtr = objPtr;
7728 interp->liveList = objPtr;
@@ -7730,32 +7912,32 @@
7730 return objPtr;
7731 }
7732
7733 void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
7734 {
7735
7736 JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr,
7737 objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>"));
7738
7739
7740 Jim_FreeIntRep(interp, objPtr);
7741
7742 if (objPtr->bytes != NULL) {
7743 if (objPtr->bytes != JimEmptyStringRep)
7744 Jim_Free(objPtr->bytes);
7745 }
7746
7747 if (objPtr->prevObjPtr)
7748 objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
7749 if (objPtr->nextObjPtr)
7750 objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
7751 if (interp->liveList == objPtr)
7752 interp->liveList = objPtr->nextObjPtr;
7753 #ifdef JIM_DISABLE_OBJECT_POOL
7754 Jim_Free(objPtr);
7755 #else
7756
7757 objPtr->prevObjPtr = NULL;
7758 objPtr->nextObjPtr = interp->freeList;
7759 if (interp->freeList)
7760 interp->freeList->prevObjPtr = objPtr;
7761 interp->freeList = objPtr;
@@ -7778,45 +7960,45 @@
7778 {
7779 Jim_Obj *dupPtr;
7780
7781 dupPtr = Jim_NewObj(interp);
7782 if (objPtr->bytes == NULL) {
7783
7784 dupPtr->bytes = NULL;
7785 }
7786 else if (objPtr->length == 0) {
7787
7788 dupPtr->bytes = JimEmptyStringRep;
7789 dupPtr->length = 0;
7790 dupPtr->typePtr = NULL;
7791 return dupPtr;
7792 }
7793 else {
7794 dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
7795 dupPtr->length = objPtr->length;
7796
7797 memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
7798 }
7799
7800
7801 dupPtr->typePtr = objPtr->typePtr;
7802 if (objPtr->typePtr != NULL) {
7803 if (objPtr->typePtr->dupIntRepProc == NULL) {
7804 dupPtr->internalRep = objPtr->internalRep;
7805 }
7806 else {
7807
7808 objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
7809 }
7810 }
7811 return dupPtr;
7812 }
7813
7814 const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
7815 {
7816 if (objPtr->bytes == NULL) {
7817
7818 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7819 objPtr->typePtr->updateStringProc(objPtr);
7820 }
7821 if (lenPtr)
7822 *lenPtr = objPtr->length;
@@ -7825,11 +8007,11 @@
7825
7826
7827 int Jim_Length(Jim_Obj *objPtr)
7828 {
7829 if (objPtr->bytes == NULL) {
7830
7831 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7832 objPtr->typePtr->updateStringProc(objPtr);
7833 }
7834 return objPtr->length;
7835 }
@@ -7836,11 +8018,11 @@
7836
7837
7838 const char *Jim_String(Jim_Obj *objPtr)
7839 {
7840 if (objPtr->bytes == NULL) {
7841
7842 JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value."));
7843 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7844 objPtr->typePtr->updateStringProc(objPtr);
7845 }
7846 return objPtr->bytes;
@@ -7896,22 +8078,22 @@
7896 }
7897
7898 static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
7899 {
7900 if (objPtr->typePtr != &stringObjType) {
7901
7902 if (objPtr->bytes == NULL) {
7903
7904 JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
7905 objPtr->typePtr->updateStringProc(objPtr);
7906 }
7907
7908 Jim_FreeIntRep(interp, objPtr);
7909
7910 objPtr->typePtr = &stringObjType;
7911 objPtr->internalRep.strValue.maxLength = objPtr->length;
7912
7913 objPtr->internalRep.strValue.charLength = -1;
7914 }
7915 return JIM_OK;
7916 }
7917
@@ -7932,14 +8114,14 @@
7932
7933 Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
7934 {
7935 Jim_Obj *objPtr = Jim_NewObj(interp);
7936
7937
7938 if (len == -1)
7939 len = strlen(s);
7940
7941 if (len == 0) {
7942 objPtr->bytes = JimEmptyStringRep;
7943 }
7944 else {
7945 objPtr->bytes = Jim_Alloc(len + 1);
@@ -7946,25 +8128,25 @@
7946 memcpy(objPtr->bytes, s, len);
7947 objPtr->bytes[len] = '\0';
7948 }
7949 objPtr->length = len;
7950
7951
7952 objPtr->typePtr = NULL;
7953 return objPtr;
7954 }
7955
7956
7957 Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen)
7958 {
7959 #ifdef JIM_UTF8
7960
7961 int bytelen = utf8_index(s, charlen);
7962
7963 Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen);
7964
7965
7966 objPtr->typePtr = &stringObjType;
7967 objPtr->internalRep.strValue.maxLength = bytelen;
7968 objPtr->internalRep.strValue.charLength = charlen;
7969
7970 return objPtr;
@@ -7991,11 +8173,11 @@
7991 len = strlen(str);
7992 needlen = objPtr->length + len;
7993 if (objPtr->internalRep.strValue.maxLength < needlen ||
7994 objPtr->internalRep.strValue.maxLength == 0) {
7995 needlen *= 2;
7996
7997 if (needlen < 7) {
7998 needlen = 7;
7999 }
8000 if (objPtr->bytes == JimEmptyStringRep) {
8001 objPtr->bytes = Jim_Alloc(needlen + 1);
@@ -8007,11 +8189,11 @@
8007 }
8008 memcpy(objPtr->bytes + objPtr->length, str, len);
8009 objPtr->bytes[objPtr->length + len] = '\0';
8010
8011 if (objPtr->internalRep.strValue.charLength >= 0) {
8012
8013 objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len);
8014 }
8015 objPtr->length += len;
8016 }
8017
@@ -8069,11 +8251,11 @@
8069 int l1, l2;
8070 const char *s1 = Jim_GetString(firstObjPtr, &l1);
8071 const char *s2 = Jim_GetString(secondObjPtr, &l2);
8072
8073 if (nocase) {
8074
8075 return JimStringCompareLen(s1, s2, -1, nocase);
8076 }
8077 return JimStringCompare(s1, l1, s2, l2);
8078 }
8079
@@ -8171,11 +8353,11 @@
8171
8172 if (first == 0 && rangeLen == len) {
8173 return strObjPtr;
8174 }
8175 if (len == bytelen) {
8176
8177 return Jim_NewStringObj(interp, str + first, rangeLen);
8178 }
8179 return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen);
8180 #else
8181 return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr);
@@ -8200,19 +8382,19 @@
8200 return strObjPtr;
8201 }
8202
8203 str = Jim_String(strObjPtr);
8204
8205
8206 objPtr = Jim_NewStringObjUtf8(interp, str, first);
8207
8208
8209 if (newStrObj) {
8210 Jim_AppendObj(interp, objPtr, newStrObj);
8211 }
8212
8213
8214 Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
8215
8216 return objPtr;
8217 }
8218
@@ -8311,11 +8493,11 @@
8311 while (len) {
8312 int c;
8313 int n = utf8_tounicode(str, &c);
8314
8315 if (utf8_memchr(trimchars, trimlen, c) == NULL) {
8316
8317 break;
8318 }
8319 str += n;
8320 len -= n;
8321 }
@@ -8382,41 +8564,41 @@
8382
8383 len = Jim_Length(strObjPtr);
8384 nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
8385
8386 if (nontrim == NULL) {
8387
8388 return Jim_NewEmptyStringObj(interp);
8389 }
8390 if (nontrim == strObjPtr->bytes + len) {
8391
8392 return strObjPtr;
8393 }
8394
8395 if (Jim_IsShared(strObjPtr)) {
8396 strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes));
8397 }
8398 else {
8399
8400 strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0;
8401 strObjPtr->length = (nontrim - strObjPtr->bytes);
8402 }
8403
8404 return strObjPtr;
8405 }
8406
8407 static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr)
8408 {
8409
8410 Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr);
8411
8412
8413 strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr);
8414
8415
8416 if (objPtr != strObjPtr && objPtr->refCount == 0) {
8417
8418 Jim_FreeNewObj(interp, objPtr);
8419 }
8420
8421 return strObjPtr;
8422 }
@@ -8434,17 +8616,17 @@
8434 static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
8435 {
8436 static const char * const strclassnames[] = {
8437 "integer", "alpha", "alnum", "ascii", "digit",
8438 "double", "lower", "upper", "space", "xdigit",
8439 "control", "print", "graph", "punct",
8440 NULL
8441 };
8442 enum {
8443 STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
8444 STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
8445 STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
8446 };
8447 int strclass;
8448 int len;
8449 int i;
8450 const char *str;
@@ -8472,10 +8654,17 @@
8472 {
8473 double d;
8474 Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
8475 return JIM_OK;
8476 }
 
 
 
 
 
 
 
8477
8478 case STR_IS_ALPHA: isclassfunc = isalpha; break;
8479 case STR_IS_ALNUM: isclassfunc = isalnum; break;
8480 case STR_IS_ASCII: isclassfunc = jim_isascii; break;
8481 case STR_IS_DIGIT: isclassfunc = isdigit; break;
@@ -8524,11 +8713,11 @@
8524
8525 if (objPtr->typePtr != &comparedStringObjType) {
8526 Jim_FreeIntRep(interp, objPtr);
8527 objPtr->typePtr = &comparedStringObjType;
8528 }
8529 objPtr->internalRep.ptr = (char *)str;
8530 return 1;
8531 }
8532 }
8533
8534 static int qsortCompareStringPointers(const void *a, const void *b)
@@ -8600,12 +8789,10 @@
8600 return objPtr;
8601 }
8602
8603 static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
8604 static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
8605 static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
8606 static int JimParseCheckMissing(Jim_Interp *interp, int ch);
8607
8608 static const Jim_ObjType scriptObjType = {
8609 "script",
8610 FreeScriptInternalRep,
8611 DupScriptInternalRep,
@@ -8619,21 +8806,25 @@
8619 int type;
8620 } ScriptToken;
8621
8622 typedef struct ScriptObj
8623 {
8624 ScriptToken *token;
8625 Jim_Obj *fileNameObj;
8626 int len;
8627 int substFlags;
8628 int inUse; /* Used to share a ScriptObj. Currently
8629 only used by Jim_EvalObj() as protection against
8630 shimmering of the currently evaluated object. */
8631 int firstline;
8632 int linenr;
8633 int missing;
8634 } ScriptObj;
 
 
 
 
8635
8636 void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
8637 {
8638 int i;
8639 struct ScriptObj *script = (void *)objPtr->internalRep.ptr;
@@ -8656,23 +8847,23 @@
8656 dupPtr->typePtr = NULL;
8657 }
8658
8659 typedef struct
8660 {
8661 const char *token;
8662 int len;
8663 int type;
8664 int line;
8665 } ParseToken;
8666
8667 typedef struct
8668 {
8669
8670 ParseToken *list;
8671 int size;
8672 int count;
8673 ParseToken static_list[20];
8674 } ParseTokenList;
8675
8676 static void ScriptTokenListInit(ParseTokenList *tokenlist)
8677 {
8678 tokenlist->list = tokenlist->static_list;
@@ -8691,18 +8882,18 @@
8691 int line)
8692 {
8693 ParseToken *t;
8694
8695 if (tokenlist->count == tokenlist->size) {
8696
8697 tokenlist->size *= 2;
8698 if (tokenlist->list != tokenlist->static_list) {
8699 tokenlist->list =
8700 Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list));
8701 }
8702 else {
8703
8704 tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list));
8705 memcpy(tokenlist->list, tokenlist->static_list,
8706 tokenlist->count * sizeof(*tokenlist->list));
8707 }
8708 }
@@ -8716,20 +8907,20 @@
8716 static int JimCountWordTokens(ParseToken *t)
8717 {
8718 int expand = 1;
8719 int count = 0;
8720
8721
8722 if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) {
8723 if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) {
8724
8725 expand = -1;
8726 t++;
8727 }
8728 }
8729
8730
8731 while (!TOKEN_IS_SEP(t->type)) {
8732 t++;
8733 count++;
8734 }
8735
@@ -8739,11 +8930,11 @@
8739 static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t)
8740 {
8741 Jim_Obj *objPtr;
8742
8743 if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) {
8744
8745 int len = t->len;
8746 char *str = Jim_Alloc(len + 1);
8747 len = JimEscape(str, t->token, len);
8748 objPtr = Jim_NewStringObjNoAlloc(interp, str, len);
8749 }
@@ -8756,13 +8947,13 @@
8756 static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
8757 ParseTokenList *tokenlist)
8758 {
8759 int i;
8760 struct ScriptToken *token;
8761
8762 int lineargs = 0;
8763
8764 ScriptToken *linefirst;
8765 int count;
8766 int linenr;
8767
8768 #ifdef DEBUG_SHOW_SCRIPT_TOKENS
@@ -8771,11 +8962,11 @@
8771 printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type),
8772 tokenlist->list[i].len, tokenlist->list[i].token);
8773 }
8774 #endif
8775
8776
8777 count = tokenlist->count;
8778 for (i = 0; i < tokenlist->count; i++) {
8779 if (tokenlist->list[i].type == JIM_TT_EOL) {
8780 count++;
8781 }
@@ -8782,59 +8973,59 @@
8782 }
8783 linenr = script->firstline = tokenlist->list[0].line;
8784
8785 token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
8786
8787
8788 linefirst = token++;
8789
8790 for (i = 0; i < tokenlist->count; ) {
8791
8792 int wordtokens;
8793
8794
8795 while (tokenlist->list[i].type == JIM_TT_SEP) {
8796 i++;
8797 }
8798
8799 wordtokens = JimCountWordTokens(tokenlist->list + i);
8800
8801 if (wordtokens == 0) {
8802
8803 if (lineargs) {
8804 linefirst->type = JIM_TT_LINE;
8805 linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr);
8806 Jim_IncrRefCount(linefirst->objPtr);
8807
8808
8809 lineargs = 0;
8810 linefirst = token++;
8811 }
8812 i++;
8813 continue;
8814 }
8815 else if (wordtokens != 1) {
8816
8817 token->type = JIM_TT_WORD;
8818 token->objPtr = Jim_NewIntObj(interp, wordtokens);
8819 Jim_IncrRefCount(token->objPtr);
8820 token++;
8821 if (wordtokens < 0) {
8822
8823 i++;
8824 wordtokens = -wordtokens - 1;
8825 lineargs--;
8826 }
8827 }
8828
8829 if (lineargs == 0) {
8830
8831 linenr = tokenlist->list[i].line;
8832 }
8833 lineargs++;
8834
8835
8836 while (wordtokens--) {
8837 const ParseToken *t = &tokenlist->list[i++];
8838
8839 token->type = t->type;
8840 token->objPtr = JimMakeScriptObj(interp, t);
@@ -8860,10 +9051,19 @@
8860 printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
8861 }
8862 #endif
8863
8864 }
 
 
 
 
 
 
 
 
 
8865
8866 static int JimParseCheckMissing(Jim_Interp *interp, int ch)
8867 {
8868 const char *msg;
8869
@@ -8897,11 +9097,11 @@
8897 token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count);
8898
8899 for (i = 0; i < tokenlist->count; i++) {
8900 const ParseToken *t = &tokenlist->list[i];
8901
8902
8903 token->type = t->type;
8904 token->objPtr = JimMakeScriptObj(interp, t);
8905 Jim_IncrRefCount(token->objPtr);
8906 token++;
8907 }
@@ -8916,29 +9116,29 @@
8916 struct JimParserCtx parser;
8917 struct ScriptObj *script;
8918 ParseTokenList tokenlist;
8919 int line = 1;
8920
8921
8922 if (objPtr->typePtr == &sourceObjType) {
8923 line = objPtr->internalRep.sourceValue.lineNumber;
8924 }
8925
8926
8927 ScriptTokenListInit(&tokenlist);
8928
8929 JimParserInit(&parser, scriptText, scriptTextLen, line);
8930 while (!parser.eof) {
8931 JimParseScript(&parser);
8932 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
8933 parser.tline);
8934 }
8935
8936
8937 ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0);
8938
8939
8940 script = Jim_Alloc(sizeof(*script));
8941 memset(script, 0, sizeof(*script));
8942 script->inUse = 1;
8943 if (objPtr->typePtr == &sourceObjType) {
8944 script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -8950,25 +9150,25 @@
8950 script->missing = parser.missing.ch;
8951 script->linenr = parser.missing.line;
8952
8953 ScriptObjAddTokens(interp, script, &tokenlist);
8954
8955
8956 ScriptTokenListFree(&tokenlist);
8957
8958
8959 Jim_FreeIntRep(interp, objPtr);
8960 Jim_SetIntRepPtr(objPtr, script);
8961 objPtr->typePtr = &scriptObjType;
8962 }
8963
8964 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script);
8965
8966 ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr)
8967 {
8968 if (objPtr == interp->emptyObj) {
8969
8970 objPtr = interp->nullScriptObj;
8971 }
8972
8973 if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
8974 JimSetScriptFromAny(interp, objPtr);
@@ -9003,17 +9203,17 @@
9003 Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
9004 Jim_Free(cmdPtr->u.proc.staticVars);
9005 }
9006 }
9007 else {
9008
9009 if (cmdPtr->u.native.delProc) {
9010 cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
9011 }
9012 }
9013 if (cmdPtr->prevCmd) {
9014
9015 JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
9016 }
9017 Jim_Free(cmdPtr);
9018 }
9019 }
@@ -9024,46 +9224,46 @@
9024 Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
9025 Jim_Free(val);
9026 }
9027
9028 static const Jim_HashTableType JimVariablesHashTableType = {
9029 JimStringCopyHTHashFunction,
9030 JimStringCopyHTDup,
9031 NULL,
9032 JimStringCopyHTKeyCompare,
9033 JimStringCopyHTKeyDestructor,
9034 JimVariablesHTValDestructor
9035 };
9036
9037 static void JimCommandsHT_ValDestructor(void *interp, void *val)
9038 {
9039 JimDecrCmdRefCount(interp, val);
9040 }
9041
9042 static const Jim_HashTableType JimCommandsHashTableType = {
9043 JimStringCopyHTHashFunction,
9044 JimStringCopyHTDup,
9045 NULL,
9046 JimStringCopyHTKeyCompare,
9047 JimStringCopyHTKeyDestructor,
9048 JimCommandsHT_ValDestructor
9049 };
9050
9051
9052
9053 #ifdef jim_ext_namespace
9054 static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
9055 {
9056 const char *name = Jim_String(nsObj);
9057 if (name[0] == ':' && name[1] == ':') {
9058
9059 while (*++name == ':') {
9060 }
9061 nsObj = Jim_NewStringObj(interp, name, -1);
9062 }
9063 else if (Jim_Length(interp->framePtr->nsObj)) {
9064
9065 nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9066 Jim_AppendStrings(interp, nsObj, "::", name, NULL);
9067 }
9068 return nsObj;
9069 }
@@ -9087,16 +9287,16 @@
9087 static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
9088 {
9089 Jim_Obj *objPtr = interp->emptyObj;
9090
9091 if (name[0] == ':' && name[1] == ':') {
9092
9093 while (*++name == ':') {
9094 }
9095 }
9096 else if (Jim_Length(interp->framePtr->nsObj)) {
9097
9098 objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9099 Jim_AppendStrings(interp, objPtr, "::", name, NULL);
9100 name = Jim_String(objPtr);
9101 }
9102 Jim_IncrRefCount(objPtr);
@@ -9105,11 +9305,11 @@
9105 }
9106
9107 #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
9108
9109 #else
9110
9111 #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
9112 #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
9113
9114 Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
9115 {
@@ -9124,17 +9324,17 @@
9124
9125 Jim_InterpIncrProcEpoch(interp);
9126 }
9127
9128 if (he && interp->local) {
9129
9130 cmd->prevCmd = Jim_GetHashEntryVal(he);
9131 Jim_SetHashVal(&interp->commands, he, cmd);
9132 }
9133 else {
9134 if (he) {
9135
9136 Jim_DeleteHashEntry(&interp->commands, name);
9137 }
9138
9139 Jim_AddHashEntry(&interp->commands, name, cmd);
9140 }
@@ -9141,15 +9341,15 @@
9141 return JIM_OK;
9142 }
9143
9144
9145 int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
9146 Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc)
9147 {
9148 Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
9149
9150
9151 memset(cmdPtr, 0, sizeof(*cmdPtr));
9152 cmdPtr->inUse = 1;
9153 cmdPtr->u.native.delProc = delProc;
9154 cmdPtr->u.native.cmdProc = cmdProc;
9155 cmdPtr->u.native.privData = privData;
@@ -9174,11 +9374,11 @@
9174 Jim_Obj *objPtr, *initObjPtr, *nameObjPtr;
9175 Jim_Var *varPtr;
9176 int subLen;
9177
9178 objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i);
9179
9180 subLen = Jim_ListLength(interp, objPtr);
9181 if (subLen == 1 || subLen == 2) {
9182 nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0);
9183 if (subLen == 1) {
9184 initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
@@ -9220,19 +9420,19 @@
9220
9221 static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
9222 {
9223 #ifdef jim_ext_namespace
9224 if (cmdPtr->isproc) {
9225
9226 const char *pt = strrchr(cmdname, ':');
9227 if (pt && pt != cmdname && pt[-1] == ':') {
9228 Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
9229 cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
9230 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9231
9232 if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
9233
9234 Jim_InterpIncrProcEpoch(interp);
9235 }
9236 }
9237 }
9238 #endif
@@ -9245,11 +9445,11 @@
9245 int argListLen;
9246 int i;
9247
9248 argListLen = Jim_ListLength(interp, argListObjPtr);
9249
9250
9251 cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen);
9252 memset(cmdPtr, 0, sizeof(*cmdPtr));
9253 cmdPtr->inUse = 1;
9254 cmdPtr->isproc = 1;
9255 cmdPtr->u.proc.argListObjPtr = argListObjPtr;
@@ -9260,24 +9460,24 @@
9260 cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
9261 Jim_IncrRefCount(argListObjPtr);
9262 Jim_IncrRefCount(bodyObjPtr);
9263 Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
9264
9265
9266 if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
9267 goto err;
9268 }
9269
9270
9271
9272 for (i = 0; i < argListLen; i++) {
9273 Jim_Obj *argPtr;
9274 Jim_Obj *nameObjPtr;
9275 Jim_Obj *defaultObjPtr;
9276 int len;
9277
9278
9279 argPtr = Jim_ListGetIndex(interp, argListObjPtr, i);
9280 len = Jim_ListLength(interp, argPtr);
9281 if (len == 0) {
9282 Jim_SetResultString(interp, "argument with no name", -1);
9283 err:
@@ -9288,16 +9488,16 @@
9288 Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
9289 goto err;
9290 }
9291
9292 if (len == 2) {
9293
9294 nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0);
9295 defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1);
9296 }
9297 else {
9298
9299 nameObjPtr = argPtr;
9300 defaultObjPtr = NULL;
9301 }
9302
9303
@@ -9358,29 +9558,29 @@
9358 }
9359
9360 fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
9361 fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
9362
9363
9364 he = Jim_FindHashEntry(&interp->commands, fqold);
9365 if (he == NULL) {
9366 Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
9367 }
9368 else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
9369 Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
9370 }
9371 else {
9372
9373 cmdPtr = Jim_GetHashEntryVal(he);
9374 JimIncrCmdRefCount(cmdPtr);
9375 JimUpdateProcNamespace(interp, cmdPtr, fqnew);
9376 Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
9377
9378
9379 Jim_DeleteHashEntry(&interp->commands, fqold);
9380
9381
9382 Jim_InterpIncrProcEpoch(interp);
9383
9384 ret = JIM_OK;
9385 }
9386
@@ -9419,23 +9619,23 @@
9419 objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
9420 #ifdef jim_ext_namespace
9421 || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
9422 #endif
9423 ) {
9424
9425
9426
 
9427 const char *name = Jim_String(objPtr);
9428 Jim_HashEntry *he;
9429
9430 if (name[0] == ':' && name[1] == ':') {
9431 while (*++name == ':') {
9432 }
9433 }
9434 #ifdef jim_ext_namespace
9435 else if (Jim_Length(interp->framePtr->nsObj)) {
9436
9437 Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
9438 Jim_AppendStrings(interp, nameObj, "::", name, NULL);
9439 he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
9440 Jim_FreeNewObj(interp, nameObj);
9441 if (he) {
@@ -9442,11 +9642,11 @@
9442 goto found;
9443 }
9444 }
9445 #endif
9446
9447
9448 he = Jim_FindHashEntry(&interp->commands, name);
9449 if (he == NULL) {
9450 if (flags & JIM_ERRMSG) {
9451 Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
9452 }
@@ -9455,11 +9655,11 @@
9455 #ifdef jim_ext_namespace
9456 found:
9457 #endif
9458 cmd = Jim_GetHashEntryVal(he);
9459
9460
9461 Jim_FreeIntRep(interp, objPtr);
9462 objPtr->typePtr = &commandObjType;
9463 objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
9464 objPtr->internalRep.cmdValue.cmdPtr = cmd;
9465 objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
@@ -9474,11 +9674,11 @@
9474 return cmd;
9475 }
9476
9477
9478
9479 #define JIM_DICT_SUGAR 100
9480
9481 static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
9482
9483 static const Jim_ObjType variableObjType = {
9484 "variable",
@@ -9488,11 +9688,11 @@
9488 JIM_TYPE_REFERENCES,
9489 };
9490
9491 static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
9492 {
9493
9494 if (nameObjPtr->typePtr != &variableObjType) {
9495 int len;
9496 const char *str = Jim_GetString(nameObjPtr, &len);
9497 if (memchr(str, '\0', len)) {
9498 Jim_SetResultFormatted(interp, "%s name contains embedded null", type);
@@ -9508,18 +9708,18 @@
9508 Jim_CallFrame *framePtr;
9509 Jim_HashEntry *he;
9510 int global;
9511 int len;
9512
9513
9514 if (objPtr->typePtr == &variableObjType) {
9515 framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
9516 if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
9517
9518 return JIM_OK;
9519 }
9520
9521 }
9522 else if (objPtr->typePtr == &dictSubstObjType) {
9523 return JIM_DICT_SUGAR;
9524 }
9525 else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
@@ -9527,11 +9727,11 @@
9527 }
9528
9529
9530 varName = Jim_GetString(objPtr, &len);
9531
9532
9533 if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
9534 return JIM_DICT_SUGAR;
9535 }
9536
9537 if (varName[0] == ':' && varName[1] == ':') {
@@ -9543,23 +9743,23 @@
9543 else {
9544 global = 0;
9545 framePtr = interp->framePtr;
9546 }
9547
9548
9549 he = Jim_FindHashEntry(&framePtr->vars, varName);
9550 if (he == NULL) {
9551 if (!global && framePtr->staticVars) {
9552
9553 he = Jim_FindHashEntry(framePtr->staticVars, varName);
9554 }
9555 if (he == NULL) {
9556 return JIM_ERR;
9557 }
9558 }
9559
9560
9561 Jim_FreeIntRep(interp, objPtr);
9562 objPtr->typePtr = &variableObjType;
9563 objPtr->internalRep.varValue.callFrameId = framePtr->id;
9564 objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he);
9565 objPtr->internalRep.varValue.global = global;
@@ -9574,11 +9774,11 @@
9574 {
9575 const char *name;
9576 Jim_CallFrame *framePtr;
9577 int global;
9578
9579
9580 Jim_Var *var = Jim_Alloc(sizeof(*var));
9581
9582 var->objPtr = valObjPtr;
9583 Jim_IncrRefCount(valObjPtr);
9584 var->linkFramePtr = NULL;
@@ -9593,14 +9793,14 @@
9593 else {
9594 framePtr = interp->framePtr;
9595 global = 0;
9596 }
9597
9598
9599 Jim_AddHashEntry(&framePtr->vars, name, var);
9600
9601
9602 Jim_FreeIntRep(interp, nameObjPtr);
9603 nameObjPtr->typePtr = &variableObjType;
9604 nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
9605 nameObjPtr->internalRep.varValue.varPtr = var;
9606 nameObjPtr->internalRep.varValue.global = global;
@@ -9630,11 +9830,11 @@
9630 if (var->linkFramePtr == NULL) {
9631 Jim_IncrRefCount(valObjPtr);
9632 Jim_DecrRefCount(interp, var->objPtr);
9633 var->objPtr = valObjPtr;
9634 }
9635 else {
9636 Jim_CallFrame *savedCallFrame;
9637
9638 savedCallFrame = interp->framePtr;
9639 interp->framePtr = var->linkFramePtr;
9640 err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
@@ -9691,14 +9891,14 @@
9691 const char *varName;
9692 const char *targetName;
9693 Jim_CallFrame *framePtr;
9694 Jim_Var *varPtr;
9695
9696
9697 switch (SetVariableFromAny(interp, nameObjPtr)) {
9698 case JIM_DICT_SUGAR:
9699
9700 Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
9701 return JIM_ERR;
9702
9703 case JIM_OK:
9704 varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -9706,23 +9906,23 @@
9706 if (varPtr->linkFramePtr == NULL) {
9707 Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
9708 return JIM_ERR;
9709 }
9710
9711
9712 varPtr->linkFramePtr = NULL;
9713 break;
9714 }
9715
9716
9717
9718 varName = Jim_String(nameObjPtr);
9719
9720 if (varName[0] == ':' && varName[1] == ':') {
9721 while (*++varName == ':') {
9722 }
9723
9724 framePtr = interp->topFramePtr;
9725 }
9726 else {
9727 framePtr = interp->framePtr;
9728 }
@@ -9742,15 +9942,15 @@
9742 nameObjPtr);
9743 Jim_DecrRefCount(interp, targetNameObjPtr);
9744 return JIM_ERR;
9745 }
9746
9747
9748 if (framePtr == targetCallFrame) {
9749 Jim_Obj *objPtr = targetNameObjPtr;
9750
9751
9752 while (1) {
9753 if (strcmp(Jim_String(objPtr), varName) == 0) {
9754 Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
9755 Jim_DecrRefCount(interp, targetNameObjPtr);
9756 return JIM_ERR;
@@ -9762,13 +9962,13 @@
9762 break;
9763 objPtr = varPtr->objPtr;
9764 }
9765 }
9766
9767
9768 Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
9769
9770 nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
9771 Jim_DecrRefCount(interp, targetNameObjPtr);
9772 return JIM_OK;
9773 }
9774
@@ -9782,26 +9982,26 @@
9782 return varPtr->objPtr;
9783 }
9784 else {
9785 Jim_Obj *objPtr;
9786
9787
9788 Jim_CallFrame *savedCallFrame = interp->framePtr;
9789
9790 interp->framePtr = varPtr->linkFramePtr;
9791 objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags);
9792 interp->framePtr = savedCallFrame;
9793 if (objPtr) {
9794 return objPtr;
9795 }
9796
9797 }
9798 }
9799 break;
9800
9801 case JIM_DICT_SUGAR:
9802
9803 return JimDictSugarGet(interp, nameObjPtr, flags);
9804 }
9805 if (flags & JIM_ERRMSG) {
9806 Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr);
9807 }
@@ -9851,17 +10051,17 @@
9851 int retval;
9852 Jim_CallFrame *framePtr;
9853
9854 retval = SetVariableFromAny(interp, nameObjPtr);
9855 if (retval == JIM_DICT_SUGAR) {
9856
9857 return JimDictSugarSet(interp, nameObjPtr, NULL);
9858 }
9859 else if (retval == JIM_OK) {
9860 varPtr = nameObjPtr->internalRep.varValue.varPtr;
9861
9862
9863 if (varPtr->linkFramePtr) {
9864 framePtr = interp->framePtr;
9865 interp->framePtr = varPtr->linkFramePtr;
9866 retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
9867 interp->framePtr = framePtr;
@@ -9876,11 +10076,11 @@
9876 framePtr = interp->framePtr;
9877 }
9878
9879 retval = Jim_DeleteHashEntry(&framePtr->vars, name);
9880 if (retval == JIM_OK) {
9881
9882 framePtr->id = interp->callFrameEpoch++;
9883 }
9884 }
9885 }
9886 if (retval != JIM_OK && (flags & JIM_ERRMSG)) {
@@ -9909,11 +10109,11 @@
9909 keyLen = (str + len) - p;
9910 if (str[len - 1] == ')') {
9911 keyLen--;
9912 }
9913
9914
9915 keyObjPtr = Jim_NewStringObj(interp, p, keyLen);
9916
9917 Jim_IncrRefCount(varObjPtr);
9918 Jim_IncrRefCount(keyObjPtr);
9919 *varPtrPtr = varObjPtr;
@@ -9928,23 +10128,23 @@
9928
9929 err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
9930 &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
9931
9932 if (err == JIM_OK) {
9933
9934 Jim_SetEmptyResult(interp);
9935 }
9936 else {
9937 if (!valObjPtr) {
9938
9939 if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) {
9940 Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array",
9941 objPtr);
9942 return err;
9943 }
9944 }
9945
9946 Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array",
9947 (valObjPtr ? "set" : "unset"), objPtr);
9948 }
9949 return err;
9950 }
@@ -9966,11 +10166,11 @@
9966 Jim_SetResultFormatted(interp,
9967 "can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr,
9968 ret < 0 ? "variable isn't" : "no such element in");
9969 }
9970 else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) {
9971
9972 Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr));
9973 }
9974
9975 return resObjPtr;
9976 }
@@ -10008,11 +10208,11 @@
10008 {
10009 if (objPtr->typePtr != &dictSubstObjType) {
10010 Jim_Obj *varObjPtr, *keyObjPtr;
10011
10012 if (objPtr->typePtr == &interpolatedObjType) {
10013
10014
10015 varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
10016 keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
10017
10018 Jim_IncrRefCount(varObjPtr);
@@ -10053,11 +10253,11 @@
10053 static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
10054 {
10055 Jim_Obj *resultObjPtr;
10056
10057 if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) {
10058
10059 resultObjPtr->refCount--;
10060 return resultObjPtr;
10061 }
10062 return NULL;
10063 }
@@ -10076,11 +10276,10 @@
10076 cf->procArgsObjPtr = NULL;
10077 cf->procBodyObjPtr = NULL;
10078 cf->next = NULL;
10079 cf->staticVars = NULL;
10080 cf->localCommands = NULL;
10081 cf->tailcall = 0;
10082 cf->tailcallObj = NULL;
10083 cf->tailcallCmd = NULL;
10084 }
10085 else {
10086 cf = Jim_Alloc(sizeof(*cf));
@@ -10098,11 +10297,11 @@
10098 return cf;
10099 }
10100
10101 static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
10102 {
10103
10104 if (localCommands) {
10105 Jim_Obj *cmdNameObj;
10106
10107 while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
10108 Jim_HashEntry *he;
@@ -10117,20 +10316,20 @@
10117 Jim_Cmd *cmd = Jim_GetHashEntryVal(he);
10118 if (cmd->prevCmd) {
10119 Jim_Cmd *prevCmd = cmd->prevCmd;
10120 cmd->prevCmd = NULL;
10121
10122
10123 JimDecrCmdRefCount(interp, cmd);
10124
10125
10126 Jim_SetHashVal(ht, he, prevCmd);
10127 }
10128 else {
10129 Jim_DeleteHashEntry(ht, fqname);
10130 Jim_InterpIncrProcEpoch(interp);
10131 }
 
10132 }
10133 Jim_DecrRefCount(interp, cmdNameObj);
10134 JimFreeQualifiedName(interp, fqObjName);
10135 }
10136 Jim_FreeStack(localCommands);
@@ -10138,12 +10337,12 @@
10138 }
10139 return JIM_OK;
10140 }
10141
10142
10143 #define JIM_FCF_FULL 0
10144 #define JIM_FCF_REUSE 1
10145 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action)
10146 {
10147 JimDeleteLocalProcs(interp, cf->localCommands);
10148
10149 if (cf->procArgsObjPtr)
@@ -10176,263 +10375,10 @@
10176 cf->next = interp->freeFramesList;
10177 interp->freeFramesList = cf;
10178 }
10179
10180
10181 #ifdef JIM_REFERENCES
10182
10183 static void JimReferencesHTValDestructor(void *interp, void *val)
10184 {
10185 Jim_Reference *refPtr = (void *)val;
10186
10187 Jim_DecrRefCount(interp, refPtr->objPtr);
10188 if (refPtr->finalizerCmdNamePtr != NULL) {
10189 Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10190 }
10191 Jim_Free(val);
10192 }
10193
10194 static unsigned int JimReferencesHTHashFunction(const void *key)
10195 {
10196
10197 const unsigned long *widePtr = key;
10198 unsigned int intValue = (unsigned int)*widePtr;
10199
10200 return Jim_IntHashFunction(intValue);
10201 }
10202
10203 static void *JimReferencesHTKeyDup(void *privdata, const void *key)
10204 {
10205 void *copy = Jim_Alloc(sizeof(unsigned long));
10206
10207 JIM_NOTUSED(privdata);
10208
10209 memcpy(copy, key, sizeof(unsigned long));
10210 return copy;
10211 }
10212
10213 static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2)
10214 {
10215 JIM_NOTUSED(privdata);
10216
10217 return memcmp(key1, key2, sizeof(unsigned long)) == 0;
10218 }
10219
10220 static void JimReferencesHTKeyDestructor(void *privdata, void *key)
10221 {
10222 JIM_NOTUSED(privdata);
10223
10224 Jim_Free(key);
10225 }
10226
10227 static const Jim_HashTableType JimReferencesHashTableType = {
10228 JimReferencesHTHashFunction,
10229 JimReferencesHTKeyDup,
10230 NULL,
10231 JimReferencesHTKeyCompare,
10232 JimReferencesHTKeyDestructor,
10233 JimReferencesHTValDestructor
10234 };
10235
10236
10237
10238 #define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
10239
10240 static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
10241 {
10242 const char *fmt = "<reference.<%s>.%020lu>";
10243
10244 sprintf(buf, fmt, refPtr->tag, id);
10245 return JIM_REFERENCE_SPACE;
10246 }
10247
10248 static void UpdateStringOfReference(struct Jim_Obj *objPtr);
10249
10250 static const Jim_ObjType referenceObjType = {
10251 "reference",
10252 NULL,
10253 NULL,
10254 UpdateStringOfReference,
10255 JIM_TYPE_REFERENCES,
10256 };
10257
10258 static void UpdateStringOfReference(struct Jim_Obj *objPtr)
10259 {
10260 char buf[JIM_REFERENCE_SPACE + 1];
10261
10262 JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id);
10263 JimSetStringBytes(objPtr, buf);
10264 }
10265
10266 static int isrefchar(int c)
10267 {
10268 return (c == '_' || isalnum(c));
10269 }
10270
10271 static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
10272 {
10273 unsigned long value;
10274 int i, len;
10275 const char *str, *start, *end;
10276 char refId[21];
10277 Jim_Reference *refPtr;
10278 Jim_HashEntry *he;
10279 char *endptr;
10280
10281
10282 str = Jim_GetString(objPtr, &len);
10283
10284 if (len < JIM_REFERENCE_SPACE)
10285 goto badformat;
10286
10287 start = str;
10288 end = str + len - 1;
10289 while (*start == ' ')
10290 start++;
10291 while (*end == ' ' && end > start)
10292 end--;
10293 if (end - start + 1 != JIM_REFERENCE_SPACE)
10294 goto badformat;
10295
10296 if (memcmp(start, "<reference.<", 12) != 0)
10297 goto badformat;
10298 if (start[12 + JIM_REFERENCE_TAGLEN] != '>' || end[0] != '>')
10299 goto badformat;
10300
10301 for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10302 if (!isrefchar(start[12 + i]))
10303 goto badformat;
10304 }
10305
10306 memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
10307 refId[20] = '\0';
10308
10309 value = strtoul(refId, &endptr, 10);
10310 if (JimCheckConversion(refId, endptr) != JIM_OK)
10311 goto badformat;
10312
10313 he = Jim_FindHashEntry(&interp->references, &value);
10314 if (he == NULL) {
10315 Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
10316 return JIM_ERR;
10317 }
10318 refPtr = Jim_GetHashEntryVal(he);
10319
10320 Jim_FreeIntRep(interp, objPtr);
10321 objPtr->typePtr = &referenceObjType;
10322 objPtr->internalRep.refValue.id = value;
10323 objPtr->internalRep.refValue.refPtr = refPtr;
10324 return JIM_OK;
10325
10326 badformat:
10327 Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr);
10328 return JIM_ERR;
10329 }
10330
10331 Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
10332 {
10333 struct Jim_Reference *refPtr;
10334 unsigned long id;
10335 Jim_Obj *refObjPtr;
10336 const char *tag;
10337 int tagLen, i;
10338
10339
10340 Jim_CollectIfNeeded(interp);
10341
10342 refPtr = Jim_Alloc(sizeof(*refPtr));
10343 refPtr->objPtr = objPtr;
10344 Jim_IncrRefCount(objPtr);
10345 refPtr->finalizerCmdNamePtr = cmdNamePtr;
10346 if (cmdNamePtr)
10347 Jim_IncrRefCount(cmdNamePtr);
10348 id = interp->referenceNextId++;
10349 Jim_AddHashEntry(&interp->references, &id, refPtr);
10350 refObjPtr = Jim_NewObj(interp);
10351 refObjPtr->typePtr = &referenceObjType;
10352 refObjPtr->bytes = NULL;
10353 refObjPtr->internalRep.refValue.id = id;
10354 refObjPtr->internalRep.refValue.refPtr = refPtr;
10355 interp->referenceNextId++;
10356 tag = Jim_GetString(tagPtr, &tagLen);
10357 if (tagLen > JIM_REFERENCE_TAGLEN)
10358 tagLen = JIM_REFERENCE_TAGLEN;
10359 for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) {
10360 if (i < tagLen && isrefchar(tag[i]))
10361 refPtr->tag[i] = tag[i];
10362 else
10363 refPtr->tag[i] = '_';
10364 }
10365 refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0';
10366 return refObjPtr;
10367 }
10368
10369 Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr)
10370 {
10371 if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR)
10372 return NULL;
10373 return objPtr->internalRep.refValue.refPtr;
10374 }
10375
10376 int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr)
10377 {
10378 Jim_Reference *refPtr;
10379
10380 if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10381 return JIM_ERR;
10382 Jim_IncrRefCount(cmdNamePtr);
10383 if (refPtr->finalizerCmdNamePtr)
10384 Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr);
10385 refPtr->finalizerCmdNamePtr = cmdNamePtr;
10386 return JIM_OK;
10387 }
10388
10389 int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr)
10390 {
10391 Jim_Reference *refPtr;
10392
10393 if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL)
10394 return JIM_ERR;
10395 *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr;
10396 return JIM_OK;
10397 }
10398
10399
10400
10401 static const Jim_HashTableType JimRefMarkHashTableType = {
10402 JimReferencesHTHashFunction,
10403 JimReferencesHTKeyDup,
10404 NULL,
10405 JimReferencesHTKeyCompare,
10406 JimReferencesHTKeyDestructor,
10407 NULL
10408 };
10409
10410
10411 int Jim_Collect(Jim_Interp *interp)
10412 {
10413 int collected = 0;
10414 return collected;
10415 }
10416
10417 #define JIM_COLLECT_ID_PERIOD 5000
10418 #define JIM_COLLECT_TIME_PERIOD 300
10419
10420 void Jim_CollectIfNeeded(Jim_Interp *interp)
10421 {
10422 unsigned long elapsedId;
10423 int elapsedTime;
10424
10425 elapsedId = interp->referenceNextId - interp->lastCollectId;
10426 elapsedTime = time(NULL) - interp->lastCollectTime;
10427
10428
10429 if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) {
10430 Jim_Collect(interp);
10431 }
10432 }
10433 #endif
10434
10435 int Jim_IsBigEndian(void)
10436 {
10437 union {
10438 unsigned short s;
@@ -10479,14 +10425,15 @@
10479 Jim_IncrRefCount(i->nullScriptObj);
10480 Jim_IncrRefCount(i->errorProc);
10481 Jim_IncrRefCount(i->trueObj);
10482 Jim_IncrRefCount(i->falseObj);
10483
10484
10485 Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY);
10486 Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0");
10487
 
10488 Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS);
10489 Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM);
10490 Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR);
10491 Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", Jim_IsBigEndian() ? "bigEndian" : "littleEndian");
10492 Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0");
@@ -10500,11 +10447,11 @@
10500 {
10501 Jim_CallFrame *cf, *cfx;
10502
10503 Jim_Obj *objPtr, *nextObjPtr;
10504
10505
10506 for (cf = i->framePtr; cf; cf = cfx) {
10507 cfx = cf->parent;
10508 JimFreeCallFrame(i, cf, JIM_FCF_FULL);
10509 }
10510
@@ -10553,27 +10500,27 @@
10553 printf("-------------------------------------\n\n");
10554 JimPanic((1, "Live list non empty freeing the interpreter! Leak?"));
10555 }
10556 #endif
10557
10558
10559 objPtr = i->freeList;
10560 while (objPtr) {
10561 nextObjPtr = objPtr->nextObjPtr;
10562 Jim_Free(objPtr);
10563 objPtr = nextObjPtr;
10564 }
10565
10566
10567 for (cf = i->freeFramesList; cf; cf = cfx) {
10568 cfx = cf->next;
10569 if (cf->vars.table)
10570 Jim_FreeHashTable(&cf->vars);
10571 Jim_Free(cf);
10572 }
10573
10574
10575 Jim_Free(i);
10576 }
10577
10578 Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
10579 {
@@ -10594,25 +10541,25 @@
10594 else {
10595 if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) {
10596 level = -1;
10597 }
10598 else {
10599
10600 level = interp->framePtr->level - level;
10601 }
10602 }
10603 }
10604 else {
10605 str = "1";
10606 level = interp->framePtr->level - 1;
10607 }
10608
10609 if (level == 0) {
10610 return interp->topFramePtr;
10611 }
10612 if (level > 0) {
10613
10614 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10615 if (framePtr->level == level) {
10616 return framePtr;
10617 }
10618 }
@@ -10627,19 +10574,19 @@
10627 long level;
10628 Jim_CallFrame *framePtr;
10629
10630 if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) {
10631 if (level <= 0) {
10632
10633 level = interp->framePtr->level + level;
10634 }
10635
10636 if (level == 0) {
10637 return interp->topFramePtr;
10638 }
10639
10640
10641 for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
10642 if (framePtr->level == level) {
10643 return framePtr;
10644 }
10645 }
@@ -10658,11 +10605,11 @@
10658
10659 static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj)
10660 {
10661 int len;
10662
10663
10664 Jim_IncrRefCount(stackTraceObj);
10665 Jim_DecrRefCount(interp, interp->stackTrace);
10666 interp->stackTrace = stackTraceObj;
10667 interp->errorFlag = 1;
10668
@@ -10679,32 +10626,32 @@
10679 {
10680 if (strcmp(procname, "unknown") == 0) {
10681 procname = "";
10682 }
10683 if (!*procname && !Jim_Length(fileNameObj)) {
10684
10685 return;
10686 }
10687
10688 if (Jim_IsShared(interp->stackTrace)) {
10689 Jim_DecrRefCount(interp, interp->stackTrace);
10690 interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace);
10691 Jim_IncrRefCount(interp->stackTrace);
10692 }
10693
10694
10695 if (!*procname && Jim_Length(fileNameObj)) {
10696
10697 int len = Jim_ListLength(interp, interp->stackTrace);
10698
10699 if (len >= 3) {
10700 Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3);
10701 if (Jim_Length(objPtr)) {
10702
10703 objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2);
10704 if (Jim_Length(objPtr) == 0) {
10705
10706 ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0);
10707 ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0);
10708 return;
10709 }
10710 }
@@ -10806,18 +10753,18 @@
10806 {
10807 jim_wide wideValue;
10808 const char *str;
10809
10810 if (objPtr->typePtr == &coercedDoubleObjType) {
10811
10812 objPtr->typePtr = &intObjType;
10813 return JIM_OK;
10814 }
10815
10816
10817 str = Jim_String(objPtr);
10818
10819 if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) {
10820 if (flags & JIM_ERRMSG) {
10821 Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr);
10822 }
10823 return JIM_ERR;
@@ -10824,11 +10771,11 @@
10824 }
10825 if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) {
10826 Jim_SetResultString(interp, "Integer value too big to be represented", -1);
10827 return JIM_ERR;
10828 }
10829
10830 Jim_FreeIntRep(interp, objPtr);
10831 objPtr->typePtr = &intObjType;
10832 objPtr->internalRep.wideValue = wideValue;
10833 return JIM_OK;
10834 }
@@ -10923,17 +10870,17 @@
10923 {
10924 char buf[JIM_DOUBLE_SPACE + 1];
10925 int i;
10926 int len = sprintf(buf, "%.12g", value);
10927
10928
10929 for (i = 0; i < len; i++) {
10930 if (buf[i] == '.' || buf[i] == 'e') {
10931 #if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
10932 char *e = strchr(buf, 'e');
10933 if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
10934
10935 e += 2;
10936 memmove(e, e + 1, len - (e - buf));
10937 }
10938 #endif
10939 break;
@@ -10955,38 +10902,38 @@
10955 const char *str;
10956
10957 str = Jim_String(objPtr);
10958
10959 #ifdef HAVE_LONG_LONG
10960
10961 #define MIN_INT_IN_DOUBLE -(1LL << 53)
10962 #define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1)
10963
10964 if (objPtr->typePtr == &intObjType
10965 && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE
10966 && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) {
10967
10968
10969 objPtr->typePtr = &coercedDoubleObjType;
10970 return JIM_OK;
10971 }
10972 else
10973 #endif
10974 if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) {
10975
10976 Jim_FreeIntRep(interp, objPtr);
10977 objPtr->typePtr = &coercedDoubleObjType;
10978 objPtr->internalRep.wideValue = wideValue;
10979 return JIM_OK;
10980 }
10981 else {
10982
10983 if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) {
10984 Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr);
10985 return JIM_ERR;
10986 }
10987
10988 Jim_FreeIntRep(interp, objPtr);
10989 }
10990 objPtr->typePtr = &doubleObjType;
10991 objPtr->internalRep.doubleValue = doubleValue;
10992 return JIM_OK;
@@ -11018,10 +10965,50 @@
11018 objPtr->typePtr = &doubleObjType;
11019 objPtr->bytes = NULL;
11020 objPtr->internalRep.doubleValue = doubleValue;
11021 return objPtr;
11022 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11023
11024 static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec);
11025 static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr);
11026 static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
11027 static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -11069,11 +11056,11 @@
11069 #define JIM_ELESTR_QUOTE 2
11070 static unsigned char ListElementQuotingType(const char *s, int len)
11071 {
11072 int i, level, blevel, trySimple = 1;
11073
11074
11075 if (len == 0)
11076 return JIM_ELESTR_BRACE;
11077 if (s[0] == '"' || s[0] == '{') {
11078 trySimple = 0;
11079 goto testbrace;
@@ -11091,19 +11078,20 @@
11091 case '\n':
11092 case '\t':
11093 case '\f':
11094 case '\v':
11095 trySimple = 0;
 
11096 case '{':
11097 case '}':
11098 goto testbrace;
11099 }
11100 }
11101 return JIM_ELESTR_SIMPLE;
11102
11103 testbrace:
11104
11105 if (s[len - 1] == '\\')
11106 return JIM_ELESTR_QUOTE;
11107 level = 0;
11108 blevel = 0;
11109 for (i = 0; i < len; i++) {
@@ -11219,11 +11207,11 @@
11219 int i, bufLen, realLength;
11220 const char *strRep;
11221 char *p;
11222 unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN];
11223
11224
11225 if (objc > STATIC_QUOTING_LEN) {
11226 quotingType = Jim_Alloc(objc);
11227 }
11228 else {
11229 quotingType = staticQuoting;
@@ -11238,25 +11226,25 @@
11238 case JIM_ELESTR_SIMPLE:
11239 if (i != 0 || strRep[0] != '#') {
11240 bufLen += len;
11241 break;
11242 }
11243
11244 quotingType[i] = JIM_ELESTR_BRACE;
11245
11246 case JIM_ELESTR_BRACE:
11247 bufLen += len + 2;
11248 break;
11249 case JIM_ELESTR_QUOTE:
11250 bufLen += len * 2;
11251 break;
11252 }
11253 bufLen++;
11254 }
11255 bufLen++;
11256
11257
11258 p = objPtr->bytes = Jim_Alloc(bufLen + 1);
11259 realLength = 0;
11260 for (i = 0; i < objc; i++) {
11261 int len, qlen;
11262
@@ -11283,17 +11271,17 @@
11283 qlen = BackslashQuoteString(strRep, len, p);
11284 p += qlen;
11285 realLength += qlen;
11286 break;
11287 }
11288
11289 if (i + 1 != objc) {
11290 *p++ = ' ';
11291 realLength++;
11292 }
11293 }
11294 *p = '\0';
11295 objPtr->length = realLength;
11296
11297 if (quotingType != staticQuoting) {
11298 Jim_Free(quotingType);
11299 }
@@ -11324,21 +11312,21 @@
11324 listObjPtrPtr = JimDictPairs(objPtr, &len);
11325 for (i = 0; i < len; i++) {
11326 Jim_IncrRefCount(listObjPtrPtr[i]);
11327 }
11328
11329
11330 Jim_FreeIntRep(interp, objPtr);
11331 objPtr->typePtr = &listObjType;
11332 objPtr->internalRep.listValue.len = len;
11333 objPtr->internalRep.listValue.maxLen = len;
11334 objPtr->internalRep.listValue.ele = listObjPtrPtr;
11335
11336 return JIM_OK;
11337 }
11338
11339
11340 if (objPtr->typePtr == &sourceObjType) {
11341 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
11342 linenr = objPtr->internalRep.sourceValue.lineNumber;
11343 }
11344 else {
@@ -11345,20 +11333,20 @@
11345 fileNameObj = interp->emptyObj;
11346 linenr = 1;
11347 }
11348 Jim_IncrRefCount(fileNameObj);
11349
11350
11351 str = Jim_GetString(objPtr, &strLen);
11352
11353 Jim_FreeIntRep(interp, objPtr);
11354 objPtr->typePtr = &listObjType;
11355 objPtr->internalRep.listValue.len = 0;
11356 objPtr->internalRep.listValue.maxLen = 0;
11357 objPtr->internalRep.listValue.ele = NULL;
11358
11359
11360 if (strLen) {
11361 JimParserInit(&parser, str, strLen, linenr);
11362 while (!parser.eof) {
11363 Jim_Obj *elementPtr;
11364
@@ -11488,11 +11476,11 @@
11488 Jim_Obj *compare_script;
11489 int rc;
11490
11491 jim_wide ret = 0;
11492
11493
11494 compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command);
11495 Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj);
11496 Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj);
11497
11498 rc = Jim_EvalObj(sort_info->interp, compare_script);
@@ -11510,23 +11498,23 @@
11510 int dst = 0;
11511 Jim_Obj **ele = listObjPtr->internalRep.listValue.ele;
11512
11513 for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) {
11514 if (comp(&ele[dst], &ele[src]) == 0) {
11515
11516 Jim_DecrRefCount(sort_info->interp, ele[dst]);
11517 }
11518 else {
11519
11520 dst++;
11521 }
11522 ele[dst] = ele[src];
11523 }
11524
11525 ele[++dst] = ele[src];
11526
11527
11528 listObjPtr->internalRep.listValue.len = dst;
11529 }
11530
11531
11532 static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info)
@@ -11540,11 +11528,11 @@
11540 int rc;
11541
11542 JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object"));
11543 SetListFromAny(interp, listObjPtr);
11544
11545
11546 prev_info = sort_info;
11547 sort_info = info;
11548
11549 vector = listObjPtr->internalRep.listValue.ele;
11550 len = listObjPtr->internalRep.listValue.len;
@@ -11563,16 +11551,17 @@
11563 break;
11564 case JIM_LSORT_COMMAND:
11565 fn = ListSortCommand;
11566 break;
11567 default:
11568 fn = NULL;
11569 JimPanic((1, "ListSort called with invalid sort type"));
 
11570 }
11571
11572 if (info->indexed) {
11573
11574 info->subfn = fn;
11575 fn = ListSortIndexHelper;
11576 }
11577
11578 if ((rc = setjmp(info->jmpbuf)) == 0) {
@@ -11596,11 +11585,11 @@
11596 int i;
11597 Jim_Obj **point;
11598
11599 if (requiredLen > listPtr->internalRep.listValue.maxLen) {
11600 if (requiredLen < 2) {
11601
11602 requiredLen = 4;
11603 }
11604 else {
11605 requiredLen *= 2;
11606 }
@@ -11782,34 +11771,34 @@
11782 for (i = 0; i < objc; i++)
11783 ListAppendList(objPtr, objv[i]);
11784 return objPtr;
11785 }
11786 else {
11787
11788 int len = 0, objLen;
11789 char *bytes, *p;
11790
11791
11792 for (i = 0; i < objc; i++) {
11793 len += Jim_Length(objv[i]);
11794 }
11795 if (objc)
11796 len += objc - 1;
11797
11798 p = bytes = Jim_Alloc(len + 1);
11799 for (i = 0; i < objc; i++) {
11800 const char *s = Jim_GetString(objv[i], &objLen);
11801
11802
11803 while (objLen && isspace(UCHAR(*s))) {
11804 s++;
11805 objLen--;
11806 len--;
11807 }
11808
11809 while (objLen && isspace(UCHAR(s[objLen - 1]))) {
11810
11811 if (objLen > 1 && s[objLen - 2] == '\\') {
11812 break;
11813 }
11814 objLen--;
11815 len--;
@@ -11836,11 +11825,11 @@
11836 int len, rangeLen;
11837
11838 if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
11839 Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
11840 return NULL;
11841 len = Jim_ListLength(interp, listObjPtr);
11842 first = JimRelToAbsIndex(len, first);
11843 last = JimRelToAbsIndex(len, last);
11844 JimRelToAbsRange(len, &first, &last, &rangeLen);
11845 if (first == 0 && last == len) {
11846 return listObjPtr;
@@ -11876,16 +11865,16 @@
11876 {
11877 Jim_DecrRefCount(interp, (Jim_Obj *)val);
11878 }
11879
11880 static const Jim_HashTableType JimDictHashTableType = {
11881 JimObjectHTHashFunction,
11882 JimObjectHTKeyValDup,
11883 JimObjectHTKeyValDup,
11884 JimObjectHTKeyCompare,
11885 JimObjectHTKeyValDestructor,
11886 JimObjectHTKeyValDestructor
11887 };
11888
11889 static const Jim_ObjType dictObjType = {
11890 "dict",
11891 FreeDictInternalRep,
@@ -11906,17 +11895,17 @@
11906 {
11907 Jim_HashTable *ht, *dupHt;
11908 Jim_HashTableIterator htiter;
11909 Jim_HashEntry *he;
11910
11911
11912 ht = srcPtr->internalRep.ptr;
11913 dupHt = Jim_Alloc(sizeof(*dupHt));
11914 Jim_InitHashTable(dupHt, &JimDictHashTableType, interp);
11915 if (ht->size != 0)
11916 Jim_ExpandHashTable(dupHt, ht->size);
11917
11918 JimInitHashTableIterator(ht, &htiter);
11919 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
11920 Jim_AddHashEntry(dupHt, he->key, he->u.val);
11921 }
11922
@@ -11932,11 +11921,11 @@
11932 Jim_Obj **objv;
11933 int i;
11934
11935 ht = dictPtr->internalRep.ptr;
11936
11937
11938 objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
11939 JimInitHashTableIterator(ht, &htiter);
11940 i = 0;
11941 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
11942 objv[i++] = Jim_GetHashEntryKey(he);
@@ -11946,15 +11935,15 @@
11946 return objv;
11947 }
11948
11949 static void UpdateStringOfDict(struct Jim_Obj *objPtr)
11950 {
11951
11952 int len;
11953 Jim_Obj **objv = JimDictPairs(objPtr, &len);
11954
11955
11956 JimMakeListStringRep(objPtr, objv, len);
11957
11958 Jim_Free(objv);
11959 }
11960
@@ -11968,18 +11957,18 @@
11968
11969 if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) {
11970 Jim_String(objPtr);
11971 }
11972
11973
11974 listlen = Jim_ListLength(interp, objPtr);
11975 if (listlen % 2) {
11976 Jim_SetResultString(interp, "missing value to go with key", -1);
11977 return JIM_ERR;
11978 }
11979 else {
11980
11981 Jim_HashTable *ht;
11982 int i;
11983
11984 ht = Jim_Alloc(sizeof(*ht));
11985 Jim_InitHashTable(ht, &JimDictHashTableType, interp);
@@ -12004,11 +11993,11 @@
12004 static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
12005 Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr)
12006 {
12007 Jim_HashTable *ht = objPtr->internalRep.ptr;
12008
12009 if (valueObjPtr == NULL) {
12010 return Jim_DeleteHashEntry(ht, keyObjPtr);
12011 }
12012 Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr);
12013 return JIM_OK;
12014 }
@@ -12104,11 +12093,11 @@
12104 int shared, i;
12105
12106 varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
12107 if (objPtr == NULL) {
12108 if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
12109
12110 return JIM_ERR;
12111 }
12112 varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
12113 if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) {
12114 Jim_FreeNewObj(interp, varObjPtr);
@@ -12118,26 +12107,26 @@
12118 if ((shared = Jim_IsShared(objPtr)))
12119 varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
12120 for (i = 0; i < keyc; i++) {
12121 dictObjPtr = objPtr;
12122
12123
12124 if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
12125 goto err;
12126 }
12127
12128 if (i == keyc - 1) {
12129
12130 if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
12131 if (newObjPtr || (flags & JIM_MUSTEXIST)) {
12132 goto err;
12133 }
12134 }
12135 break;
12136 }
12137
12138
12139 Jim_InvalidateStringRep(dictObjPtr);
12140 if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
12141 newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) {
12142 if (Jim_IsShared(objPtr)) {
12143 objPtr = Jim_DuplicateObj(interp, objPtr);
@@ -12150,11 +12139,11 @@
12150 }
12151 objPtr = Jim_NewDictObj(interp, NULL, 0);
12152 DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
12153 }
12154 }
12155
12156 Jim_InvalidateStringRep(objPtr);
12157 Jim_InvalidateStringRep(varObjPtr);
12158 if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
12159 goto err;
12160 }
@@ -12187,11 +12176,11 @@
12187 char buf[JIM_INTEGER_SPACE + 1];
12188 if (objPtr->internalRep.intValue >= 0) {
12189 sprintf(buf, "%d", objPtr->internalRep.intValue);
12190 }
12191 else {
12192
12193 sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
12194 }
12195 JimSetStringBytes(objPtr, buf);
12196 }
12197 }
@@ -12200,14 +12189,14 @@
12200 {
12201 int idx, end = 0;
12202 const char *str;
12203 char *endptr;
12204
12205
12206 str = Jim_String(objPtr);
12207
12208
12209 if (strncmp(str, "end", 3) == 0) {
12210 end = 1;
12211 str += 3;
12212 idx = 0;
12213 }
@@ -12218,21 +12207,21 @@
12218 goto badindex;
12219 }
12220 str = endptr;
12221 }
12222
12223
12224 if (*str == '+' || *str == '-') {
12225 int sign = (*str == '+' ? 1 : -1);
12226
12227 idx += sign * jim_strtol(++str, &endptr);
12228 if (str == endptr || *endptr) {
12229 goto badindex;
12230 }
12231 str = endptr;
12232 }
12233
12234 while (isspace(UCHAR(*str))) {
12235 str++;
12236 }
12237 if (*str) {
12238 goto badindex;
@@ -12240,19 +12229,19 @@
12240 if (end) {
12241 if (idx > 0) {
12242 idx = INT_MAX;
12243 }
12244 else {
12245
12246 idx--;
12247 }
12248 }
12249 else if (idx < 0) {
12250 idx = -INT_MAX;
12251 }
12252
12253
12254 Jim_FreeIntRep(interp, objPtr);
12255 objPtr->typePtr = &indexObjType;
12256 objPtr->internalRep.intValue = idx;
12257 return JIM_OK;
12258
@@ -12262,11 +12251,11 @@
12262 return JIM_ERR;
12263 }
12264
12265 int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
12266 {
12267
12268 if (objPtr->typePtr == &intObjType) {
12269 jim_wide val = JimWideValue(objPtr);
12270
12271 if (val < 0)
12272 *indexPtr = -INT_MAX;
@@ -12319,18 +12308,18 @@
12319 static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
12320 {
12321 int returnCode;
12322 jim_wide wideValue;
12323
12324
12325 if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR)
12326 returnCode = (int)wideValue;
12327 else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) {
12328 Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr);
12329 return JIM_ERR;
12330 }
12331
12332 Jim_FreeIntRep(interp, objPtr);
12333 objPtr->typePtr = &returnCodeObjType;
12334 objPtr->internalRep.intValue = returnCode;
12335 return JIM_OK;
12336 }
@@ -12344,19 +12333,20 @@
12344 }
12345
12346 static int JimParseExprOperator(struct JimParserCtx *pc);
12347 static int JimParseExprNumber(struct JimParserCtx *pc);
12348 static int JimParseExprIrrational(struct JimParserCtx *pc);
 
12349
12350
12351
12352
12353 enum
12354 {
12355
12356
12357 JIM_EXPROP_MUL = JIM_TT_EXPR_OP,
12358 JIM_EXPROP_DIV,
12359 JIM_EXPROP_MOD,
12360 JIM_EXPROP_SUB,
12361 JIM_EXPROP_ADD,
12362 JIM_EXPROP_LSHIFT,
@@ -12367,66 +12357,67 @@
12367 JIM_EXPROP_GT,
12368 JIM_EXPROP_LTE,
12369 JIM_EXPROP_GTE,
12370 JIM_EXPROP_NUMEQ,
12371 JIM_EXPROP_NUMNE,
12372 JIM_EXPROP_BITAND,
12373 JIM_EXPROP_BITXOR,
12374 JIM_EXPROP_BITOR,
12375
12376
12377 JIM_EXPROP_LOGICAND,
12378 JIM_EXPROP_LOGICAND_LEFT,
12379 JIM_EXPROP_LOGICAND_RIGHT,
12380
12381
12382 JIM_EXPROP_LOGICOR,
12383 JIM_EXPROP_LOGICOR_LEFT,
12384 JIM_EXPROP_LOGICOR_RIGHT,
12385
12386
12387
12388 JIM_EXPROP_TERNARY,
12389 JIM_EXPROP_TERNARY_LEFT,
12390 JIM_EXPROP_TERNARY_RIGHT,
12391
12392
12393 JIM_EXPROP_COLON,
12394 JIM_EXPROP_COLON_LEFT,
12395 JIM_EXPROP_COLON_RIGHT,
12396
12397 JIM_EXPROP_POW,
12398
12399
12400 JIM_EXPROP_STREQ,
12401 JIM_EXPROP_STRNE,
12402 JIM_EXPROP_STRIN,
12403 JIM_EXPROP_STRNI,
12404
12405
12406 JIM_EXPROP_NOT,
12407 JIM_EXPROP_BITNOT,
12408 JIM_EXPROP_UNARYMINUS,
12409 JIM_EXPROP_UNARYPLUS,
12410
12411
12412 JIM_EXPROP_FUNC_FIRST,
12413 JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST,
12414 JIM_EXPROP_FUNC_WIDE,
12415 JIM_EXPROP_FUNC_ABS,
12416 JIM_EXPROP_FUNC_DOUBLE,
12417 JIM_EXPROP_FUNC_ROUND,
12418 JIM_EXPROP_FUNC_RAND,
12419 JIM_EXPROP_FUNC_SRAND,
12420
12421
12422 JIM_EXPROP_FUNC_SIN,
12423 JIM_EXPROP_FUNC_COS,
12424 JIM_EXPROP_FUNC_TAN,
12425 JIM_EXPROP_FUNC_ASIN,
12426 JIM_EXPROP_FUNC_ACOS,
12427 JIM_EXPROP_FUNC_ATAN,
 
12428 JIM_EXPROP_FUNC_SINH,
12429 JIM_EXPROP_FUNC_COSH,
12430 JIM_EXPROP_FUNC_TANH,
12431 JIM_EXPROP_FUNC_CEIL,
12432 JIM_EXPROP_FUNC_FLOOR,
@@ -12433,10 +12424,12 @@
12433 JIM_EXPROP_FUNC_EXP,
12434 JIM_EXPROP_FUNC_LOG,
12435 JIM_EXPROP_FUNC_LOG10,
12436 JIM_EXPROP_FUNC_SQRT,
12437 JIM_EXPROP_FUNC_POW,
 
 
12438 };
12439
12440 struct JimExprState
12441 {
12442 Jim_Obj **stack;
@@ -12513,11 +12506,15 @@
12513 case JIM_EXPROP_UNARYPLUS:
12514 dC = dA;
12515 intresult = 0;
12516 break;
12517 case JIM_EXPROP_FUNC_ABS:
 
 
 
12518 dC = dA >= 0 ? dA : -dA;
 
12519 intresult = 0;
12520 break;
12521 case JIM_EXPROP_UNARYMINUS:
12522 dC = -dA;
12523 intresult = 0;
@@ -12705,16 +12702,16 @@
12705 }
12706 }
12707 break;
12708 case JIM_EXPROP_ROTL:
12709 case JIM_EXPROP_ROTR:{
12710
12711 unsigned long uA = (unsigned long)wA;
12712 unsigned long uB = (unsigned long)wB;
12713 const unsigned int S = sizeof(unsigned long) * 8;
12714
12715
12716 uB %= S;
12717
12718 if (e->opcode == JIM_EXPROP_ROTR) {
12719 uB = S - uB;
12720 }
@@ -12736,11 +12733,10 @@
12736
12737
12738
12739 static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
12740 {
12741 int intresult = 1;
12742 int rc = JIM_OK;
12743 double dA, dB, dC = 0;
12744 jim_wide wA, wB, wC = 0;
12745
12746 Jim_Obj *B = ExprPop(e);
@@ -12748,30 +12744,36 @@
12748
12749 if ((A->typePtr != &doubleObjType || A->bytes) &&
12750 (B->typePtr != &doubleObjType || B->bytes) &&
12751 JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) {
12752
12753
12754
12755 switch (e->opcode) {
12756 case JIM_EXPROP_POW:
12757 case JIM_EXPROP_FUNC_POW:
 
 
 
 
 
12758 wC = JimPowWide(wA, wB);
12759 break;
12760 case JIM_EXPROP_ADD:
12761 wC = wA + wB;
12762 break;
12763 case JIM_EXPROP_SUB:
12764 wC = wA - wB;
12765 break;
12766 case JIM_EXPROP_MUL:
12767 wC = wA * wB;
12768 break;
12769 case JIM_EXPROP_DIV:
12770 if (wB == 0) {
12771 Jim_SetResultString(interp, "Division by zero", -1);
12772 rc = JIM_ERR;
 
12773 }
12774 else {
12775 if (wB < 0) {
12776 wB = -wB;
12777 wA = -wA;
@@ -12778,55 +12780,67 @@
12778 }
12779 wC = wA / wB;
12780 if (wA % wB < 0) {
12781 wC--;
12782 }
 
12783 }
12784 break;
12785 case JIM_EXPROP_LT:
12786 wC = wA < wB;
12787 break;
12788 case JIM_EXPROP_GT:
12789 wC = wA > wB;
12790 break;
12791 case JIM_EXPROP_LTE:
12792 wC = wA <= wB;
12793 break;
12794 case JIM_EXPROP_GTE:
12795 wC = wA >= wB;
12796 break;
12797 case JIM_EXPROP_NUMEQ:
12798 wC = wA == wB;
12799 break;
12800 case JIM_EXPROP_NUMNE:
12801 wC = wA != wB;
12802 break;
12803 default:
12804 abort();
12805 }
12806 }
12807 else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
12808 intresult = 0;
12809 switch (e->opcode) {
 
12810 case JIM_EXPROP_POW:
12811 case JIM_EXPROP_FUNC_POW:
12812 #ifdef JIM_MATH_FUNCTIONS
12813 dC = pow(dA, dB);
12814 #else
12815 Jim_SetResultString(interp, "unsupported", -1);
12816 rc = JIM_ERR;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12817 #endif
12818 break;
12819 case JIM_EXPROP_ADD:
12820 dC = dA + dB;
12821 break;
12822 case JIM_EXPROP_SUB:
12823 dC = dA - dB;
12824 break;
12825 case JIM_EXPROP_MUL:
12826 dC = dA * dB;
12827 break;
12828 case JIM_EXPROP_DIV:
12829 if (dB == 0) {
12830 #ifdef INFINITY
12831 dC = dA < 0 ? -INFINITY : INFINITY;
12832 #else
@@ -12834,83 +12848,70 @@
12834 #endif
12835 }
12836 else {
12837 dC = dA / dB;
12838 }
12839 break;
12840 case JIM_EXPROP_LT:
12841 wC = dA < dB;
12842 intresult = 1;
12843 break;
12844 case JIM_EXPROP_GT:
12845 wC = dA > dB;
12846 intresult = 1;
12847 break;
12848 case JIM_EXPROP_LTE:
12849 wC = dA <= dB;
12850 intresult = 1;
12851 break;
12852 case JIM_EXPROP_GTE:
12853 wC = dA >= dB;
12854 intresult = 1;
12855 break;
12856 case JIM_EXPROP_NUMEQ:
12857 wC = dA == dB;
12858 intresult = 1;
12859 break;
12860 case JIM_EXPROP_NUMNE:
12861 wC = dA != dB;
12862 intresult = 1;
12863 break;
12864 default:
12865 abort();
12866 }
12867 }
12868 else {
12869
12870
12871
 
12872 int i = Jim_StringCompareObj(interp, A, B, 0);
12873
12874 switch (e->opcode) {
12875 case JIM_EXPROP_LT:
12876 wC = i < 0;
12877 break;
12878 case JIM_EXPROP_GT:
12879 wC = i > 0;
12880 break;
12881 case JIM_EXPROP_LTE:
12882 wC = i <= 0;
12883 break;
12884 case JIM_EXPROP_GTE:
12885 wC = i >= 0;
12886 break;
12887 case JIM_EXPROP_NUMEQ:
12888 wC = i == 0;
12889 break;
12890 case JIM_EXPROP_NUMNE:
12891 wC = i != 0;
12892 break;
12893 default:
12894 rc = JIM_ERR;
12895 break;
12896 }
12897 }
12898
12899 if (rc == JIM_OK) {
12900 if (intresult) {
12901 ExprPush(e, Jim_NewIntObj(interp, wC));
12902 }
12903 else {
12904 ExprPush(e, Jim_NewDoubleObj(interp, dC));
12905 }
12906 }
12907
12908 Jim_DecrRefCount(interp, A);
12909 Jim_DecrRefCount(interp, B);
12910
12911 return rc;
 
 
 
 
 
 
12912 }
12913
12914 static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
12915 {
12916 int listlen;
@@ -12959,16 +12960,20 @@
12959
12960 static int ExprBool(Jim_Interp *interp, Jim_Obj *obj)
12961 {
12962 long l;
12963 double d;
 
12964
12965 if (Jim_GetLong(interp, obj, &l) == JIM_OK) {
12966 return l != 0;
12967 }
12968 if (Jim_GetDouble(interp, obj, &d) == JIM_OK) {
12969 return d != 0;
 
 
 
12970 }
12971 return -1;
12972 }
12973
12974 static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e)
@@ -12977,21 +12982,21 @@
12977 Jim_Obj *A = ExprPop(e);
12978 int rc = JIM_OK;
12979
12980 switch (ExprBool(interp, A)) {
12981 case 0:
12982
12983 e->skip = JimWideValue(skip);
12984 ExprPush(e, Jim_NewIntObj(interp, 0));
12985 break;
12986
12987 case 1:
12988
12989 break;
12990
12991 case -1:
12992
12993 rc = JIM_ERR;
12994 }
12995 Jim_DecrRefCount(interp, A);
12996 Jim_DecrRefCount(interp, skip);
12997
@@ -13004,21 +13009,21 @@
13004 Jim_Obj *A = ExprPop(e);
13005 int rc = JIM_OK;
13006
13007 switch (ExprBool(interp, A)) {
13008 case 0:
13009
13010 break;
13011
13012 case 1:
13013
13014 e->skip = JimWideValue(skip);
13015 ExprPush(e, Jim_NewIntObj(interp, 1));
13016 break;
13017
13018 case -1:
13019
13020 rc = JIM_ERR;
13021 break;
13022 }
13023 Jim_DecrRefCount(interp, A);
13024 Jim_DecrRefCount(interp, skip);
@@ -13039,11 +13044,11 @@
13039 case 1:
13040 ExprPush(e, Jim_NewIntObj(interp, 1));
13041 break;
13042
13043 case -1:
13044
13045 rc = JIM_ERR;
13046 break;
13047 }
13048 Jim_DecrRefCount(interp, A);
13049
@@ -13054,27 +13059,27 @@
13054 {
13055 Jim_Obj *skip = ExprPop(e);
13056 Jim_Obj *A = ExprPop(e);
13057 int rc = JIM_OK;
13058
13059
13060 ExprPush(e, A);
13061
13062 switch (ExprBool(interp, A)) {
13063 case 0:
13064
13065 e->skip = JimWideValue(skip);
13066
13067 ExprPush(e, Jim_NewIntObj(interp, 0));
13068 break;
13069
13070 case 1:
13071
13072 break;
13073
13074 case -1:
13075
13076 rc = JIM_ERR;
13077 break;
13078 }
13079 Jim_DecrRefCount(interp, A);
13080 Jim_DecrRefCount(interp, skip);
@@ -13086,15 +13091,15 @@
13086 {
13087 Jim_Obj *skip = ExprPop(e);
13088 Jim_Obj *B = ExprPop(e);
13089 Jim_Obj *A = ExprPop(e);
13090
13091
13092 if (ExprBool(interp, A)) {
13093
13094 e->skip = JimWideValue(skip);
13095
13096 ExprPush(e, B);
13097 }
13098
13099 Jim_DecrRefCount(interp, skip);
13100 Jim_DecrRefCount(interp, A);
@@ -13110,15 +13115,16 @@
13110 enum
13111 {
13112 LAZY_NONE,
13113 LAZY_OP,
13114 LAZY_LEFT,
13115 LAZY_RIGHT
 
13116 };
13117
13118 #define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1}
13119 #define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1}
13120
13121 static const struct Jim_ExprOperator Jim_ExprOperators[] = {
13122 OPRINIT("*", 110, 2, JimExprOpBin),
13123 OPRINIT("/", 110, 2, JimExprOpBin),
13124 OPRINIT("%", 110, 2, JimExprOpIntBin),
@@ -13142,27 +13148,28 @@
13142
13143 OPRINIT("&", 50, 2, JimExprOpIntBin),
13144 OPRINIT("^", 49, 2, JimExprOpIntBin),
13145 OPRINIT("|", 48, 2, JimExprOpIntBin),
13146
13147 OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP),
13148 OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT),
13149 OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13150
13151 OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP),
13152 OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT),
13153 OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT),
13154
13155 OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP),
13156 OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT),
13157 OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13158
13159 OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP),
13160 OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT),
13161 OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT),
13162
13163 OPRINIT("**", 250, 2, JimExprOpBin),
 
13164
13165 OPRINIT("eq", 60, 2, JimExprOpStrBin),
13166 OPRINIT("ne", 60, 2, JimExprOpStrBin),
13167
13168 OPRINIT("in", 55, 2, JimExprOpStrBin),
@@ -13188,10 +13195,11 @@
13188 OPRINIT("cos", 200, 1, JimExprOpDoubleUnary),
13189 OPRINIT("tan", 200, 1, JimExprOpDoubleUnary),
13190 OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
13191 OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
13192 OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
 
13193 OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
13194 OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
13195 OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
13196 OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary),
13197 OPRINIT("floor", 200, 1, JimExprOpDoubleUnary),
@@ -13198,10 +13206,12 @@
13198 OPRINIT("exp", 200, 1, JimExprOpDoubleUnary),
13199 OPRINIT("log", 200, 1, JimExprOpDoubleUnary),
13200 OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
13201 OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
13202 OPRINIT("pow", 200, 2, JimExprOpBin),
 
 
13203 #endif
13204 };
13205 #undef OPRINIT
13206 #undef OPRINIT_LAZY
13207
@@ -13208,20 +13218,20 @@
13208 #define JIM_EXPR_OPERATORS_NUM \
13209 (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator))
13210
13211 static int JimParseExpression(struct JimParserCtx *pc)
13212 {
13213
13214 while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) {
13215 if (*pc->p == '\n') {
13216 pc->linenr++;
13217 }
13218 pc->p++;
13219 pc->len--;
13220 }
13221
13222
13223 pc->tline = pc->linenr;
13224 pc->tstart = pc->p;
13225
13226 if (pc->len == 0) {
13227 pc->tend = pc->p;
@@ -13247,11 +13257,11 @@
13247 return JimParseCmd(pc);
13248 case '$':
13249 if (JimParseVar(pc) == JIM_ERR)
13250 return JimParseExprOperator(pc);
13251 else {
13252
13253 if (pc->tt == JIM_TT_EXPRSUGAR) {
13254 return JIM_ERR;
13255 }
13256 return JIM_OK;
13257 }
@@ -13276,10 +13286,18 @@
13276 case 'N':
13277 case 'I':
13278 case 'n':
13279 case 'i':
13280 if (JimParseExprIrrational(pc) == JIM_ERR)
 
 
 
 
 
 
 
 
13281 return JimParseExprOperator(pc);
13282 break;
13283 default:
13284 return JimParseExprOperator(pc);
13285 break;
@@ -13289,21 +13307,21 @@
13289
13290 static int JimParseExprNumber(struct JimParserCtx *pc)
13291 {
13292 char *end;
13293
13294
13295 pc->tt = JIM_TT_EXPR_INT;
13296
13297 jim_strtoull(pc->p, (char **)&pc->p);
13298
13299 if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) {
13300 if (strtod(pc->tstart, &end)) { }
13301 if (end == pc->tstart)
13302 return JIM_ERR;
13303 if (end > pc->p) {
13304
13305 pc->tt = JIM_TT_EXPR_DOUBLE;
13306 pc->p = end;
13307 }
13308 }
13309 pc->tend = pc->p - 1;
@@ -13327,17 +13345,38 @@
13327 return JIM_OK;
13328 }
13329 }
13330 return JIM_ERR;
13331 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13332
13333 static int JimParseExprOperator(struct JimParserCtx *pc)
13334 {
13335 int i;
13336 int bestIdx = -1, bestLen = 0;
13337
13338
13339 for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) {
13340 const char * const opname = Jim_ExprOperators[i].name;
13341 const int oplen = Jim_ExprOperators[i].namelen;
13342
13343 if (opname == NULL || opname[0] != pc->p[0]) {
@@ -13351,11 +13390,11 @@
13351 }
13352 if (bestIdx == -1) {
13353 return JIM_ERR;
13354 }
13355
13356
13357 if (bestIdx >= JIM_EXPROP_FUNC_FIRST) {
13358 const char *p = pc->p + bestLen;
13359 int len = pc->len - bestLen;
13360
13361 while (len && isspace(UCHAR(*p))) {
@@ -13385,13 +13424,19 @@
13385
13386 const char *jim_tt_name(int type)
13387 {
13388 static const char * const tt_names[JIM_TT_EXPR_OP] =
13389 { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT",
13390 "DBL", "$()" };
13391 if (type < JIM_TT_EXPR_OP) {
13392 return tt_names[type];
 
 
 
 
 
 
13393 }
13394 else {
13395 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type);
13396 static char buf[20];
13397
@@ -13416,13 +13461,13 @@
13416 };
13417
13418
13419 typedef struct ExprByteCode
13420 {
13421 ScriptToken *token;
13422 int len;
13423 int inUse;
13424 } ExprByteCode;
13425
13426 static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr)
13427 {
13428 int i;
@@ -13450,26 +13495,29 @@
13450 static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
13451 {
13452 JIM_NOTUSED(interp);
13453 JIM_NOTUSED(srcPtr);
13454
13455
13456 dupPtr->typePtr = NULL;
13457 }
13458
13459
13460 static int ExprCheckCorrectness(ExprByteCode * expr)
13461 {
13462 int i;
13463 int stacklen = 0;
13464 int ternary = 0;
 
 
13465
13466 for (i = 0; i < expr->len; i++) {
13467 ScriptToken *t = &expr->token[i];
13468 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
 
13469
13470 stacklen -= op->arity;
 
13471 if (stacklen < 0) {
13472 break;
13473 }
13474 if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) {
13475 ternary++;
@@ -13476,26 +13524,47 @@
13476 }
13477 else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) {
13478 ternary--;
13479 }
13480
13481
13482 stacklen++;
13483 }
13484 if (stacklen != 1 || ternary != 0) {
13485 return JIM_ERR;
13486 }
13487 return JIM_OK;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13488 }
13489
13490 static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t)
13491 {
13492 int i;
13493
13494 int leftindex, arity, offset;
13495
13496
13497 leftindex = expr->len - 1;
13498
13499 arity = 1;
13500 while (arity) {
13501 ScriptToken *tt = &expr->token[leftindex];
@@ -13508,11 +13577,11 @@
13508 return JIM_ERR;
13509 }
13510 }
13511 leftindex++;
13512
13513
13514 memmove(&expr->token[leftindex + 2], &expr->token[leftindex],
13515 sizeof(*expr->token) * (expr->len - leftindex));
13516 expr->len += 2;
13517 offset = (expr->len - leftindex) - 1;
13518
@@ -13520,16 +13589,16 @@
13520 expr->token[leftindex + 1].objPtr = interp->emptyObj;
13521
13522 expr->token[leftindex].type = JIM_TT_EXPR_INT;
13523 expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset);
13524
13525
13526 expr->token[expr->len].objPtr = interp->emptyObj;
13527 expr->token[expr->len].type = t->type + 2;
13528 expr->len++;
13529
13530
13531 for (i = leftindex - 1; i > 0; i--) {
13532 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type);
13533 if (op->lazy == LAZY_LEFT) {
13534 if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) {
13535 JimWideValue(expr->token[i - 1].objPtr) += 2;
@@ -13575,11 +13644,11 @@
13575 return right_index;
13576 }
13577 right_index--;
13578 }
13579
13580
13581 return -1;
13582 }
13583
13584 static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index)
13585 {
@@ -13617,11 +13686,11 @@
13617
13618 if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) {
13619 continue;
13620 }
13621
13622
13623 if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) {
13624 continue;
13625 }
13626
13627 tmp = expr->token[prev_right_index];
@@ -13630,25 +13699,25 @@
13630 }
13631 expr->token[i] = tmp;
13632
13633 JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index);
13634
13635
13636 i++;
13637 }
13638 }
13639
13640 static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj)
13641 {
13642 Jim_Stack stack;
13643 ExprByteCode *expr;
13644 int ok = 1;
13645 int i;
13646 int prevtt = JIM_TT_NONE;
13647 int have_ternary = 0;
13648
13649
13650 int count = tokenlist->count - 1;
13651
13652 expr = Jim_Alloc(sizeof(*expr));
13653 expr->inUse = 1;
13654 expr->len = 0;
@@ -13659,11 +13728,11 @@
13659 ParseToken *t = &tokenlist->list[i];
13660 const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type);
13661
13662 if (op->lazy == LAZY_OP) {
13663 count += 2;
13664
13665 if (t->type == JIM_EXPROP_TERNARY) {
13666 have_ternary = 1;
13667 }
13668 }
13669 }
@@ -13671,128 +13740,128 @@
13671 expr->token = Jim_Alloc(sizeof(ScriptToken) * count);
13672
13673 for (i = 0; i < tokenlist->count && ok; i++) {
13674 ParseToken *t = &tokenlist->list[i];
13675
13676
13677 struct ScriptToken *token = &expr->token[expr->len];
13678
13679 if (t->type == JIM_TT_EOL) {
13680 break;
13681 }
13682
13683 switch (t->type) {
13684 case JIM_TT_STR:
13685 case JIM_TT_ESC:
13686 case JIM_TT_VAR:
13687 case JIM_TT_DICTSUGAR:
13688 case JIM_TT_EXPRSUGAR:
13689 case JIM_TT_CMD:
13690 token->type = t->type;
13691 strexpr:
13692 token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13693 if (t->type == JIM_TT_CMD) {
13694
13695 JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13696 }
13697 expr->len++;
13698 break;
13699
13700 case JIM_TT_EXPR_INT:
13701 case JIM_TT_EXPR_DOUBLE:
13702 {
13703 char *endptr;
13704 if (t->type == JIM_TT_EXPR_INT) {
13705 token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13706 }
13707 else {
13708 token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13709 }
13710 if (endptr != t->token + t->len) {
13711
13712 Jim_FreeNewObj(interp, token->objPtr);
13713 token->type = JIM_TT_STR;
13714 goto strexpr;
13715 }
13716 token->type = t->type;
13717 expr->len++;
13718 }
13719 break;
13720
13721 case JIM_TT_SUBEXPR_START:
13722 Jim_StackPush(&stack, t);
13723 prevtt = JIM_TT_NONE;
13724 continue;
13725
13726 case JIM_TT_SUBEXPR_COMMA:
13727
13728 continue;
13729
13730 case JIM_TT_SUBEXPR_END:
13731 ok = 0;
13732 while (Jim_StackLen(&stack)) {
13733 ParseToken *tt = Jim_StackPop(&stack);
13734
13735 if (tt->type == JIM_TT_SUBEXPR_START) {
13736 ok = 1;
13737 break;
13738 }
13739
13740 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13741 goto err;
13742 }
13743 }
13744 if (!ok) {
13745 Jim_SetResultString(interp, "Unexpected close parenthesis", -1);
13746 goto err;
13747 }
13748 break;
13749
13750
13751 default:{
13752
13753 const struct Jim_ExprOperator *op;
13754 ParseToken *tt;
13755
13756
13757 if (prevtt == JIM_TT_NONE || 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
13775 if (op->arity != 1 && tt_op->precedence >= op->precedence) {
13776 if (ExprAddOperator(interp, expr, tt) != JIM_OK) {
13777 ok = 0;
13778 goto err;
13779 }
13780 Jim_StackPop(&stack);
13781 }
13782 else {
13783 break;
13784 }
13785 }
13786 Jim_StackPush(&stack, t);
13787 break;
13788 }
13789 }
13790 prevtt = t->type;
13791 }
13792
13793
13794 while (Jim_StackLen(&stack)) {
13795 ParseToken *tt = Jim_StackPop(&stack);
13796
13797 if (tt->type == JIM_TT_SUBEXPR_START) {
13798 ok = 0;
@@ -13808,11 +13877,11 @@
13808 if (have_ternary) {
13809 ExprTernaryReorderExpression(interp, expr);
13810 }
13811
13812 err:
13813
13814 Jim_FreeStack(&stack);
13815
13816 for (i = 0; i < expr->len; i++) {
13817 Jim_IncrRefCount(expr->token[i].objPtr);
13818 }
@@ -13835,11 +13904,11 @@
13835 ParseTokenList tokenlist;
13836 int line;
13837 Jim_Obj *fileNameObj;
13838 int rc = JIM_ERR;
13839
13840
13841 if (objPtr->typePtr == &sourceObjType) {
13842 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
13843 line = objPtr->internalRep.sourceValue.lineNumber;
13844 }
13845 else {
@@ -13848,18 +13917,17 @@
13848 }
13849 Jim_IncrRefCount(fileNameObj);
13850
13851 exprText = Jim_GetString(objPtr, &exprTextLen);
13852
13853
13854 ScriptTokenListInit(&tokenlist);
13855
13856 JimParserInit(&parser, exprText, exprTextLen, line);
13857 while (!parser.eof) {
13858 if (JimParseExpression(&parser) != JIM_OK) {
13859 ScriptTokenListFree(&tokenlist);
13860 invalidexpr:
13861 Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr);
13862 expr = NULL;
13863 goto err;
13864 }
13865
@@ -13882,14 +13950,14 @@
13882 ScriptTokenListFree(&tokenlist);
13883 Jim_DecrRefCount(interp, fileNameObj);
13884 return JIM_ERR;
13885 }
13886
13887
13888 expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj);
13889
13890
 
 
13891 ScriptTokenListFree(&tokenlist);
13892
13893 if (!expr) {
13894 goto err;
13895 }
@@ -13905,20 +13973,22 @@
13905 printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
13906 }
13907 }
13908 #endif
13909
13910
13911 if (ExprCheckCorrectness(expr) != JIM_OK) {
 
13912 ExprFreeByteCode(interp, expr);
13913 goto invalidexpr;
 
13914 }
13915
13916 rc = JIM_OK;
13917
13918 err:
13919
13920 Jim_DecrRefCount(interp, fileNameObj);
13921 Jim_FreeIntRep(interp, objPtr);
13922 Jim_SetIntRepPtr(objPtr, expr);
13923 objPtr->typePtr = &exprObjType;
13924 return rc;
@@ -13958,11 +14028,11 @@
13958 int retcode = JIM_OK;
13959 struct JimExprState e;
13960
13961 expr = JimGetExpression(interp, exprObjPtr);
13962 if (!expr) {
13963 return JIM_ERR;
13964 }
13965
13966 #ifdef JIM_OPTIMIZATION
13967 {
13968 Jim_Obj *objPtr;
@@ -14031,26 +14101,27 @@
14031 noopt:
14032 #endif
14033
14034 expr->inUse++;
14035
14036
14037
14038 if (expr->len > JIM_EE_STATICSTACK_LEN)
14039 e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len);
14040 else
14041 e.stack = staticStack;
14042
14043 e.stacklen = 0;
14044
14045
14046 for (i = 0; i < expr->len && retcode == JIM_OK; i++) {
14047 Jim_Obj *objPtr;
14048
14049 switch (expr->token[i].type) {
14050 case JIM_TT_EXPR_INT:
14051 case JIM_TT_EXPR_DOUBLE:
 
14052 case JIM_TT_STR:
14053 ExprPush(&e, expr->token[i].objPtr);
14054 break;
14055
14056 case JIM_TT_VAR:
@@ -14086,16 +14157,16 @@
14086 ExprPush(&e, Jim_GetResult(interp));
14087 }
14088 break;
14089
14090 default:{
14091
14092 e.skip = 0;
14093 e.opcode = expr->token[i].type;
14094
14095 retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e);
14096
14097 i += e.skip;
14098 continue;
14099 }
14100 }
14101 }
@@ -14119,20 +14190,27 @@
14119 int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr)
14120 {
14121 int retcode;
14122 jim_wide wideValue;
14123 double doubleValue;
 
14124 Jim_Obj *exprResultPtr;
14125
14126 retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr);
14127 if (retcode != JIM_OK)
14128 return retcode;
14129
14130 if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) {
14131 if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) {
14132 Jim_DecrRefCount(interp, exprResultPtr);
14133 return JIM_ERR;
 
 
 
 
 
 
14134 }
14135 else {
14136 Jim_DecrRefCount(interp, exprResultPtr);
14137 *boolPtr = doubleValue != 0;
14138 return JIM_OK;
@@ -14147,29 +14225,29 @@
14147
14148
14149
14150 typedef struct ScanFmtPartDescr
14151 {
14152 char *arg;
14153 char *prefix;
14154 size_t width;
14155 int pos;
14156 char type;
14157 char modifier;
14158 } ScanFmtPartDescr;
14159
14160
14161 typedef struct ScanFmtStringObj
14162 {
14163 jim_wide size;
14164 char *stringRep;
14165 size_t count;
14166 size_t convCount;
14167 size_t maxPos;
14168 const char *error;
14169 char *scratch;
14170 ScanFmtPartDescr descr[1];
14171 } ScanFmtStringObj;
14172
14173
14174 static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
14175 static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
@@ -14216,22 +14294,22 @@
14216 int maxFmtLen = objPtr->length;
14217 const char *fmtEnd = fmt + maxFmtLen;
14218 int curr;
14219
14220 Jim_FreeIntRep(interp, objPtr);
14221
14222 for (i = 0, maxCount = 0; i < maxFmtLen; ++i)
14223 if (fmt[i] == '%')
14224 ++maxCount;
14225
14226 approxSize = sizeof(ScanFmtStringObj)
14227 +(maxCount + 1) * sizeof(ScanFmtPartDescr)
14228 +maxFmtLen * sizeof(char) + 3 + 1
14229 + maxFmtLen * sizeof(char) + 1
14230 + maxFmtLen * sizeof(char)
14231 +(maxCount + 1) * sizeof(char)
14232 +1;
14233 fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize);
14234 memset(fmtObj, 0, approxSize);
14235 fmtObj->size = approxSize;
14236 fmtObj->maxPos = 0;
14237 fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1];
@@ -14243,12 +14321,12 @@
14243 for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) {
14244 int width = 0, skip;
14245 ScanFmtPartDescr *descr = &fmtObj->descr[curr];
14246
14247 fmtObj->count++;
14248 descr->width = 0;
14249
14250 if (*fmt != '%' || fmt[1] == '%') {
14251 descr->type = 0;
14252 descr->prefix = &buffer[i];
14253 for (; fmt < fmtEnd; ++fmt) {
14254 if (*fmt == '%') {
@@ -14258,65 +14336,65 @@
14258 }
14259 buffer[i++] = *fmt;
14260 }
14261 buffer[i++] = 0;
14262 }
14263
14264 ++fmt;
14265
14266 if (fmt >= fmtEnd)
14267 goto done;
14268 descr->pos = 0;
14269 if (*fmt == '*') {
14270 descr->pos = -1;
14271 ++fmt;
14272 }
14273 else
14274 fmtObj->convCount++;
14275
14276 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14277 fmt += skip;
14278
14279 if (descr->pos != -1 && *fmt == '$') {
14280 int prev;
14281
14282 ++fmt;
14283 descr->pos = width;
14284 width = 0;
14285
14286 if ((lastPos == 0 && descr->pos > 0)
14287 || (lastPos > 0 && descr->pos == 0)) {
14288 fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers";
14289 return JIM_ERR;
14290 }
14291
14292 for (prev = 0; prev < curr; ++prev) {
14293 if (fmtObj->descr[prev].pos == -1)
14294 continue;
14295 if (fmtObj->descr[prev].pos == descr->pos) {
14296 fmtObj->error =
14297 "variable is assigned by multiple \"%n$\" conversion specifiers";
14298 return JIM_ERR;
14299 }
14300 }
14301
14302 if (sscanf(fmt, "%d%n", &width, &skip) == 1) {
14303 descr->width = width;
14304 fmt += skip;
14305 }
14306 if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos)
14307 fmtObj->maxPos = descr->pos;
14308 }
14309 else {
14310
14311 descr->width = width;
14312 }
14313 }
14314
14315 if (lastPos == -1)
14316 lastPos = descr->pos;
14317
14318 if (*fmt == '[') {
14319 int swapped = 1, beg = i, end, j;
14320
14321 descr->type = '[';
14322 descr->arg = &buffer[i];
@@ -14331,11 +14409,11 @@
14331 fmtObj->error = "unmatched [ in format string";
14332 return JIM_ERR;
14333 }
14334 end = i;
14335 buffer[i++] = 0;
14336
14337 while (swapped) {
14338 swapped = 0;
14339 for (j = beg + 1; j < end - 1; ++j) {
14340 if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) {
14341 char tmp = buffer[j - 1];
@@ -14346,11 +14424,11 @@
14346 }
14347 }
14348 }
14349 }
14350 else {
14351
14352 if (strchr("hlL", *fmt) != 0)
14353 descr->modifier = tolower((int)*fmt++);
14354
14355 descr->type = *fmt;
14356 if (strchr("efgcsndoxui", *fmt) == 0) {
@@ -14389,11 +14467,11 @@
14389 while (*str) {
14390 int c;
14391 int n;
14392
14393 if (!sdescr && isspace(UCHAR(*str)))
14394 break;
14395
14396 n = utf8_tounicode(str, &c);
14397 if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN))
14398 break;
14399 while (n--)
@@ -14412,89 +14490,89 @@
14412 size_t scanned = 0;
14413 size_t anchor = pos;
14414 int i;
14415 Jim_Obj *tmpObj = NULL;
14416
14417
14418 *valObjPtr = 0;
14419 if (descr->prefix) {
14420 for (i = 0; pos < strLen && descr->prefix[i]; ++i) {
14421
14422 if (isspace(UCHAR(descr->prefix[i])))
14423 while (pos < strLen && isspace(UCHAR(str[pos])))
14424 ++pos;
14425 else if (descr->prefix[i] != str[pos])
14426 break;
14427 else
14428 ++pos;
14429 }
14430 if (pos >= strLen) {
14431 return -1;
14432 }
14433 else if (descr->prefix[i] != 0)
14434 return 0;
14435 }
14436
14437 if (descr->type != 'c' && descr->type != '[' && descr->type != 'n')
14438 while (isspace(UCHAR(str[pos])))
14439 ++pos;
14440
14441 scanned = pos - anchor;
14442
14443
14444 if (descr->type == 'n') {
14445
14446 *valObjPtr = Jim_NewIntObj(interp, anchor + scanned);
14447 }
14448 else if (pos >= strLen) {
14449
14450 return -1;
14451 }
14452 else if (descr->type == 'c') {
14453 int c;
14454 scanned += utf8_tounicode(&str[pos], &c);
14455 *valObjPtr = Jim_NewIntObj(interp, c);
14456 return scanned;
14457 }
14458 else {
14459
14460 if (descr->width > 0) {
14461 size_t sLen = utf8_strlen(&str[pos], strLen - pos);
14462 size_t tLen = descr->width > sLen ? sLen : descr->width;
14463
14464 tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen);
14465 tok = tmpObj->bytes;
14466 }
14467 else {
14468
14469 tok = &str[pos];
14470 }
14471 switch (descr->type) {
14472 case 'd':
14473 case 'o':
14474 case 'x':
14475 case 'u':
14476 case 'i':{
14477 char *endp;
14478 jim_wide w;
14479
14480 int base = descr->type == 'o' ? 8
14481 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
14482
14483
14484 if (base == 0) {
14485 w = jim_strtoull(tok, &endp);
14486 }
14487 else {
14488 w = strtoull(tok, &endp, base);
14489 }
14490
14491 if (endp != tok) {
14492
14493 *valObjPtr = Jim_NewIntObj(interp, w);
14494
14495
14496 scanned += endp - tok;
14497 }
14498 else {
14499 scanned = *tok ? 0 : -1;
14500 }
@@ -14511,13 +14589,13 @@
14511 case 'g':{
14512 char *endp;
14513 double value = strtod(tok, &endp);
14514
14515 if (endp != tok) {
14516
14517 *valObjPtr = Jim_NewDoubleObj(interp, value);
14518
14519 scanned += endp - tok;
14520 }
14521 else {
14522 scanned = *tok ? 0 : -1;
14523 }
@@ -14542,65 +14620,65 @@
14542 Jim_Obj **resultVec = 0;
14543 int resultc;
14544 Jim_Obj *emptyStr = 0;
14545 ScanFmtStringObj *fmtObj;
14546
14547
14548 JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format"));
14549
14550 fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr;
14551
14552 if (fmtObj->error != 0) {
14553 if (flags & JIM_ERRMSG)
14554 Jim_SetResultString(interp, fmtObj->error, -1);
14555 return 0;
14556 }
14557
14558 emptyStr = Jim_NewEmptyStringObj(interp);
14559 Jim_IncrRefCount(emptyStr);
14560
14561 resultList = Jim_NewListObj(interp, NULL, 0);
14562 if (fmtObj->maxPos > 0) {
14563 for (i = 0; i < fmtObj->maxPos; ++i)
14564 Jim_ListAppendElement(interp, resultList, emptyStr);
14565 JimListGetElements(interp, resultList, &resultc, &resultVec);
14566 }
14567
14568 for (i = 0, pos = 0; i < fmtObj->count; ++i) {
14569 ScanFmtPartDescr *descr = &(fmtObj->descr[i]);
14570 Jim_Obj *value = 0;
14571
14572
14573 if (descr->type == 0)
14574 continue;
14575
14576 if (scanned > 0)
14577 scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value);
14578
14579 if (scanned == -1 && i == 0)
14580 goto eof;
14581
14582 pos += scanned;
14583
14584
14585 if (value == 0)
14586 value = Jim_NewEmptyStringObj(interp);
14587
14588 if (descr->pos == -1) {
14589 Jim_FreeNewObj(interp, value);
14590 }
14591 else if (descr->pos == 0)
14592
14593 Jim_ListAppendElement(interp, resultList, value);
14594 else if (resultVec[descr->pos - 1] == emptyStr) {
14595
14596 Jim_DecrRefCount(interp, resultVec[descr->pos - 1]);
14597 Jim_IncrRefCount(value);
14598 resultVec[descr->pos - 1] = value;
14599 }
14600 else {
14601
14602 Jim_FreeNewObj(interp, value);
14603 goto err;
14604 }
14605 }
14606 Jim_DecrRefCount(interp, emptyStr);
@@ -14638,15 +14716,15 @@
14638 {
14639 Jim_PrngState *prng;
14640 unsigned char *destByte = (unsigned char *)dest;
14641 unsigned int si, sj, x;
14642
14643
14644 if (interp->prngState == NULL)
14645 JimPrngInit(interp);
14646 prng = interp->prngState;
14647
14648 for (x = 0; x < len; x++) {
14649 prng->i = (prng->i + 1) & 0xff;
14650 si = prng->sbox[prng->i];
14651 prng->j = (prng->j + si) & 0xff;
14652 sj = prng->sbox[prng->j];
@@ -14660,19 +14738,19 @@
14660 static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen)
14661 {
14662 int i;
14663 Jim_PrngState *prng;
14664
14665
14666 if (interp->prngState == NULL)
14667 JimPrngInit(interp);
14668 prng = interp->prngState;
14669
14670
14671 for (i = 0; i < 256; i++)
14672 prng->sbox[i] = i;
14673
14674 for (i = 0; i < seedLen; i++) {
14675 unsigned char t;
14676
14677 t = prng->sbox[i & 0xFF];
14678 prng->sbox[i & 0xFF] = prng->sbox[seed[i]];
@@ -14699,11 +14777,11 @@
14699 if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK)
14700 return JIM_ERR;
14701 }
14702 intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
14703 if (!intObjPtr) {
14704
14705 wideValue = 0;
14706 }
14707 else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) {
14708 return JIM_ERR;
14709 }
@@ -14713,26 +14791,26 @@
14713 Jim_FreeNewObj(interp, intObjPtr);
14714 return JIM_ERR;
14715 }
14716 }
14717 else {
14718
14719 Jim_InvalidateStringRep(intObjPtr);
14720 JimWideValue(intObjPtr) = wideValue + increment;
14721
14722 if (argv[1]->typePtr != &variableObjType) {
14723
14724 Jim_SetVariable(interp, argv[1], intObjPtr);
14725 }
14726 }
14727 Jim_SetResult(interp, intObjPtr);
14728 return JIM_OK;
14729 }
14730
14731
14732 #define JIM_EVAL_SARGV_LEN 8
14733 #define JIM_EVAL_SINTV_LEN 8
14734
14735
14736 static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
14737 {
14738 int retcode;
@@ -14740,16 +14818,16 @@
14740 if (interp->unknown_called > 50) {
14741 return JIM_ERR;
14742 }
14743
14744
14745
14746 if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
14747 return JIM_ERR;
14748
14749 interp->unknown_called++;
14750
14751 retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
14752 interp->unknown_called--;
14753
14754 return retcode;
14755 }
@@ -14767,11 +14845,11 @@
14767 }
14768 printf("\n");
14769 #endif
14770
14771 if (interp->framePtr->tailcallCmd) {
14772
14773 cmdPtr = interp->framePtr->tailcallCmd;
14774 interp->framePtr->tailcallCmd = NULL;
14775 }
14776 else {
14777 cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
@@ -14786,11 +14864,11 @@
14786 retcode = JIM_ERR;
14787 goto out;
14788 }
14789 interp->evalDepth++;
14790
14791
14792 Jim_SetEmptyResult(interp);
14793 if (cmdPtr->isproc) {
14794 retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
14795 }
14796 else {
@@ -14807,17 +14885,17 @@
14807
14808 int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
14809 {
14810 int i, retcode;
14811
14812
14813 for (i = 0; i < objc; i++)
14814 Jim_IncrRefCount(objv[i]);
14815
14816 retcode = JimInvokeCommand(interp, objc, objv);
14817
14818
14819 for (i = 0; i < objc; i++)
14820 Jim_DecrRefCount(interp, objv[i]);
14821
14822 return retcode;
14823 }
@@ -14835,25 +14913,25 @@
14835 }
14836
14837 static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script)
14838 {
14839 if (!interp->errorFlag) {
14840
14841 interp->errorFlag = 1;
14842 Jim_IncrRefCount(script->fileNameObj);
14843 Jim_DecrRefCount(interp, interp->errorFileNameObj);
14844 interp->errorFileNameObj = script->fileNameObj;
14845 interp->errorLine = script->linenr;
14846
14847 JimResetStackTrace(interp);
14848
14849 interp->addStackTrace++;
14850 }
14851
14852
14853 if (interp->addStackTrace > 0) {
14854
14855
14856 JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
14857
14858 if (Jim_Length(script->fileNameObj)) {
14859 interp->addStackTrace = 0;
@@ -14888,14 +14966,14 @@
14888 case JIM_OK:
14889 case JIM_RETURN:
14890 objPtr = interp->result;
14891 break;
14892 case JIM_BREAK:
14893
14894 return JIM_BREAK;
14895 case JIM_CONTINUE:
14896
14897 return JIM_CONTINUE;
14898 default:
14899 return JIM_ERR;
14900 }
14901 break;
@@ -14930,23 +15008,23 @@
14930 case JIM_OK:
14931 case JIM_RETURN:
14932 break;
14933 case JIM_BREAK:
14934 if (flags & JIM_SUBST_FLAG) {
14935
14936 tokens = i;
14937 continue;
14938 }
14939
14940
14941 case JIM_CONTINUE:
14942 if (flags & JIM_SUBST_FLAG) {
14943 intv[i] = NULL;
14944 continue;
14945 }
14946
14947
14948 default:
14949 while (i--) {
14950 Jim_DecrRefCount(interp, intv[i]);
14951 }
14952 if (intv != sintv) {
@@ -14957,28 +15035,28 @@
14957 Jim_IncrRefCount(intv[i]);
14958 Jim_String(intv[i]);
14959 totlen += intv[i]->length;
14960 }
14961
14962
14963 if (tokens == 1 && intv[0] && intv == sintv) {
14964 Jim_DecrRefCount(interp, intv[0]);
14965 return intv[0];
14966 }
14967
14968 objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0);
14969
14970 if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC
14971 && token[2].type == JIM_TT_VAR) {
14972
14973 objPtr->typePtr = &interpolatedObjType;
14974 objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
14975 objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
14976 Jim_IncrRefCount(intv[2]);
14977 }
14978 else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) {
14979
14980 JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber);
14981 }
14982
14983
14984 s = objPtr->bytes = Jim_Alloc(totlen + 1);
@@ -14989,11 +15067,11 @@
14989 s += intv[i]->length;
14990 Jim_DecrRefCount(interp, intv[i]);
14991 }
14992 }
14993 objPtr->bytes[totlen] = '\0';
14994
14995 if (intv != sintv) {
14996 Jim_Free(intv);
14997 }
14998
14999 return objPtr;
@@ -15033,11 +15111,11 @@
15033
15034 if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
15035 return JimEvalObjList(interp, scriptObjPtr);
15036 }
15037
15038 Jim_IncrRefCount(scriptObjPtr);
15039 script = JimGetScript(interp, scriptObjPtr);
15040 if (!JimScriptValid(interp, script)) {
15041 Jim_DecrRefCount(interp, scriptObjPtr);
15042 return JIM_ERR;
15043 }
@@ -15069,11 +15147,11 @@
15069 }
15070 #endif
15071
15072 script->inUse++;
15073
15074
15075 prevScriptObj = interp->currentScriptObj;
15076 interp->currentScriptObj = scriptObjPtr;
15077
15078 interp->errorFlag = 0;
15079 argv = sargv;
@@ -15080,19 +15158,19 @@
15080
15081 for (i = 0; i < script->len && retcode == JIM_OK; ) {
15082 int argc;
15083 int j;
15084
15085
15086 argc = token[i].objPtr->internalRep.scriptLineValue.argc;
15087 script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
15088
15089
15090 if (argc > JIM_EVAL_SARGV_LEN)
15091 argv = Jim_Alloc(sizeof(Jim_Obj *) * argc);
15092
15093
15094 i++;
15095
15096 for (j = 0; j < argc; j++) {
15097 long wordtokens = 1;
15098 int expand = 0;
@@ -15148,11 +15226,11 @@
15148
15149 if (!expand) {
15150 argv[j] = wordObjPtr;
15151 }
15152 else {
15153
15154 int len = Jim_ListLength(interp, wordObjPtr);
15155 int newargc = argc + len - 1;
15156 int k;
15157
15158 if (len > 1) {
@@ -15161,39 +15239,39 @@
15161 argv = Jim_Alloc(sizeof(*argv) * newargc);
15162 memcpy(argv, sargv, sizeof(*argv) * j);
15163 }
15164 }
15165 else {
15166
15167 argv = Jim_Realloc(argv, sizeof(*argv) * newargc);
15168 }
15169 }
15170
15171
15172 for (k = 0; k < len; k++) {
15173 argv[j++] = wordObjPtr->internalRep.listValue.ele[k];
15174 Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]);
15175 }
15176
15177 Jim_DecrRefCount(interp, wordObjPtr);
15178
15179
15180 j--;
15181 argc += len - 1;
15182 }
15183 }
15184
15185 if (retcode == JIM_OK && argc) {
15186
15187 retcode = JimInvokeCommand(interp, argc, argv);
15188
15189 if (Jim_CheckSignal(interp)) {
15190 retcode = JIM_SIGNAL;
15191 }
15192 }
15193
15194
15195 while (j-- > 0) {
15196 Jim_DecrRefCount(interp, argv[j]);
15197 }
15198
15199 if (argv != sargv) {
@@ -15200,21 +15278,21 @@
15200 Jim_Free(argv);
15201 argv = sargv;
15202 }
15203 }
15204
15205
15206 if (retcode == JIM_ERR) {
15207 JimAddErrorToStack(interp, script);
15208 }
15209
15210 else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) {
15211
15212 interp->addStackTrace = 0;
15213 }
15214
15215
15216 interp->currentScriptObj = prevScriptObj;
15217
15218 Jim_FreeIntRep(interp, scriptObjPtr);
15219 scriptObjPtr->typePtr = &scriptObjType;
15220 Jim_SetIntRepPtr(scriptObjPtr, script);
@@ -15224,14 +15302,14 @@
15224 }
15225
15226 static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj)
15227 {
15228 int retcode;
15229
15230 const char *varname = Jim_String(argNameObj);
15231 if (*varname == '&') {
15232
15233 Jim_Obj *objPtr;
15234 Jim_CallFrame *savedCallFrame = interp->framePtr;
15235
15236 interp->framePtr = interp->framePtr->parent;
15237 objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
@@ -15238,11 +15316,11 @@
15238 interp->framePtr = savedCallFrame;
15239 if (!objPtr) {
15240 return JIM_ERR;
15241 }
15242
15243
15244 objPtr = Jim_NewStringObj(interp, varname + 1, -1);
15245 Jim_IncrRefCount(objPtr);
15246 retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
15247 Jim_DecrRefCount(interp, objPtr);
15248 }
@@ -15252,26 +15330,26 @@
15252 return retcode;
15253 }
15254
15255 static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd)
15256 {
15257
15258 Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
15259 int i;
15260
15261 for (i = 0; i < cmd->u.proc.argListLen; i++) {
15262 Jim_AppendString(interp, argmsg, " ", 1);
15263
15264 if (i == cmd->u.proc.argsPos) {
15265 if (cmd->u.proc.arglist[i].defaultObjPtr) {
15266
15267 Jim_AppendString(interp, argmsg, "?", 1);
15268 Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr);
15269 Jim_AppendString(interp, argmsg, " ...?", -1);
15270 }
15271 else {
15272
15273 Jim_AppendString(interp, argmsg, "?arg...?", -1);
15274 }
15275 }
15276 else {
15277 if (cmd->u.proc.arglist[i].defaultObjPtr) {
@@ -15296,11 +15374,11 @@
15296 int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
15297 {
15298 Jim_CallFrame *callFramePtr;
15299 int retcode;
15300
15301
15302 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
15303 callFramePtr->argv = &interp->emptyObj;
15304 callFramePtr->argc = 0;
15305 callFramePtr->procArgsObjPtr = NULL;
15306 callFramePtr->procBodyObjPtr = scriptObj;
@@ -15308,21 +15386,21 @@
15308 callFramePtr->fileNameObj = interp->emptyObj;
15309 callFramePtr->line = 0;
15310 Jim_IncrRefCount(scriptObj);
15311 interp->framePtr = callFramePtr;
15312
15313
15314 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15315 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15316 retcode = JIM_ERR;
15317 }
15318 else {
15319
15320 retcode = Jim_EvalObj(interp, scriptObj);
15321 }
15322
15323
15324 interp->framePtr = interp->framePtr->parent;
15325 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
15326
15327 return retcode;
15328 }
@@ -15332,62 +15410,62 @@
15332 {
15333 Jim_CallFrame *callFramePtr;
15334 int i, d, retcode, optargs;
15335 ScriptObj *script;
15336
15337
15338 if (argc - 1 < cmd->u.proc.reqArity ||
15339 (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
15340 JimSetProcWrongArgs(interp, argv[0], cmd);
15341 return JIM_ERR;
15342 }
15343
15344 if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15345
15346 return JIM_OK;
15347 }
15348
15349
15350 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15351 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15352 return JIM_ERR;
15353 }
15354
15355
15356 callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
15357 callFramePtr->argv = argv;
15358 callFramePtr->argc = argc;
15359 callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
15360 callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
15361 callFramePtr->staticVars = cmd->u.proc.staticVars;
15362
15363
15364 script = JimGetScript(interp, interp->currentScriptObj);
15365 callFramePtr->fileNameObj = script->fileNameObj;
15366 callFramePtr->line = script->linenr;
15367
15368 Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
15369 Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
15370 interp->framePtr = callFramePtr;
15371
15372
15373 optargs = (argc - 1 - cmd->u.proc.reqArity);
15374
15375
15376 i = 1;
15377 for (d = 0; d < cmd->u.proc.argListLen; d++) {
15378 Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr;
15379 if (d == cmd->u.proc.argsPos) {
15380
15381 Jim_Obj *listObjPtr;
15382 int argsLen = 0;
15383 if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) {
15384 argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity);
15385 }
15386 listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen);
15387
15388
15389 if (cmd->u.proc.arglist[d].defaultObjPtr) {
15390 nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr;
15391 }
15392 retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr);
15393 if (retcode != JIM_OK) {
@@ -15396,60 +15474,56 @@
15396
15397 i += argsLen;
15398 continue;
15399 }
15400
15401
15402 if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) {
15403 retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]);
15404 }
15405 else {
15406
15407 retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr);
15408 }
15409 if (retcode != JIM_OK) {
15410 goto badargset;
15411 }
15412 }
15413
15414
15415 retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr);
15416
15417 badargset:
15418
15419
15420 interp->framePtr = interp->framePtr->parent;
15421 JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE);
 
15422
15423 if (interp->framePtr->tailcallObj) {
15424
15425 if (interp->framePtr->tailcall++ == 0) {
15426
15427 do {
15428 Jim_Obj *tailcallObj = interp->framePtr->tailcallObj;
15429
15430 interp->framePtr->tailcallObj = NULL;
15431
15432 if (retcode == JIM_EVAL) {
15433 retcode = Jim_EvalObjList(interp, tailcallObj);
15434 if (retcode == JIM_RETURN) {
15435 interp->returnLevel++;
15436 }
15437 }
15438 Jim_DecrRefCount(interp, tailcallObj);
15439 } while (interp->framePtr->tailcallObj);
15440
15441
15442 if (interp->framePtr->tailcallCmd) {
15443 JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd);
15444 interp->framePtr->tailcallCmd = NULL;
15445 }
15446 }
15447 interp->framePtr->tailcall--;
15448 }
15449
15450
15451 if (retcode == JIM_RETURN) {
15452 if (--interp->returnLevel <= 0) {
15453 retcode = interp->returnCode;
15454 interp->returnCode = JIM_OK;
15455 interp->returnLevel = 0;
@@ -15561,20 +15635,20 @@
15561 prevScriptObj = interp->currentScriptObj;
15562 interp->currentScriptObj = scriptObjPtr;
15563
15564 retcode = Jim_EvalObj(interp, scriptObjPtr);
15565
15566
15567 if (retcode == JIM_RETURN) {
15568 if (--interp->returnLevel <= 0) {
15569 retcode = interp->returnCode;
15570 interp->returnCode = JIM_OK;
15571 interp->returnLevel = 0;
15572 }
15573 }
15574 if (retcode == JIM_ERR) {
15575
15576 interp->addStackTrace++;
15577 }
15578
15579 interp->currentScriptObj = prevScriptObj;
15580
@@ -15600,11 +15674,11 @@
15600 }
15601 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15602 if (JimParseVar(pc) == JIM_OK) {
15603 return;
15604 }
15605
15606 pc->tstart = pc->p;
15607 flags |= JIM_SUBST_NOVAR;
15608 }
15609 while (pc->len) {
15610 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
@@ -15631,32 +15705,32 @@
15631 const char *scriptText = Jim_GetString(objPtr, &scriptTextLen);
15632 struct JimParserCtx parser;
15633 struct ScriptObj *script = Jim_Alloc(sizeof(*script));
15634 ParseTokenList tokenlist;
15635
15636
15637 ScriptTokenListInit(&tokenlist);
15638
15639 JimParserInit(&parser, scriptText, scriptTextLen, 1);
15640 while (1) {
15641 JimParseSubst(&parser, flags);
15642 if (parser.eof) {
15643
15644 break;
15645 }
15646 ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt,
15647 parser.tline);
15648 }
15649
15650
15651 script->inUse = 1;
15652 script->substFlags = flags;
15653 script->fileNameObj = interp->emptyObj;
15654 Jim_IncrRefCount(script->fileNameObj);
15655 SubstObjAddTokens(interp, script, &tokenlist);
15656
15657
15658 ScriptTokenListFree(&tokenlist);
15659
15660 #ifdef DEBUG_SHOW_SUBST
15661 {
15662 int i;
@@ -15667,11 +15741,11 @@
15667 Jim_String(script->token[i].objPtr));
15668 }
15669 }
15670 #endif
15671
15672
15673 Jim_FreeIntRep(interp, objPtr);
15674 Jim_SetIntRepPtr(objPtr, script);
15675 objPtr->typePtr = &scriptObjType;
15676 return JIM_OK;
15677 }
@@ -15685,11 +15759,11 @@
15685
15686 int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags)
15687 {
15688 ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags);
15689
15690 Jim_IncrRefCount(substObjPtr);
15691 script->inUse++;
15692
15693 *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags);
15694
15695 script->inUse--;
@@ -15701,11 +15775,15 @@
15701 }
15702
15703 void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
15704 {
15705 Jim_Obj *objPtr;
15706 Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
 
 
 
 
15707
15708 if (*msg) {
15709 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
15710 }
15711 Jim_IncrRefCount(listObjPtr);
@@ -15726,11 +15804,11 @@
15726 JimHashtableIteratorCallbackType *callback, int type)
15727 {
15728 Jim_HashEntry *he;
15729 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
15730
15731
15732 if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
15733 he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
15734 if (he) {
15735 callback(interp, listObjPtr, he, type);
15736 }
@@ -15757,11 +15835,11 @@
15757 {
15758 Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he);
15759 Jim_Obj *objPtr;
15760
15761 if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
15762
15763 return;
15764 }
15765
15766 objPtr = Jim_NewStringObj(interp, he->key, -1);
15767 Jim_IncrRefCount(objPtr);
@@ -15817,11 +15895,11 @@
15817
15818 targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr);
15819 if (targetCallFrame == NULL) {
15820 return JIM_ERR;
15821 }
15822
15823 if (targetCallFrame == interp->topFramePtr) {
15824 Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr);
15825 return JIM_ERR;
15826 }
15827 if (info_level_cmd) {
@@ -16004,11 +16082,11 @@
16004 if (!objPtr)
16005 return JIM_ERR;
16006 Jim_SetResult(interp, objPtr);
16007 return JIM_OK;
16008 }
16009
16010 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
16011 return JIM_ERR;
16012 Jim_SetResult(interp, argv[2]);
16013 return JIM_OK;
16014 }
@@ -16047,11 +16125,11 @@
16047 if (argc != 3) {
16048 Jim_WrongNumArgs(interp, 1, argv, "condition body");
16049 return JIM_ERR;
16050 }
16051
16052
16053 while (1) {
16054 int boolean, retval;
16055
16056 if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK)
16057 return retval;
@@ -16087,11 +16165,11 @@
16087 if (argc != 5) {
16088 Jim_WrongNumArgs(interp, 1, argv, "start test next body");
16089 return JIM_ERR;
16090 }
16091
16092
16093 if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) {
16094 return retval;
16095 }
16096
16097 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
@@ -16103,19 +16181,19 @@
16103 ExprByteCode *expr;
16104 jim_wide stop, currentVal;
16105 Jim_Obj *objPtr;
16106 int cmpOffset;
16107
16108
16109 expr = JimGetExpression(interp, argv[2]);
16110 incrScript = JimGetScript(interp, argv[3]);
16111
16112
16113 if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) {
16114 goto evalstart;
16115 }
16116
16117 if (incrScript->token[1].type != JIM_TT_ESC ||
16118 expr->token[0].type != JIM_TT_VAR ||
16119 (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) {
16120 goto evalstart;
16121 }
@@ -16128,48 +16206,48 @@
16128 }
16129 else {
16130 goto evalstart;
16131 }
16132
16133
16134 if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) {
16135 goto evalstart;
16136 }
16137
16138
16139 if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) {
16140 goto evalstart;
16141 }
16142
16143
16144 if (expr->token[1].type == JIM_TT_EXPR_INT) {
16145 if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) {
16146 goto evalstart;
16147 }
16148 }
16149 else {
16150 stopVarNamePtr = expr->token[1].objPtr;
16151 Jim_IncrRefCount(stopVarNamePtr);
16152
16153 stop = 0;
16154 }
16155
16156
16157 varNamePtr = expr->token[0].objPtr;
16158 Jim_IncrRefCount(varNamePtr);
16159
16160 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE);
16161 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &currentVal) != JIM_OK) {
16162 goto testcond;
16163 }
16164
16165
16166 while (retval == JIM_OK) {
16167
16168
16169
16170
 
 
16171 if (stopVarNamePtr) {
16172 objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE);
16173 if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) {
16174 goto testcond;
16175 }
@@ -16177,18 +16255,18 @@
16177
16178 if (currentVal >= stop + cmpOffset) {
16179 break;
16180 }
16181
16182
16183 retval = Jim_EvalObj(interp, argv[4]);
16184 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16185 retval = JIM_OK;
16186
16187 objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
16188
16189
16190 if (objPtr == NULL) {
16191 retval = JIM_ERR;
16192 goto out;
16193 }
16194 if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
@@ -16208,25 +16286,25 @@
16208 }
16209 evalstart:
16210 #endif
16211
16212 while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) {
16213
16214 retval = Jim_EvalObj(interp, argv[4]);
16215
16216 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16217
16218 evalnext:
16219 retval = Jim_EvalObj(interp, argv[3]);
16220 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16221
16222 testcond:
16223 retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean);
16224 }
16225 }
16226 }
16227 out:
16228 if (stopVarNamePtr) {
16229 Jim_DecrRefCount(interp, stopVarNamePtr);
16230 }
16231 if (varNamePtr) {
16232 Jim_DecrRefCount(interp, varNamePtr);
@@ -16268,11 +16346,11 @@
16268 if (retval == JIM_OK || retval == JIM_CONTINUE) {
16269 Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
16270
16271 retval = JIM_OK;
16272
16273
16274 i += incr;
16275
16276 if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
16277 if (argv[1]->typePtr != &variableObjType) {
16278 if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) {
@@ -16333,21 +16411,21 @@
16333
16334 static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
16335 {
16336 int result = JIM_OK;
16337 int i, numargs;
16338 Jim_ListIter twoiters[2];
16339 Jim_ListIter *iters;
16340 Jim_Obj *script;
16341 Jim_Obj *resultObj;
16342
16343 if (argc < 4 || argc % 2 != 0) {
16344 Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
16345 return JIM_ERR;
16346 }
16347 script = argv[argc - 1];
16348 numargs = (argc - 1 - 1);
16349
16350 if (numargs == 2) {
16351 iters = twoiters;
16352 }
16353 else {
@@ -16371,34 +16449,34 @@
16371 resultObj = interp->emptyObj;
16372 }
16373 Jim_IncrRefCount(resultObj);
16374
16375 while (1) {
16376
16377 for (i = 0; i < numargs; i += 2) {
16378 if (!JimListIterDone(interp, &iters[i + 1])) {
16379 break;
16380 }
16381 }
16382 if (i == numargs) {
16383
16384 break;
16385 }
16386
16387
16388 for (i = 0; i < numargs; i += 2) {
16389 Jim_Obj *varName;
16390
16391
16392 JimListIterInit(&iters[i], argv[i + 1]);
16393 while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
16394 Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
16395 if (!valObj) {
16396
16397 valObj = interp->emptyObj;
16398 }
16399
16400 Jim_IncrRefCount(valObj);
16401 result = Jim_SetVariable(interp, varName, valObj);
16402 Jim_DecrRefCount(interp, valObj);
16403 if (result != JIM_OK) {
16404 goto err;
@@ -16480,41 +16558,41 @@
16480 {
16481 int boolean, retval, current = 1, falsebody = 0;
16482
16483 if (argc >= 3) {
16484 while (1) {
16485
16486 if (current >= argc)
16487 goto err;
16488 if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean))
16489 != JIM_OK)
16490 return retval;
16491
16492 if (current >= argc)
16493 goto err;
16494 if (Jim_CompareStringImmediate(interp, argv[current], "then"))
16495 current++;
16496
16497 if (current >= argc)
16498 goto err;
16499 if (boolean)
16500 return Jim_EvalObj(interp, argv[current]);
16501
16502 if (++current >= argc) {
16503 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
16504 return JIM_OK;
16505 }
16506 falsebody = current++;
16507 if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) {
16508
16509 if (current != argc - 1)
16510 goto err;
16511 return Jim_EvalObj(interp, argv[current]);
16512 }
16513 else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif"))
16514 continue;
16515
16516 else if (falsebody != argc - 1)
16517 goto err;
16518 return Jim_EvalObj(interp, argv[falsebody]);
16519 }
16520 return JIM_OK;
@@ -16622,21 +16700,21 @@
16622 if (Jim_StringMatchObj(interp, patObj, strObj, 0))
16623 script = caseList[i + 1];
16624 break;
16625 case SWITCH_RE:
16626 command = Jim_NewStringObj(interp, "regexp", -1);
16627
16628 case SWITCH_CMD:{
16629 int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
16630
16631 if (argc - opt == 1) {
16632 Jim_Obj **vector;
16633
16634 JimListGetElements(interp, argv[opt], &patCount, &vector);
16635 caseList = vector;
16636 }
16637
16638 if (rc < 0) {
16639 return -rc;
16640 }
16641 if (rc)
16642 script = caseList[i + 1];
@@ -16770,11 +16848,11 @@
16770 case OPT_COMMAND:
16771 if (i >= argc - 2) {
16772 goto wrongargs;
16773 }
16774 commandObj = argv[++i];
16775
16776 case OPT_EXACT:
16777 case OPT_GLOB:
16778 case OPT_REGEXP:
16779 opt_match = option;
16780 break;
@@ -16818,17 +16896,17 @@
16818 goto done;
16819 }
16820 break;
16821 }
16822
16823
16824 if (!eq && opt_bool && opt_not && !opt_all) {
16825 continue;
16826 }
16827
16828 if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) {
16829
16830 Jim_Obj *resultObj;
16831
16832 if (opt_bool) {
16833 resultObj = Jim_NewIntObj(interp, eq ^ opt_not);
16834 }
@@ -16851,11 +16929,11 @@
16851
16852 if (opt_all) {
16853 Jim_SetResult(interp, listObjPtr);
16854 }
16855 else {
16856
16857 if (opt_bool) {
16858 Jim_SetResultBool(interp, opt_not);
16859 }
16860 else if (!opt_inline) {
16861 Jim_SetResultInt(interp, -1);
@@ -16871,32 +16949,31 @@
16871
16872
16873 static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
16874 {
16875 Jim_Obj *listObjPtr;
16876 int shared, i;
 
16877
16878 if (argc < 2) {
16879 Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
16880 return JIM_ERR;
16881 }
16882 listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
16883 if (!listObjPtr) {
16884
16885 listObjPtr = Jim_NewListObj(interp, NULL, 0);
16886 if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) {
16887 Jim_FreeNewObj(interp, listObjPtr);
16888 return JIM_ERR;
16889 }
16890 }
16891 shared = Jim_IsShared(listObjPtr);
16892 if (shared)
16893 listObjPtr = Jim_DuplicateObj(interp, listObjPtr);
 
 
16894 for (i = 2; i < argc; i++)
16895 Jim_ListAppendElement(interp, listObjPtr, argv[i]);
16896 if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) {
16897 if (shared)
16898 Jim_FreeNewObj(interp, listObjPtr);
16899 return JIM_ERR;
16900 }
16901 Jim_SetResult(interp, listObjPtr);
16902 return JIM_OK;
@@ -16954,31 +17031,31 @@
16954 first = JimRelToAbsIndex(len, first);
16955 last = JimRelToAbsIndex(len, last);
16956 JimRelToAbsRange(len, &first, &last, &rangeLen);
16957
16958
16959
16960 if (first < len) {
16961
16962 }
16963 else if (len == 0) {
16964
16965 first = 0;
16966 }
16967 else {
16968 Jim_SetResultString(interp, "list doesn't contain element ", -1);
16969 Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]);
16970 return JIM_ERR;
16971 }
16972
16973
16974 newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first);
16975
16976
16977 ListInsertElements(newListObj, -1, argc - 4, argv + 4);
16978
16979
16980 ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen);
16981
16982 Jim_SetResult(interp, newListObj);
16983 return JIM_OK;
16984 }
@@ -16989,11 +17066,11 @@
16989 if (argc < 3) {
16990 Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal");
16991 return JIM_ERR;
16992 }
16993 else if (argc == 3) {
16994
16995 if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK)
16996 return JIM_ERR;
16997 Jim_SetResult(interp, argv[2]);
16998 return JIM_OK;
16999 }
@@ -17101,26 +17178,26 @@
17101 stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
17102 if (!stringObjPtr)
17103 return JIM_ERR;
17104 }
17105 else {
17106 int freeobj = 0;
17107 stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED);
17108 if (!stringObjPtr) {
17109
17110 stringObjPtr = Jim_NewEmptyStringObj(interp);
17111 freeobj = 1;
17112 }
17113 else if (Jim_IsShared(stringObjPtr)) {
17114 freeobj = 1;
17115 stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr);
17116 }
17117 for (i = 2; i < argc; i++) {
17118 Jim_AppendObj(interp, stringObjPtr, argv[i]);
17119 }
17120 if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) {
17121 if (freeobj) {
17122 Jim_FreeNewObj(interp, stringObjPtr);
17123 }
17124 return JIM_ERR;
17125 }
17126 }
@@ -17153,11 +17230,11 @@
17153 else {
17154 rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
17155 }
17156
17157 if (rc == JIM_ERR) {
17158
17159 interp->addStackTrace++;
17160 }
17161 return rc;
17162 }
17163
@@ -17165,17 +17242,16 @@
17165 static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17166 {
17167 if (argc >= 2) {
17168 int retcode;
17169 Jim_CallFrame *savedCallFrame, *targetCallFrame;
17170 int savedTailcall;
17171 const char *str;
17172
17173
17174 savedCallFrame = interp->framePtr;
17175
17176
17177 str = Jim_String(argv[1]);
17178 if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') {
17179 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17180 argc--;
17181 argv++;
@@ -17188,22 +17264,18 @@
17188 }
17189 if (argc < 2) {
17190 Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?");
17191 return JIM_ERR;
17192 }
17193
17194 interp->framePtr = targetCallFrame;
17195
17196 savedTailcall = interp->framePtr->tailcall;
17197 interp->framePtr->tailcall = 0;
17198 if (argc == 2) {
17199 retcode = Jim_EvalObj(interp, argv[1]);
17200 }
17201 else {
17202 retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
17203 }
17204 interp->framePtr->tailcall = savedTailcall;
17205 interp->framePtr = savedCallFrame;
17206 return retcode;
17207 }
17208 else {
17209 Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?");
@@ -17294,15 +17366,15 @@
17294 if (i != argc - 1 && i != argc) {
17295 Jim_WrongNumArgs(interp, 1, argv,
17296 "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?");
17297 }
17298
17299
17300 if (stackTraceObj && returnCode == JIM_ERR) {
17301 JimSetStackTrace(interp, stackTraceObj);
17302 }
17303
17304 if (errorCodeObj && returnCode == JIM_ERR) {
17305 Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj);
17306 }
17307 interp->returnCode = returnCode;
17308 interp->returnLevel = level;
@@ -17319,31 +17391,31 @@
17319 if (interp->framePtr->level == 0) {
17320 Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1);
17321 return JIM_ERR;
17322 }
17323 else if (argc >= 2) {
17324
17325 Jim_CallFrame *cf = interp->framePtr->parent;
17326
17327 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17328 if (cmdPtr == NULL) {
17329 return JIM_ERR;
17330 }
17331
17332 JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd"));
17333
17334
17335 JimIncrCmdRefCount(cmdPtr);
17336 cf->tailcallCmd = cmdPtr;
17337
17338
17339 JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj"));
17340
17341 cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1);
17342 Jim_IncrRefCount(cf->tailcallObj);
17343
17344
17345 return JIM_EVAL;
17346 }
17347 return JIM_OK;
17348 }
17349
@@ -17350,11 +17422,11 @@
17350 static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17351 {
17352 Jim_Obj *cmdList;
17353 Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
17354
17355
17356 cmdList = Jim_DuplicateObj(interp, prefixListObj);
17357 Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1);
17358
17359 return JimEvalObjList(interp, cmdList);
17360 }
@@ -17408,22 +17480,22 @@
17408 else {
17409 cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
17410 }
17411
17412 if (cmd) {
17413
17414 Jim_Obj *qualifiedCmdNameObj;
17415 const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
17416
17417 JimCreateCommand(interp, cmdname, cmd);
17418
17419
17420 JimUpdateProcNamespace(interp, cmd, cmdname);
17421
17422 JimFreeQualifiedName(interp, qualifiedCmdNameObj);
17423
17424
17425 Jim_SetResult(interp, argv[1]);
17426 return JIM_OK;
17427 }
17428 return JIM_ERR;
17429 }
@@ -17436,17 +17508,17 @@
17436 if (argc < 2) {
17437 Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?");
17438 return JIM_ERR;
17439 }
17440
17441
17442 interp->local++;
17443 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17444 interp->local--;
17445
17446
17447
17448 if (retcode == 0) {
17449 Jim_Obj *cmdNameObj = Jim_GetResult(interp);
17450
17451 if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
17452 return JIM_ERR;
@@ -17475,18 +17547,18 @@
17475 Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
17476 if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
17477 Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
17478 return JIM_ERR;
17479 }
17480
17481 cmdPtr->u.proc.upcall++;
17482 JimIncrCmdRefCount(cmdPtr);
17483
17484
17485 retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1);
17486
17487
17488 cmdPtr->u.proc.upcall--;
17489 JimDecrCmdRefCount(interp, cmdPtr);
17490
17491 return retcode;
17492 }
@@ -17513,11 +17585,11 @@
17513 return JIM_ERR;
17514 }
17515
17516 if (len == 3) {
17517 #ifdef jim_ext_namespace
17518
17519 nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
17520 #else
17521 Jim_SetResultString(interp, "namespaces not enabled", -1);
17522 return JIM_ERR;
17523 #endif
@@ -17526,11 +17598,11 @@
17526 bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
17527
17528 cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
17529
17530 if (cmd) {
17531
17532 nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
17533 nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
17534 Jim_IncrRefCount(nargv[0]);
17535 memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
17536 ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
@@ -17556,11 +17628,11 @@
17556 static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17557 {
17558 int i;
17559 Jim_CallFrame *targetCallFrame;
17560
17561
17562 if (argc > 3 && (argc % 2 == 0)) {
17563 targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]);
17564 argc--;
17565 argv++;
17566 }
@@ -17569,17 +17641,17 @@
17569 }
17570 if (targetCallFrame == NULL) {
17571 return JIM_ERR;
17572 }
17573
17574
17575 if (argc < 3) {
17576 Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?");
17577 return JIM_ERR;
17578 }
17579
17580
17581 for (i = 1; i < argc; i += 2) {
17582 if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK)
17583 return JIM_ERR;
17584 }
17585 return JIM_OK;
@@ -17592,15 +17664,15 @@
17592
17593 if (argc < 2) {
17594 Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?");
17595 return JIM_ERR;
17596 }
17597
17598 if (interp->framePtr->level == 0)
17599 return JIM_OK;
17600 for (i = 1; i < argc; i++) {
17601
17602 const char *name = Jim_String(argv[i]);
17603 if (name[0] != ':' || name[1] != ':') {
17604 if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
17605 return JIM_ERR;
17606 }
@@ -17623,21 +17695,21 @@
17623 }
17624
17625 str = Jim_String(objPtr);
17626 strLen = Jim_Utf8Length(interp, objPtr);
17627
17628
17629 resultObjPtr = Jim_NewStringObj(interp, "", 0);
17630 while (strLen) {
17631 for (i = 0; i < numMaps; i += 2) {
17632 Jim_Obj *objPtr;
17633 const char *k;
17634 int kl;
17635
17636 objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i);
17637 k = Jim_String(objPtr);
17638 kl = Jim_Utf8Length(interp, objPtr);
17639
17640 if (strLen >= kl && kl) {
17641 int rc;
17642 rc = JimStringCompareLen(str, k, kl, nocase);
17643 if (rc == 0) {
@@ -17650,11 +17722,11 @@
17650 strLen -= kl;
17651 break;
17652 }
17653 }
17654 }
17655 if (i == numMaps) {
17656 int c;
17657 if (noMatchStart == NULL)
17658 noMatchStart = str;
17659 str += utf8_tounicode(str, &c);
17660 strLen--;
@@ -17715,11 +17787,11 @@
17715 return JIM_OK;
17716
17717 case OPT_CAT:{
17718 Jim_Obj *objPtr;
17719 if (argc == 3) {
17720
17721 objPtr = argv[2];
17722 }
17723 else {
17724 int i;
17725
@@ -17734,11 +17806,11 @@
17734 }
17735
17736 case OPT_COMPARE:
17737 case OPT_EQUAL:
17738 {
17739
17740 long opt_length = -1;
17741 int n = argc - 4;
17742 int i = 2;
17743 while (n > 0) {
17744 int subopt;
@@ -17747,16 +17819,16 @@
17747 badcompareargs:
17748 Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
17749 return JIM_ERR;
17750 }
17751 if (subopt == 0) {
17752
17753 opt_case = 0;
17754 n--;
17755 }
17756 else {
17757
17758 if (n < 2) {
17759 goto badcompareargs;
17760 }
17761 if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
17762 return JIM_ERR;
@@ -17767,11 +17839,11 @@
17767 if (n) {
17768 goto badcompareargs;
17769 }
17770 argv += argc - 2;
17771 if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17772
17773 Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
17774 }
17775 else {
17776 if (opt_length >= 0) {
17777 n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
@@ -17881,11 +17953,10 @@
17881 }
17882
17883 case OPT_REVERSE:{
17884 char *buf, *p;
17885 const char *str;
17886 int len;
17887 int i;
17888
17889 if (argc != 3) {
17890 Jim_WrongNumArgs(interp, 2, argv, "string");
17891 return JIM_ERR;
@@ -17925,11 +17996,11 @@
17925 }
17926 if (idx < 0 || idx >= len || str == NULL) {
17927 Jim_SetResultString(interp, "", 0);
17928 }
17929 else if (len == Jim_Length(argv[2])) {
17930
17931 Jim_SetResultString(interp, str + idx, 1);
17932 }
17933 else {
17934 int c;
17935 int i = utf8_index(str, idx);
@@ -18079,11 +18150,11 @@
18079 {
18080 int exitCode = 0;
18081 int i;
18082 int sig = 0;
18083
18084
18085 jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL);
18086 static const int max_ignore_code = sizeof(ignore_mask) * 8;
18087
18088 Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1));
18089
@@ -18090,11 +18161,11 @@
18090 for (i = 1; i < argc - 1; i++) {
18091 const char *arg = Jim_String(argv[i]);
18092 jim_wide option;
18093 int ignore;
18094
18095
18096 if (strcmp(arg, "--") == 0) {
18097 i++;
18098 break;
18099 }
18100 if (*arg != '-') {
@@ -18119,14 +18190,14 @@
18119 if (option < 0) {
18120 goto wrongargs;
18121 }
18122
18123 if (ignore) {
18124 ignore_mask |= (1 << option);
18125 }
18126 else {
18127 ignore_mask &= ~(1 << option);
18128 }
18129 }
18130
18131 argc -= i;
18132 if (argc < 1 || argc > 3) {
@@ -18141,28 +18212,28 @@
18141 sig++;
18142 }
18143
18144 interp->signal_level += sig;
18145 if (Jim_CheckSignal(interp)) {
18146
18147 exitCode = JIM_SIGNAL;
18148 }
18149 else {
18150 exitCode = Jim_EvalObj(interp, argv[0]);
18151
18152 interp->errorFlag = 0;
18153 }
18154 interp->signal_level -= sig;
18155
18156
18157 if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) {
18158
18159 return exitCode;
18160 }
18161
18162 if (sig && exitCode == JIM_SIGNAL) {
18163
18164 if (interp->signal_set_result) {
18165 interp->signal_set_result(interp, interp->sigmask);
18166 }
18167 else {
18168 Jim_SetResultInt(interp, interp->sigmask);
@@ -18201,125 +18272,10 @@
18201 }
18202 Jim_SetResultInt(interp, exitCode);
18203 return JIM_OK;
18204 }
18205
18206 #ifdef JIM_REFERENCES
18207
18208
18209 static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18210 {
18211 if (argc != 3 && argc != 4) {
18212 Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?");
18213 return JIM_ERR;
18214 }
18215 if (argc == 3) {
18216 Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL));
18217 }
18218 else {
18219 Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3]));
18220 }
18221 return JIM_OK;
18222 }
18223
18224
18225 static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18226 {
18227 Jim_Reference *refPtr;
18228
18229 if (argc != 2) {
18230 Jim_WrongNumArgs(interp, 1, argv, "reference");
18231 return JIM_ERR;
18232 }
18233 if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18234 return JIM_ERR;
18235 Jim_SetResult(interp, refPtr->objPtr);
18236 return JIM_OK;
18237 }
18238
18239
18240 static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18241 {
18242 Jim_Reference *refPtr;
18243
18244 if (argc != 3) {
18245 Jim_WrongNumArgs(interp, 1, argv, "reference newValue");
18246 return JIM_ERR;
18247 }
18248 if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL)
18249 return JIM_ERR;
18250 Jim_IncrRefCount(argv[2]);
18251 Jim_DecrRefCount(interp, refPtr->objPtr);
18252 refPtr->objPtr = argv[2];
18253 Jim_SetResult(interp, argv[2]);
18254 return JIM_OK;
18255 }
18256
18257
18258 static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18259 {
18260 if (argc != 1) {
18261 Jim_WrongNumArgs(interp, 1, argv, "");
18262 return JIM_ERR;
18263 }
18264 Jim_SetResultInt(interp, Jim_Collect(interp));
18265
18266
18267 while (interp->freeList) {
18268 Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr;
18269 Jim_Free(interp->freeList);
18270 interp->freeList = nextObjPtr;
18271 }
18272
18273 return JIM_OK;
18274 }
18275
18276
18277 static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18278 {
18279 if (argc != 2 && argc != 3) {
18280 Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?");
18281 return JIM_ERR;
18282 }
18283 if (argc == 2) {
18284 Jim_Obj *cmdNamePtr;
18285
18286 if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK)
18287 return JIM_ERR;
18288 if (cmdNamePtr != NULL)
18289 Jim_SetResult(interp, cmdNamePtr);
18290 }
18291 else {
18292 if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK)
18293 return JIM_ERR;
18294 Jim_SetResult(interp, argv[2]);
18295 }
18296 return JIM_OK;
18297 }
18298
18299
18300 static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18301 {
18302 Jim_Obj *listObjPtr;
18303 Jim_HashTableIterator htiter;
18304 Jim_HashEntry *he;
18305
18306 listObjPtr = Jim_NewListObj(interp, NULL, 0);
18307
18308 JimInitHashTableIterator(&interp->references, &htiter);
18309 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18310 char buf[JIM_REFERENCE_SPACE + 1];
18311 Jim_Reference *refPtr = Jim_GetHashEntryVal(he);
18312 const unsigned long *refId = he->key;
18313
18314 JimFormatReference(buf, refPtr, *refId);
18315 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
18316 }
18317 Jim_SetResult(interp, listObjPtr);
18318 return JIM_OK;
18319 }
18320 #endif
18321
18322
18323 static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18324 {
18325 if (argc != 3) {
@@ -18350,11 +18306,11 @@
18350 JimDictMatchCallbackType *callback, int type)
18351 {
18352 Jim_HashEntry *he;
18353 Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
18354
18355
18356 Jim_HashTableIterator htiter;
18357 JimInitHashTableIterator(ht, &htiter);
18358 while ((he = Jim_NextHashEntry(&htiter)) != NULL) {
18359 if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
18360 callback(interp, listObjPtr, he, type);
@@ -18400,11 +18356,11 @@
18400 return JIM_ERR;
18401 }
18402
18403 ht = (Jim_HashTable *)objPtr->internalRep.ptr;
18404
18405
18406 printf("%d entries in table, %d buckets\n", ht->used, ht->size);
18407
18408 for (i = 0; i < ht->size; i++) {
18409 Jim_HashEntry *he = ht->table[i];
18410
@@ -18524,16 +18480,16 @@
18524 return JIM_OK;
18525 }
18526 if (Jim_DictSize(interp, argv[2]) < 0) {
18527 return JIM_ERR;
18528 }
18529
18530 break;
18531
18532 case OPT_UPDATE:
18533 if (argc < 6 || argc % 2) {
18534
18535 argc = 2;
18536 }
18537 break;
18538
18539 case OPT_CREATE:
@@ -18550,11 +18506,11 @@
18550 Jim_WrongNumArgs(interp, 2, argv, "dictionary");
18551 return JIM_ERR;
18552 }
18553 return Jim_DictInfo(interp, argv[2]);
18554 }
18555
18556 return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2);
18557 }
18558
18559
18560 static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -18620,11 +18576,11 @@
18620
18621 #ifdef jim_ext_namespace
18622 int nons = 0;
18623
18624 if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18625
18626 argc--;
18627 argv++;
18628 nons = 1;
18629 }
18630 #endif
@@ -18636,11 +18592,11 @@
18636 if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
18637 != JIM_OK) {
18638 return JIM_ERR;
18639 }
18640
18641
18642 switch (cmd) {
18643 case INFO_EXISTS:
18644 if (argc != 3) {
18645 Jim_WrongNumArgs(interp, 2, argv, "varName");
18646 return JIM_ERR;
@@ -18665,19 +18621,21 @@
18665 Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
18666 return JIM_OK;
18667 }
18668
18669 case INFO_CHANNELS:
18670 mode++;
18671 #ifndef jim_ext_aio
18672 Jim_SetResultString(interp, "aio not enabled", -1);
18673 return JIM_ERR;
18674 #endif
 
18675 case INFO_PROCS:
18676 mode++;
 
18677 case INFO_COMMANDS:
18678
18679 if (argc != 2 && argc != 3) {
18680 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18681 return JIM_ERR;
18682 }
18683 #ifdef jim_ext_namespace
@@ -18689,15 +18647,17 @@
18689 #endif
18690 Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
18691 break;
18692
18693 case INFO_VARS:
18694 mode++;
 
18695 case INFO_LOCALS:
18696 mode++;
 
18697 case INFO_GLOBALS:
18698
18699 if (argc != 2 && argc != 3) {
18700 Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
18701 return JIM_ERR;
18702 }
18703 #ifdef jim_ext_namespace
@@ -18803,13 +18763,12 @@
18803 case INFO_ARGS:
18804 Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
18805 break;
18806 case INFO_STATICS:
18807 if (cmdPtr->u.proc.staticVars) {
18808 int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
18809 Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
18810 NULL, JimVariablesMatch, mode));
18811 }
18812 break;
18813 }
18814 break;
18815 }
@@ -18827,27 +18786,25 @@
18827 if (argc != 3 && argc != 4) {
18828 Jim_WrongNumArgs(interp, 2, argv, "script ?missing?");
18829 return JIM_ERR;
18830 }
18831 else {
18832 int len;
18833 const char *s = Jim_GetString(argv[2], &len);
18834 char missing;
18835
18836 Jim_SetResultBool(interp, Jim_ScriptIsComplete(s, len, &missing));
18837 if (missing != ' ' && argc == 4) {
18838 Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1));
18839 }
18840 }
18841 break;
18842
18843 case INFO_HOSTNAME:
18844
18845 return Jim_Eval(interp, "os.gethostname");
18846
18847 case INFO_NAMEOFEXECUTABLE:
18848
18849 return Jim_Eval(interp, "{info nameofexecutable}");
18850
18851 case INFO_RETURNCODES:
18852 if (argc == 2) {
18853 int i;
@@ -18924,11 +18881,11 @@
18924
18925 if (option == OPT_VAR) {
18926 result = Jim_GetVariable(interp, objPtr, 0) != NULL;
18927 }
18928 else {
18929
18930 Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
18931
18932 if (cmd) {
18933 switch (option) {
18934 case OPT_COMMAND:
@@ -18967,11 +18924,11 @@
18967 if (len == 0) {
18968 return JIM_OK;
18969 }
18970 strLen = Jim_Utf8Length(interp, argv[1]);
18971
18972
18973 if (argc == 2) {
18974 splitChars = " \n\t\r";
18975 splitLen = 4;
18976 }
18977 else {
@@ -18980,11 +18937,11 @@
18980 }
18981
18982 noMatchStart = str;
18983 resObjPtr = Jim_NewListObj(interp, NULL, 0);
18984
18985
18986 if (splitLen) {
18987 Jim_Obj *objPtr;
18988 while (strLen--) {
18989 const char *sc = splitChars;
18990 int scLen = splitLen;
@@ -19009,11 +18966,11 @@
19009 #define NUM_COMMON (128 - 9)
19010 while (strLen--) {
19011 int n = utf8_tounicode(str, &c);
19012 #ifdef JIM_OPTIMIZATION
19013 if (c >= 9 && c < 128) {
19014
19015 c -= 9;
19016 if (!commonObj) {
19017 commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON);
19018 memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON);
19019 }
@@ -19043,11 +19000,11 @@
19043
19044 if (argc != 2 && argc != 3) {
19045 Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
19046 return JIM_ERR;
19047 }
19048
19049 if (argc == 2) {
19050 joinStr = " ";
19051 joinStrLen = 1;
19052 }
19053 else {
@@ -19322,13 +19279,13 @@
19322 return -1;
19323 else if (step < 0 && end > start)
19324 return -1;
19325 len = end - start;
19326 if (len < 0)
19327 len = -len;
19328 if (step < 0)
19329 step = -step;
19330 len = 1 + ((len - 1) / step);
19331 if (len > INT_MAX)
19332 len = INT_MAX;
19333 return (int)((len < 0) ? -1 : len);
19334 }
@@ -19542,11 +19499,11 @@
19542
19543 *indexPtr = -1;
19544
19545 for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {
19546 if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) {
19547
19548 *indexPtr = i;
19549 return JIM_OK;
19550 }
19551 if (flags & JIM_ENUM_ABBREV) {
19552 if (strncmp(arg, *entryPtr, arglen) == 0) {
@@ -19560,11 +19517,11 @@
19560 match = i;
19561 }
19562 }
19563 }
19564
19565
19566 if (match >= 0) {
19567 *indexPtr = match;
19568 return JIM_OK;
19569 }
19570
@@ -19597,11 +19554,11 @@
19597 return objPtr->typePtr == &listObjType;
19598 }
19599
19600 void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...)
19601 {
19602
19603 int len = strlen(format);
19604 int extra = 0;
19605 int n = 0;
19606 const char *params[5];
19607 char *buf;
@@ -19662,11 +19619,11 @@
19662 #include <string.h>
19663
19664
19665 static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19666 {
19667
19668 return JIM_OK;
19669 }
19670
19671 static const jim_subcmd_type dummy_subcmd = {
19672 "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
@@ -19741,43 +19698,43 @@
19741 return 0;
19742 }
19743
19744 cmd = argv[1];
19745
19746
19747 if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
19748 if (argc == 2) {
19749
19750 show_cmd_usage(interp, command_table, argc, argv);
19751 return &dummy_subcmd;
19752 }
19753 help = 1;
19754
19755
19756 cmd = argv[2];
19757 }
19758
19759
19760 if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
19761
19762 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
19763 add_commands(interp, command_table, " ");
19764 return &dummy_subcmd;
19765 }
19766
19767 cmdstr = Jim_GetString(cmd, &cmdlen);
19768
19769 for (ct = command_table; ct->cmd; ct++) {
19770 if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
19771
19772 break;
19773 }
19774 if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
19775 if (partial) {
19776
19777 if (help) {
19778
19779 show_cmd_usage(interp, command_table, argc, argv);
19780 return &dummy_subcmd;
19781 }
19782 bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
19783 return 0;
@@ -19785,44 +19742,44 @@
19785 partial = ct;
19786 }
19787 continue;
19788 }
19789
19790
19791 if (partial && !ct->cmd) {
19792 ct = partial;
19793 }
19794
19795 if (!ct->cmd) {
19796
19797 if (help) {
19798
19799 show_cmd_usage(interp, command_table, argc, argv);
19800 return &dummy_subcmd;
19801 }
19802 bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
19803 return 0;
19804 }
19805
19806 if (help) {
19807 Jim_SetResultString(interp, "Usage: ", -1);
19808
19809 add_cmd_usage(interp, ct, argv[0]);
19810 return &dummy_subcmd;
19811 }
19812
19813
19814 if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
19815 Jim_SetResultString(interp, "wrong # args: should be \"", -1);
19816
19817 add_cmd_usage(interp, ct, argv[0]);
19818 Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
19819
19820 return 0;
19821 }
19822
19823
19824 return ct;
19825 }
19826
19827 int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
19828 {
@@ -19873,11 +19830,11 @@
19873 *p++ = 0xe0 | ((uc & 0xf000) >> 12);
19874 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
19875 *p = 0x80 | (uc & 0x3f);
19876 return 3;
19877 }
19878
19879 else {
19880 *p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
19881 *p++ = 0x80 | ((uc & 0x3f000) >> 12);
19882 *p++ = 0x80 | ((uc & 0xfc0) >> 6);
19883 *p = 0x80 | (uc & 0x3f);
@@ -20064,11 +20021,11 @@
20064 if (ch == 'h') {
20065 useShort = 1;
20066 format += step;
20067 step = utf8_tounicode(format, &ch);
20068 } else if (ch == 'l') {
20069
20070 format += step;
20071 step = utf8_tounicode(format, &ch);
20072 if (ch == 'l') {
20073 format += step;
20074 step = utf8_tounicode(format, &ch);
@@ -20091,11 +20048,11 @@
20091 goto errorMsg;
20092 case 's': {
20093 formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes);
20094 formatted_chars = Jim_Utf8Length(interp, objv[objIndex]);
20095 if (gotPrecision && (precision < formatted_chars)) {
20096
20097 formatted_chars = precision;
20098 formatted_bytes = utf8_index(formatted_buf, precision);
20099 }
20100 break;
20101 }
@@ -20103,11 +20060,11 @@
20103 jim_wide code;
20104
20105 if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) {
20106 goto error;
20107 }
20108
20109 formatted_bytes = utf8_getchars(spec, code);
20110 formatted_buf = spec;
20111 formatted_chars = 1;
20112 break;
20113 }
@@ -20121,11 +20078,11 @@
20121 goto error;
20122 }
20123 length = sizeof(w) * 8;
20124
20125
20126
20127 if (num_buffer_size < length + 1) {
20128 num_buffer_size = length + 1;
20129 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20130 }
20131
@@ -20149,29 +20106,29 @@
20149 case 'E':
20150 case 'f':
20151 case 'g':
20152 case 'G':
20153 doubleType = 1;
20154
20155 case 'd':
20156 case 'u':
20157 case 'o':
20158 case 'x':
20159 case 'X': {
20160 jim_wide w;
20161 double d;
20162 int length;
20163
20164
20165 if (width) {
20166 p += sprintf(p, "%ld", width);
20167 }
20168 if (gotPrecision) {
20169 p += sprintf(p, ".%ld", precision);
20170 }
20171
20172
20173 if (doubleType) {
20174 if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) {
20175 goto error;
20176 }
20177 length = MAX_FLOAT_WIDTH;
@@ -20198,19 +20155,19 @@
20198 }
20199
20200 *p++ = (char) ch;
20201 *p = '\0';
20202
20203
20204 if (width > length) {
20205 length = width;
20206 }
20207 if (gotPrecision) {
20208 length += precision;
20209 }
20210
20211
20212 if (num_buffer_size < length + 1) {
20213 num_buffer_size = length + 1;
20214 num_buffer = Jim_Realloc(num_buffer, num_buffer_size);
20215 }
20216
@@ -20224,11 +20181,11 @@
20224 formatted_buf = num_buffer;
20225 break;
20226 }
20227
20228 default: {
20229
20230 spec[0] = ch;
20231 spec[1] = '\0';
20232 Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec);
20233 goto error;
20234 }
@@ -20276,36 +20233,37 @@
20276
20277 #define REG_MAX_PAREN 100
20278
20279
20280
20281 #define END 0
20282 #define BOL 1
20283 #define EOL 2
20284 #define ANY 3
20285 #define ANYOF 4
20286 #define ANYBUT 5
20287 #define BRANCH 6
20288 #define BACK 7
20289 #define EXACTLY 8
20290 #define NOTHING 9
20291 #define REP 10
20292 #define REPMIN 11
20293 #define REPX 12
20294 #define REPXMIN 13
20295
20296 #define WORDA 15
20297 #define WORDZ 16
20298
20299 #define OPENNC 1000
20300 #define OPEN 1001
20301
20302
20303
20304
20305 #define CLOSENC 2000
20306 #define CLOSE 2001
 
20307 #define CLOSE_END (CLOSE+REG_MAX_PAREN)
20308
20309 #define REG_MAGIC 0xFADED00D
20310
20311
@@ -20318,18 +20276,18 @@
20318
20319 #define FAIL(R,M) { (R)->err = (M); return (M); }
20320 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{')
20321 #define META "^$.[()|?{+*"
20322
20323 #define HASWIDTH 1
20324 #define SIMPLE 2
20325 #define SPSTART 4
20326 #define WORST 0
20327
20328 #define MAX_REP_COUNT 1000000
20329
20330 static int reg(regex_t *preg, int paren , int *flagp );
20331 static int regpiece(regex_t *preg, int *flagp );
20332 static int regbranch(regex_t *preg, int *flagp );
20333 static int regatom(regex_t *preg, int *flagp );
20334 static int regnode(regex_t *preg, int op );
20335 static int regnext(regex_t *preg, int p );
@@ -20373,15 +20331,15 @@
20373 memset(preg, 0, sizeof(*preg));
20374
20375 if (exp == NULL)
20376 FAIL(preg, REG_ERR_NULL_ARGUMENT);
20377
20378
20379 preg->cflags = cflags;
20380 preg->regparse = exp;
20381
20382
20383 preg->proglen = (strlen(exp) + 1) * 5;
20384 preg->program = malloc(preg->proglen * sizeof(int));
20385 if (preg->program == NULL)
20386 FAIL(preg, REG_ERR_NOMEM);
20387
@@ -20388,24 +20346,24 @@
20388 regc(preg, REG_MAGIC);
20389 if (reg(preg, 0, &flags) == 0) {
20390 return preg->err;
20391 }
20392
20393
20394 if (preg->re_nsub >= REG_MAX_PAREN)
20395 FAIL(preg,REG_ERR_TOO_BIG);
20396
20397
20398 preg->regstart = 0;
20399 preg->reganch = 0;
20400 preg->regmust = 0;
20401 preg->regmlen = 0;
20402 scan = 1;
20403 if (OP(preg, regnext(preg, scan)) == END) {
20404 scan = OPERAND(scan);
20405
20406
20407 if (OP(preg, scan) == EXACTLY) {
20408 preg->regstart = preg->program[OPERAND(scan)];
20409 }
20410 else if (OP(preg, scan) == BOL)
20411 preg->reganch++;
@@ -20432,24 +20390,24 @@
20432 #endif
20433
20434 return 0;
20435 }
20436
20437 static int reg(regex_t *preg, int paren , int *flagp )
20438 {
20439 int ret;
20440 int br;
20441 int ender;
20442 int parno = 0;
20443 int flags;
20444
20445 *flagp = HASWIDTH;
20446
20447
20448 if (paren) {
20449 if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
20450
20451 preg->regparse += 2;
20452 parno = -1;
20453 }
20454 else {
20455 parno = ++preg->re_nsub;
@@ -20456,16 +20414,16 @@
20456 }
20457 ret = regnode(preg, OPEN+parno);
20458 } else
20459 ret = 0;
20460
20461
20462 br = regbranch(preg, &flags);
20463 if (br == 0)
20464 return 0;
20465 if (ret != 0)
20466 regtail(preg, ret, br);
20467 else
20468 ret = br;
20469 if (!(flags&HASWIDTH))
20470 *flagp &= ~HASWIDTH;
20471 *flagp |= flags&SPSTART;
@@ -20472,25 +20430,25 @@
20472 while (*preg->regparse == '|') {
20473 preg->regparse++;
20474 br = regbranch(preg, &flags);
20475 if (br == 0)
20476 return 0;
20477 regtail(preg, ret, br);
20478 if (!(flags&HASWIDTH))
20479 *flagp &= ~HASWIDTH;
20480 *flagp |= flags&SPSTART;
20481 }
20482
20483
20484 ender = regnode(preg, (paren) ? CLOSE+parno : END);
20485 regtail(preg, ret, ender);
20486
20487
20488 for (br = ret; br != 0; br = regnext(preg, br))
20489 regoptail(preg, br, ender);
20490
20491
20492 if (paren && *preg->regparse++ != ')') {
20493 preg->err = REG_ERR_UNMATCHED_PAREN;
20494 return 0;
20495 } else if (!paren && *preg->regparse != '\0') {
20496 if (*preg->regparse == ')') {
@@ -20510,11 +20468,11 @@
20510 int ret;
20511 int chain;
20512 int latest;
20513 int flags;
20514
20515 *flagp = WORST;
20516
20517 ret = regnode(preg, BRANCH);
20518 chain = 0;
20519 while (*preg->regparse != '\0' && *preg->regparse != ')' &&
20520 *preg->regparse != '|') {
@@ -20528,11 +20486,11 @@
20528 else {
20529 regtail(preg, chain, latest);
20530 }
20531 chain = latest;
20532 }
20533 if (chain == 0)
20534 (void) regnode(preg, NOTHING);
20535
20536 return(ret);
20537 }
20538
@@ -20558,11 +20516,11 @@
20558 if (!(flags&HASWIDTH) && op != '?') {
20559 preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY;
20560 return 0;
20561 }
20562
20563
20564 if (op == '{') {
20565 char *end;
20566
20567 min = strtoul(preg->regparse + 1, &end, 10);
20568 if (end == preg->regparse + 1) {
@@ -20630,11 +20588,11 @@
20630 static void reg_addrange(regex_t *preg, int lower, int upper)
20631 {
20632 if (lower > upper) {
20633 reg_addrange(preg, upper, lower);
20634 }
20635
20636 regc(preg, upper - lower + 1);
20637 regc(preg, lower);
20638 }
20639
20640 static void reg_addrange_str(regex_t *preg, const char *str)
@@ -20698,17 +20656,17 @@
20698 case 'r': *ch = '\r'; break;
20699 case 't': *ch = '\t'; break;
20700 case 'v': *ch = '\v'; break;
20701 case 'u':
20702 if (*s == '{') {
20703
20704 n = parse_hex(s + 1, 6, ch);
20705 if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
20706 s += n + 2;
20707 }
20708 else {
20709
20710 *ch = 'u';
20711 }
20712 }
20713 else if ((n = parse_hex(s, 4, ch)) > 0) {
20714 s += n;
@@ -20739,15 +20697,15 @@
20739 int nocase = (preg->cflags & REG_ICASE);
20740
20741 int ch;
20742 int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase);
20743
20744 *flagp = WORST;
20745
20746 preg->regparse += n;
20747 switch (ch) {
20748
20749 case '^':
20750 ret = regnode(preg, BOL);
20751 break;
20752 case '$':
20753 ret = regnode(preg, EOL);
@@ -20757,24 +20715,24 @@
20757 *flagp |= HASWIDTH|SIMPLE;
20758 break;
20759 case '[': {
20760 const char *pattern = preg->regparse;
20761
20762 if (*pattern == '^') {
20763 ret = regnode(preg, ANYBUT);
20764 pattern++;
20765 } else
20766 ret = regnode(preg, ANYOF);
20767
20768
20769 if (*pattern == ']' || *pattern == '-') {
20770 reg_addrange(preg, *pattern, *pattern);
20771 pattern++;
20772 }
20773
20774 while (*pattern && *pattern != ']') {
20775
20776 int start;
20777 int end;
20778
20779 pattern += reg_utf8_tounicode_case(pattern, &start, nocase);
20780 if (start == '\\') {
@@ -20783,11 +20741,11 @@
20783 preg->err = REG_ERR_NULL_CHAR;
20784 return 0;
20785 }
20786 }
20787 if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
20788
20789 pattern += utf8_tounicode(pattern, &end);
20790 pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
20791 if (end == '\\') {
20792 pattern += reg_decode_escape(pattern, &end);
20793 if (end == 0) {
@@ -20797,35 +20755,81 @@
20797 }
20798
20799 reg_addrange(preg, start, end);
20800 continue;
20801 }
20802 if (start == '[') {
20803 if (strncmp(pattern, ":alpha:]", 8) == 0) {
20804 if ((preg->cflags & REG_ICASE) == 0) {
20805 reg_addrange(preg, 'a', 'z');
20806 }
20807 reg_addrange(preg, 'A', 'Z');
20808 pattern += 8;
20809 continue;
20810 }
20811 if (strncmp(pattern, ":alnum:]", 8) == 0) {
20812 if ((preg->cflags & REG_ICASE) == 0) {
20813 reg_addrange(preg, 'a', 'z');
20814 }
20815 reg_addrange(preg, 'A', 'Z');
20816 reg_addrange(preg, '0', '9');
20817 pattern += 8;
20818 continue;
20819 }
20820 if (strncmp(pattern, ":space:]", 8) == 0) {
20821 reg_addrange_str(preg, " \t\r\n\f\v");
20822 pattern += 8;
20823 continue;
20824 }
20825 }
20826
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20827 reg_addrange(preg, start, start);
20828 }
20829 regc(preg, '\0');
20830
20831 if (*pattern) {
@@ -20844,38 +20848,47 @@
20844 break;
20845 case '\0':
20846 case '|':
20847 case ')':
20848 preg->err = REG_ERR_INTERNAL;
20849 return 0;
20850 case '?':
20851 case '+':
20852 case '*':
20853 case '{':
20854 preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING;
20855 return 0;
20856 case '\\':
20857 switch (*preg->regparse++) {
 
20858 case '\0':
20859 preg->err = REG_ERR_TRAILING_BACKSLASH;
20860 return 0;
 
 
 
 
 
 
20861 case '<':
20862 case 'm':
20863 ret = regnode(preg, WORDA);
20864 break;
20865 case '>':
20866 case 'M':
20867 ret = regnode(preg, WORDZ);
20868 break;
20869 case 'd':
20870 ret = regnode(preg, ANYOF);
 
20871 reg_addrange(preg, '0', '9');
20872 regc(preg, '\0');
20873 *flagp |= HASWIDTH|SIMPLE;
20874 break;
20875 case 'w':
20876 ret = regnode(preg, ANYOF);
 
20877 if ((preg->cflags & REG_ICASE) == 0) {
20878 reg_addrange(preg, 'a', 'z');
20879 }
20880 reg_addrange(preg, 'A', 'Z');
20881 reg_addrange(preg, '0', '9');
@@ -20882,39 +20895,40 @@
20882 reg_addrange(preg, '_', '_');
20883 regc(preg, '\0');
20884 *flagp |= HASWIDTH|SIMPLE;
20885 break;
20886 case 's':
20887 ret = regnode(preg, ANYOF);
 
20888 reg_addrange_str(preg," \t\r\n\f\v");
20889 regc(preg, '\0');
20890 *flagp |= HASWIDTH|SIMPLE;
20891 break;
20892
20893 default:
20894
20895
20896 preg->regparse--;
20897 goto de_fault;
20898 }
20899 break;
20900 de_fault:
20901 default: {
20902 int added = 0;
20903
20904
20905 preg->regparse -= n;
20906
20907 ret = regnode(preg, EXACTLY);
20908
20909
20910
20911 while (*preg->regparse && strchr(META, *preg->regparse) == NULL) {
20912 n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE));
20913 if (ch == '\\' && preg->regparse[n]) {
20914 if (strchr("<>mMwds", preg->regparse[n])) {
20915
20916 break;
20917 }
20918 n += reg_decode_escape(preg->regparse + n, &ch);
20919 if (ch == 0) {
20920 preg->err = REG_ERR_NULL_CHAR;
@@ -20922,23 +20936,23 @@
20922 }
20923 }
20924
20925
20926 if (ISMULT(preg->regparse[n])) {
20927
20928 if (added) {
20929
20930 break;
20931 }
20932
20933 regc(preg, ch);
20934 added++;
20935 preg->regparse += n;
20936 break;
20937 }
20938
20939
20940 regc(preg, ch);
20941 added++;
20942 preg->regparse += n;
20943 }
20944 regc(preg, '\0');
@@ -20965,15 +20979,15 @@
20965
20966 static int regnode(regex_t *preg, int op)
20967 {
20968 reg_grow(preg, 2);
20969
20970
20971 preg->program[preg->p++] = op;
20972 preg->program[preg->p++] = 0;
20973
20974
20975 return preg->p - 2;
20976 }
20977
20978 static void regc(regex_t *preg, int b )
20979 {
@@ -20983,13 +20997,13 @@
20983
20984 static int reginsert(regex_t *preg, int op, int size, int opnd )
20985 {
20986 reg_grow(preg, size);
20987
20988
20989 memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd));
20990
20991 memset(preg->program + opnd, 0, sizeof(int) * size);
20992
20993 preg->program[opnd] = op;
20994
20995 preg->p += size;
@@ -21001,11 +21015,11 @@
21001 {
21002 int scan;
21003 int temp;
21004 int offset;
21005
21006
21007 scan = p;
21008 for (;;) {
21009 temp = regnext(preg, scan);
21010 if (temp == 0)
21011 break;
@@ -21021,11 +21035,11 @@
21021 }
21022
21023
21024 static void regoptail(regex_t *preg, int p, int val )
21025 {
21026
21027 if (p != 0 && OP(preg, p) == BRANCH) {
21028 regtail(preg, OPERAND(p), val);
21029 }
21030 }
21031
@@ -21037,16 +21051,16 @@
21037 int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
21038 {
21039 const char *s;
21040 int scan;
21041
21042
21043 if (preg == NULL || preg->program == NULL || string == NULL) {
21044 return REG_ERR_NULL_ARGUMENT;
21045 }
21046
21047
21048 if (*preg->program != REG_MAGIC) {
21049 return REG_ERR_CORRUPTED;
21050 }
21051
21052 #ifdef DEBUG
@@ -21055,51 +21069,51 @@
21055 #endif
21056
21057 preg->eflags = eflags;
21058 preg->pmatch = pmatch;
21059 preg->nmatch = nmatch;
21060 preg->start = string;
21061
21062
21063 for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) {
21064 int op = OP(preg, scan);
21065 if (op == END)
21066 break;
21067 if (op == REPX || op == REPXMIN)
21068 preg->program[scan + 4] = 0;
21069 }
21070
21071
21072 if (preg->regmust != 0) {
21073 s = string;
21074 while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) {
21075 if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) {
21076 break;
21077 }
21078 s++;
21079 }
21080 if (s == NULL)
21081 return REG_NOMATCH;
21082 }
21083
21084
21085 preg->regbol = string;
21086
21087
21088 if (preg->reganch) {
21089 if (eflags & REG_NOTBOL) {
21090
21091 goto nextline;
21092 }
21093 while (1) {
21094 if (regtry(preg, string)) {
21095 return REG_NOERROR;
21096 }
21097 if (*string) {
21098 nextline:
21099 if (preg->cflags & REG_NEWLINE) {
21100
21101 string = strchr(string, '\n');
21102 if (string) {
21103 preg->regbol = ++string;
21104 continue;
21105 }
@@ -21107,22 +21121,22 @@
21107 }
21108 return REG_NOMATCH;
21109 }
21110 }
21111
21112
21113 s = string;
21114 if (preg->regstart != '\0') {
21115
21116 while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) {
21117 if (regtry(preg, s))
21118 return REG_NOERROR;
21119 s++;
21120 }
21121 }
21122 else
21123
21124 while (1) {
21125 if (regtry(preg, s))
21126 return REG_NOERROR;
21127 if (*s == '\0') {
21128 break;
@@ -21131,15 +21145,15 @@
21131 int c;
21132 s += utf8_tounicode(s, &c);
21133 }
21134 }
21135
21136
21137 return REG_NOMATCH;
21138 }
21139
21140
21141 static int regtry( regex_t *preg, const char *string )
21142 {
21143 int i;
21144
21145 preg->reginput = string;
@@ -21176,11 +21190,11 @@
21176 }
21177
21178 static int reg_range_find(const int *range, int c)
21179 {
21180 while (*range) {
21181
21182 if (c >= range[1] && c <= (range[0] + range[1] - 1)) {
21183 return 1;
21184 }
21185 range += 2;
21186 }
@@ -21188,11 +21202,11 @@
21188 }
21189
21190 static const char *str_find(const char *string, int c, int nocase)
21191 {
21192 if (nocase) {
21193
21194 c = utf8_upper(c);
21195 }
21196 while (*string) {
21197 int ch;
21198 int n = reg_utf8_tounicode_case(string, &ch, nocase);
@@ -21232,15 +21246,15 @@
21232 no = regrepeat(preg, scan + 5, max);
21233 if (no < min) {
21234 return 0;
21235 }
21236 if (matchmin) {
21237
21238 max = no;
21239 no = min;
21240 }
21241
21242 while (1) {
21243 if (matchmin) {
21244 if (no > max) {
21245 break;
21246 }
@@ -21250,22 +21264,22 @@
21250 break;
21251 }
21252 }
21253 preg->reginput = save + utf8_index(save, no);
21254 reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21255
21256 if (reg_iseol(preg, nextch) || c == nextch) {
21257 if (regmatch(preg, next)) {
21258 return(1);
21259 }
21260 }
21261 if (matchmin) {
21262
21263 no++;
21264 }
21265 else {
21266
21267 no--;
21268 }
21269 }
21270 return(0);
21271 }
@@ -21275,13 +21289,13 @@
21275 int *scanpt = preg->program + scan;
21276
21277 int max = scanpt[2];
21278 int min = scanpt[3];
21279
21280
21281 if (scanpt[4] < min) {
21282
21283 scanpt[4]++;
21284 if (regmatch(preg, scan + 5)) {
21285 return 1;
21286 }
21287 scanpt[4]--;
@@ -21290,39 +21304,39 @@
21290 if (scanpt[4] > max) {
21291 return 0;
21292 }
21293
21294 if (matchmin) {
21295
21296 if (regmatch(preg, regnext(preg, scan))) {
21297 return 1;
21298 }
21299
21300 scanpt[4]++;
21301 if (regmatch(preg, scan + 5)) {
21302 return 1;
21303 }
21304 scanpt[4]--;
21305 return 0;
21306 }
21307
21308 if (scanpt[4] < max) {
21309 scanpt[4]++;
21310 if (regmatch(preg, scan + 5)) {
21311 return 1;
21312 }
21313 scanpt[4]--;
21314 }
21315
21316 return regmatch(preg, regnext(preg, scan));
21317 }
21318
21319
21320 static int regmatch(regex_t *preg, int prog)
21321 {
21322 int scan;
21323 int next;
21324 const char *save;
21325
21326 scan = prog;
21327
21328 #ifdef DEBUG
@@ -21332,48 +21346,60 @@
21332 while (scan != 0) {
21333 int n;
21334 int c;
21335 #ifdef DEBUG
21336 if (regnarrate) {
21337 fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan)));
21338 }
21339 #endif
21340 next = regnext(preg, scan);
21341 n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE));
21342
21343 switch (OP(preg, scan)) {
 
 
 
 
 
21344 case BOL:
21345 if (preg->reginput != preg->regbol)
21346 return(0);
 
 
 
 
 
 
 
21347 break;
21348 case EOL:
21349 if (!reg_iseol(preg, c)) {
21350 return(0);
21351 }
21352 break;
21353 case WORDA:
21354
21355 if ((!isalnum(UCHAR(c))) && c != '_')
21356 return(0);
21357
21358 if (preg->reginput > preg->regbol &&
21359 (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_'))
21360 return(0);
21361 break;
21362 case WORDZ:
21363
21364 if (preg->reginput > preg->regbol) {
21365
21366 if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') {
21367 c = preg->reginput[-1];
21368
21369 if (isalnum(UCHAR(c)) || c == '_') {
21370 break;
21371 }
21372 }
21373 }
21374
21375 return(0);
21376
21377 case ANY:
21378 if (reg_iseol(preg, c))
21379 return 0;
@@ -21409,12 +21435,12 @@
21409 case NOTHING:
21410 break;
21411 case BACK:
21412 break;
21413 case BRANCH:
21414 if (OP(preg, next) != BRANCH)
21415 next = OPERAND(scan);
21416 else {
21417 do {
21418 save = preg->reginput;
21419 if (regmatch(preg, OPERAND(scan))) {
21420 return(1);
@@ -21421,11 +21447,11 @@
21421 }
21422 preg->reginput = save;
21423 scan = regnext(preg, scan);
21424 } while (scan != 0 && OP(preg, scan) == BRANCH);
21425 return(0);
21426
21427 }
21428 break;
21429 case REP:
21430 case REPMIN:
21431 return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN);
@@ -21433,11 +21459,11 @@
21433 case REPX:
21434 case REPXMIN:
21435 return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN);
21436
21437 case END:
21438 return 1;
21439
21440 case OPENNC:
21441 case CLOSENC:
21442 return regmatch(preg, next);
21443
@@ -21480,11 +21506,11 @@
21480
21481 scan = preg->reginput;
21482 opnd = OPERAND(p);
21483 switch (OP(preg, p)) {
21484 case ANY:
21485
21486 while (!reg_iseol(preg, *scan) && count < max) {
21487 count++;
21488 scan++;
21489 }
21490 break;
@@ -21516,13 +21542,13 @@
21516 }
21517 count++;
21518 scan += n;
21519 }
21520 break;
21521 default:
21522 preg->err = REG_ERR_INTERNAL;
21523 count = 0;
21524 break;
21525 }
21526 preg->reginput = scan;
21527
21528 return(count);
@@ -21543,11 +21569,11 @@
21543 return(p+offset);
21544 }
21545
21546 static int regopsize(regex_t *preg, int p )
21547 {
21548
21549 switch (OP(preg, p)) {
21550 case REP:
21551 case REPMIN:
21552 case REPX:
21553 case REPXMIN:
@@ -21664,26 +21690,26 @@
21664 {
21665 DIR *dir = 0;
21666
21667 if (name && name[0]) {
21668 size_t base_length = strlen(name);
21669 const char *all =
21670 strchr("/\\", name[base_length - 1]) ? "*" : "/*";
21671
21672 if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
21673 (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) {
21674 strcat(strcpy(dir->name, name), all);
21675
21676 if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1)
21677 dir->result.d_name = 0;
21678 else {
21679 Jim_Free(dir->name);
21680 Jim_Free(dir);
21681 dir = 0;
21682 }
21683 }
21684 else {
21685 Jim_Free(dir);
21686 dir = 0;
21687 errno = ENOMEM;
21688 }
21689 }
@@ -21701,11 +21727,11 @@
21701 if (dir->handle != -1)
21702 result = _findclose(dir->handle);
21703 Jim_Free(dir->name);
21704 Jim_Free(dir);
21705 }
21706 if (result == -1)
21707 errno = EBADF;
21708 return result;
21709 }
21710
21711 struct dirent *readdir(DIR * dir)
@@ -21729,11 +21755,13 @@
21729 #include <errno.h>
21730 #include <string.h>
21731
21732
21733 #ifdef USE_LINENOISE
21734 #include <unistd.h>
 
 
21735 #include "linenoise.h"
21736 #else
21737 #define MAX_LINE_LEN 512
21738 #endif
21739
@@ -21782,11 +21810,11 @@
21782 }
21783
21784 void Jim_HistoryShow(void)
21785 {
21786 #ifdef USE_LINENOISE
21787
21788 int i;
21789 int len;
21790 char **history = linenoiseHistory(&len);
21791 for (i = 0; i < len; i++) {
21792 printf("%4d %s\n", i + 1, history[i]);
@@ -21817,32 +21845,29 @@
21817 while (1) {
21818 Jim_Obj *scriptObjPtr;
21819 const char *result;
21820 int reslen;
21821 char prompt[20];
21822 const char *str;
21823
21824 if (retcode != 0) {
21825 const char *retcodestr = Jim_ReturnCode(retcode);
21826
21827 if (*retcodestr == '?') {
21828 snprintf(prompt, sizeof(prompt) - 3, "[%d] ", retcode);
21829 }
21830 else {
21831 snprintf(prompt, sizeof(prompt) - 3, "[%s] ", retcodestr);
21832 }
21833 }
21834 else {
21835 prompt[0] = '\0';
21836 }
21837 strcat(prompt, ". ");
21838
21839 scriptObjPtr = Jim_NewStringObj(interp, "", 0);
21840 Jim_IncrRefCount(scriptObjPtr);
21841 while (1) {
21842 char state;
21843 int len;
21844 char *line;
21845
21846 line = Jim_HistoryGetline(prompt);
21847 if (line == NULL) {
21848 if (errno == EINTR) {
@@ -21851,26 +21876,23 @@
21851 Jim_DecrRefCount(interp, scriptObjPtr);
21852 retcode = JIM_OK;
21853 goto out;
21854 }
21855 if (Jim_Length(scriptObjPtr) != 0) {
 
21856 Jim_AppendString(interp, scriptObjPtr, "\n", 1);
21857 }
21858 Jim_AppendString(interp, scriptObjPtr, line, -1);
21859 free(line);
21860 str = Jim_GetString(scriptObjPtr, &len);
21861 if (len == 0) {
21862 continue;
21863 }
21864 if (Jim_ScriptIsComplete(str, len, &state))
21865 break;
21866
21867 snprintf(prompt, sizeof(prompt), "%c> ", state);
21868 }
21869 #ifdef USE_LINENOISE
21870 if (strcmp(str, "h") == 0) {
21871
21872 Jim_HistoryShow();
21873 Jim_DecrRefCount(interp, scriptObjPtr);
21874 continue;
21875 }
21876
@@ -21881,11 +21903,10 @@
21881 #endif
21882 retcode = Jim_EvalObj(interp, scriptObjPtr);
21883 Jim_DecrRefCount(interp, scriptObjPtr);
21884
21885 if (retcode == JIM_EXIT) {
21886 retcode = JIM_EXIT;
21887 break;
21888 }
21889 if (retcode == JIM_ERR) {
21890 Jim_MakeErrorMessage(interp);
21891 }
@@ -21910,11 +21931,11 @@
21910 static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
21911 {
21912 int n;
21913 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
21914
21915
21916 for (n = 0; n < argc; n++) {
21917 Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
21918
21919 Jim_ListAppendElement(interp, listObj, obj);
21920 }
@@ -21926,45 +21947,71 @@
21926 static void JimPrintErrorMessage(Jim_Interp *interp)
21927 {
21928 Jim_MakeErrorMessage(interp);
21929 fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp)));
21930 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21931
21932 int main(int argc, char *const argv[])
21933 {
21934 int retcode;
21935 Jim_Interp *interp;
 
 
21936
21937 if (argc > 1 && strcmp(argv[1], "--version") == 0) {
21938 printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
21939 return 0;
21940 }
 
 
 
 
21941
21942
21943 interp = Jim_CreateInterp();
21944 Jim_RegisterCoreCommands(interp);
21945
21946
21947 if (Jim_InitStaticExtensions(interp) != JIM_OK) {
21948 JimPrintErrorMessage(interp);
21949 }
21950
21951 Jim_SetVariableStrWithStr(interp, "jim::argv0", argv[0]);
21952 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0");
21953 retcode = Jim_initjimshInit(interp);
21954
21955 if (argc == 1) {
 
21956 if (retcode == JIM_ERR) {
21957 JimPrintErrorMessage(interp);
21958 }
21959 if (retcode != JIM_EXIT) {
21960 JimSetArgv(interp, 0, NULL);
21961 retcode = Jim_InteractivePrompt(interp);
21962 }
21963 }
21964 else {
 
21965 if (argc > 2 && strcmp(argv[1], "-e") == 0) {
 
21966 JimSetArgv(interp, argc - 3, argv + 3);
21967 retcode = Jim_Eval(interp, argv[2]);
21968 if (retcode != JIM_ERR) {
21969 printf("%s\n", Jim_String(Jim_GetResult(interp)));
21970 }
21971
21972 DDED autosetup/pkg-config.tcl
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -1,20 +1,18 @@
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 "."
8 #define jim_ext_bootstrap
9 #define jim_ext_aio
10 #define jim_ext_readdir
 
11 #define jim_ext_regexp
12 #define jim_ext_file
13 #define jim_ext_glob
14 #define jim_ext_exec
15 #define jim_ext_clock
16 #define jim_ext_array
17 #define jim_ext_stdlib
18 #define jim_ext_tclcompat
@@ -35,20 +33,26 @@
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
@@ -64,11 +68,13 @@
68 int dlclose(void *handle);
69 void *dlsym(void *handle, const char *symbol);
70 char *dlerror(void);
71
72
73 #if defined(__MINGW32__)
74 #define JIM_SPRINTF_DOUBLE_NEEDS_FIX
75 #endif
76
77 #ifdef _MSC_VER
78
79
80 #if _MSC_VER >= 1000
@@ -103,14 +109,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);
@@ -120,11 +126,11 @@
126 #include <stdlib.h>
127 #define strtod __strtod
128
129 #endif
130
131 #endif
132
133 #ifdef __cplusplus
134 }
135 #endif
136
@@ -173,13 +179,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
@@ -222,31 +228,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
@@ -337,79 +343,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
@@ -440,43 +446,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;
@@ -488,35 +491,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
@@ -524,64 +527,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))
@@ -737,12 +740,12 @@
740 JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...);
741
742
743 JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp);
744 JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp,
745 const char *cmdName, Jim_CmdProc *cmdProc, void *privData,
746 Jim_DelCmdProc *delProc);
747 JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp,
748 const char *cmdName);
749 JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp,
750 const char *oldName, const char *newName);
751 JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp,
@@ -832,10 +835,14 @@
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);
@@ -853,12 +860,13 @@
860
861 JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc,
862 Jim_Obj *const *argv, const char *msg);
863 JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr,
864 const char * const *tablePtr, int *indexPtr, const char *name, int flags);
865 JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp,
866 Jim_Obj *scriptObj, char *stateCharPtr);
867
868 JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len);
869
870
871 typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data);
872 JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key);
@@ -904,11 +912,11 @@
912
913 #ifdef __cplusplus
914 }
915 #endif
916
917 #endif
918
919 #ifndef JIM_SUBCMD_H
920 #define JIM_SUBCMD_H
921
922
@@ -915,24 +923,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
@@ -960,36 +968,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
@@ -997,13 +1005,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,
@@ -1037,11 +1045,20 @@
1045 return JIM_ERR;
1046
1047 return Jim_EvalSource(interp, "bootstrap.tcl", 1,
1048 "\n"
1049 "\n"
1050 "proc package {cmd pkg} {\n"
1051 " if {$cmd eq \"require\"} {\n"
1052 " foreach path $::auto_path {\n"
1053 " if {[file exists $path/$pkg.tcl]} {\n"
1054 " uplevel #0 [list source $path/$pkg.tcl]\n"
1055 " return\n"
1056 " }\n"
1057 " }\n"
1058 " }\n"
1059 "}\n"
1060 );
1061 }
1062 int Jim_initjimshInit(Jim_Interp *interp)
1063 {
1064 if (Jim_PackageProvide(interp, "initjimsh", "1.0", JIM_ERRMSG))
@@ -1771,10 +1788,11 @@
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
@@ -1793,13 +1811,18 @@
1811 #endif
1812 #else
1813 #define JIM_ANSIC
1814 #endif
1815
1816 #if defined(JIM_SSL)
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
@@ -1815,66 +1838,61 @@
1838 #ifndef PF_INET6
1839 #define PF_INET6 0
1840 #endif
1841 #endif
1842
1843 #define JimCheckStreamError(interp, af) af->fops->error(af)
1844
1845
1846 struct AioFile;
1847
1848 typedef struct {
1849 int (*writer)(struct AioFile *af, const char *buf, int len);
1850 int (*reader)(struct AioFile *af, char *buf, int len);
1851 const char *(*getline)(struct AioFile *af, char *buf, int len);
1852 int (*error)(const struct AioFile *af);
1853 const char *(*strerror)(struct AioFile *af);
1854 int (*verify)(struct AioFile *af);
1855 } JimAioFopsType;
1856
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;
1868 void *ssl;
1869 const JimAioFopsType *fops;
1870 } AioFile;
1871
1872 static int stdio_writer(struct AioFile *af, const char *buf, int len)
1873 {
1874 return fwrite(buf, 1, len, af->fp);
1875 }
1876
1877 static int stdio_reader(struct AioFile *af, char *buf, int len)
1878 {
1879 return fread(buf, 1, len, af->fp);
1880 }
1881
1882 static const char *stdio_getline(struct AioFile *af, char *buf, int len)
1883 {
1884 return fgets(buf, len, af->fp);
1885 }
1886
1887 static int stdio_error(const AioFile *af)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) {
@@ -1884,21 +1902,86 @@
1902 #ifdef ECONNABORTED
1903 if (errno != ECONNABORTED) {
1904 return JIM_OK;
1905 }
1906 #endif
 
1907 return JIM_ERR;
1908 }
1909
1910 static const char *stdio_strerror(struct AioFile *af)
1911 {
1912 return strerror(errno);
1913 }
1914
1915 static const JimAioFopsType stdio_fops = {
1916 stdio_writer,
1917 stdio_reader,
1918 stdio_getline,
1919 stdio_error,
1920 stdio_strerror,
1921 NULL
1922 };
1923
1924
1925 static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
1926 static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
1927 const char *hdlfmt, int family, const char *mode);
1928
1929
1930 static const char *JimAioErrorString(AioFile *af)
1931 {
1932 if (af && af->fops)
1933 return af->fops->strerror(af);
1934
1935 return strerror(errno);
1936 }
1937
1938 static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name)
1939 {
1940 AioFile *af = Jim_CmdPrivData(interp);
1941
1942 if (name) {
1943 Jim_SetResultFormatted(interp, "%#s: %s", name, JimAioErrorString(af));
1944 }
1945 else {
1946 Jim_SetResultString(interp, JimAioErrorString(af), -1);
1947 }
1948 }
1949
1950 static void JimAioDelProc(Jim_Interp *interp, void *privData)
1951 {
1952 AioFile *af = privData;
1953
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);
1966 }
1967 #endif
1968
1969 if (!(af->openFlags & AIO_KEEPOPEN)) {
1970 fclose(af->fp);
1971 }
1972
1973 Jim_Free(af);
1974 }
1975
1976 static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
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--;
@@ -1923,21 +2006,21 @@
2006 readlen = AIO_BUF_LEN;
2007 }
2008 else {
2009 readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen);
2010 }
2011 retval = af->fops->reader(af, buf, readlen);
2012 if (retval > 0) {
2013 Jim_AppendString(interp, objPtr, buf, retval);
2014 if (neededLen != -1) {
2015 neededLen -= retval;
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) {
@@ -1950,19 +2033,43 @@
2033 }
2034 }
2035 Jim_SetResult(interp, objPtr);
2036 return JIM_OK;
2037 }
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;
2049 }
2050
2051 FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command)
2052 {
2053 AioFile *af;
2054
2055 af = Jim_AioFile(interp, command);
2056 if (af == NULL) {
2057 return NULL;
2058 }
2059
2060 return af->fp;
2061 }
2062
2063 static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2064 {
2065 AioFile *af = Jim_CmdPrivData(interp);
2066 jim_wide count = 0;
2067 jim_wide maxlen = JIM_WIDE_MAX;
2068 AioFile *outf = Jim_AioFile(interp, argv[0]);
2069
2070 if (outf == NULL) {
2071 return JIM_ERR;
2072 }
2073
2074 if (argc == 2) {
2075 if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) {
@@ -1969,27 +2076,22 @@
2076 return JIM_ERR;
2077 }
2078 }
2079
2080 while (count < maxlen) {
2081 char ch;
2082
2083 if (af->fops->reader(af, &ch, 1) != 1) {
2084 break;
2085 }
2086 if (outf->fops->writer(outf, &ch, 1) != 1) {
2087 break;
2088 }
2089 count++;
2090 }
2091
2092 if (JimCheckStreamError(interp, af) || JimCheckStreamError(interp, outf)) {
 
 
 
 
 
 
 
 
2093 return JIM_ERR;
2094 }
2095
2096 Jim_SetResultInt(interp, count);
2097
@@ -2006,30 +2108,32 @@
2108 errno = 0;
2109
2110 objPtr = Jim_NewStringObj(interp, NULL, 0);
2111 while (1) {
2112 buf[AIO_BUF_LEN - 1] = '_';
2113
2114 if (af->fops->getline(af, buf, AIO_BUF_LEN) == NULL)
2115 break;
2116
2117 if (buf[AIO_BUF_LEN - 1] == '\0' && buf[AIO_BUF_LEN - 2] != '\n') {
2118 Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN - 1);
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) {
@@ -2039,11 +2143,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 {
@@ -2068,12 +2172,12 @@
2172 else {
2173 strObj = argv[0];
2174 }
2175
2176 wdata = Jim_GetString(strObj, &wlen);
2177 if (af->fops->writer(af, wdata, wlen) == wlen) {
2178 if (argc == 2 || af->fops->writer(af, "\n", 1) == 1) {
2179 return JIM_OK;
2180 }
2181 }
2182 JimAioSetError(interp, af->filename);
2183 return JIM_ERR;
@@ -2202,10 +2306,21 @@
2306 }
2307 Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0);
2308 return JIM_OK;
2309 }
2310 #endif
2311
2312 #ifdef HAVE_FSYNC
2313 static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2314 {
2315 AioFile *af = Jim_CmdPrivData(interp);
2316
2317 fflush(af->fp);
2318 fsync(af->fd);
2319 return JIM_OK;
2320 }
2321 #endif
2322
2323 static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2324 {
2325 AioFile *af = Jim_CmdPrivData(interp);
2326
@@ -2258,33 +2373,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
@@ -2307,127 +2422,138 @@
2422 AioFile *af = Jim_CmdPrivData(interp);
2423
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
@@ -2450,11 +2576,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);
@@ -2462,24 +2588,31 @@
2588
2589 return Jim_EvalObjVector(interp, 3, evalObj);
2590 }
2591 }
2592 #endif
2593 return JimMakeChannel(interp, NULL, -1, argv[1], "aio.handle%ld", 0, mode) ? JIM_OK : JIM_ERR;
2594 }
2595
2596
2597 static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filename,
2598 const char *hdlfmt, int family, const char *mode)
2599 {
2600 AioFile *af;
2601 char buf[AIO_CMD_LEN];
2602 int openFlags = 0;
2603
2604 snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
2605
2606 if (fh) {
 
2607 openFlags = AIO_KEEPOPEN;
2608 }
2609
2610 snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
2611 if (!filename) {
2612 filename = Jim_NewStringObj(interp, buf, -1);
2613 }
2614
2615 Jim_IncrRefCount(filename);
2616
2617 if (fh == NULL) {
2618 #if !defined(JIM_ANSIC)
@@ -2496,15 +2629,15 @@
2629 if (fd >= 0) {
2630 close(fd);
2631 }
2632 #endif
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;
@@ -2513,34 +2646,36 @@
2646 (void)fcntl(af->fd, F_SETFD, FD_CLOEXEC);
2647 }
2648 #endif
2649 af->openFlags = openFlags;
2650 af->addr_family = family;
2651 af->fops = &stdio_fops;
2652 af->ssl = NULL;
2653
2654 Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc);
2655
2656 Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
2657
2658 return af;
2659 }
2660
2661 #if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H))
2662 static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename,
2663 const char *hdlfmt, int family, const char *mode[2])
2664 {
2665 if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0])) {
2666 Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0);
2667 Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
2668
2669 if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1])) {
2670 Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp));
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 }
@@ -2567,13 +2702,18 @@
2702 }
2703 else {
2704 filenameObj = Jim_NewStringObj(interp, template, -1);
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);
@@ -2586,33 +2726,26 @@
2726 Jim_SetResultString(interp, "platform has no tempfile support", -1);
2727 return -1;
2728 #endif
2729 }
2730
 
 
 
 
 
 
 
 
 
 
 
2731
2732 int Jim_aioInit(Jim_Interp *interp)
2733 {
2734 if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG))
2735 return JIM_ERR;
2736
2737 #if defined(JIM_SSL)
2738 Jim_CreateCommand(interp, "load_ssl_certs", JimAioLoadSSLCertsCommand, NULL, NULL);
2739 #endif
2740
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;
@@ -2708,20 +2841,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];
@@ -2769,11 +2902,11 @@
2902 };
2903
2904 if (argc < 3) {
2905 wrongNumArgs:
2906 Jim_WrongNumArgs(interp, 1, argv,
2907 "?-switch ...? exp string ?matchVar? ?subMatchVar ...?");
2908 return JIM_ERR;
2909 }
2910
2911 for (i = 1; i < argc; i++) {
2912 const char *opt = Jim_String(argv[i]);
@@ -2878,11 +3011,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;
@@ -2918,11 +3051,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;
@@ -2991,11 +3124,11 @@
3124 };
3125
3126 if (argc < 4) {
3127 wrongNumArgs:
3128 Jim_WrongNumArgs(interp, 1, argv,
3129 "?-switch ...? exp string subSpec ?varName?");
3130 return JIM_ERR;
3131 }
3132
3133 for (i = 1; i < argc; i++) {
3134 const char *opt = Jim_String(argv[i]);
@@ -3045,11 +3178,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;
@@ -3060,11 +3193,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;
@@ -3102,11 +3235,11 @@
3235 else if ((c == '\\') || (c == '&')) {
3236 Jim_AppendString(interp, resultObj, replace_str + j, 1);
3237 continue;
3238 }
3239 else {
3240 Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2);
3241 continue;
3242 }
3243 }
3244 else {
3245 Jim_AppendString(interp, resultObj, replace_str + j, 1);
@@ -3119,23 +3252,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
@@ -3142,11 +3275,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);
@@ -3248,11 +3381,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);
@@ -3264,25 +3397,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);
@@ -3289,11 +3422,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
@@ -3309,11 +3442,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 }
@@ -3389,35 +3522,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) {
@@ -3428,22 +3561,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 }
@@ -3468,11 +3601,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
@@ -3493,11 +3626,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 }
@@ -3516,15 +3649,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;
@@ -3537,24 +3670,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
@@ -3839,192 +3972,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 };
@@ -4056,11 +4189,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 }
@@ -4080,10 +4213,11 @@
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__)
@@ -4091,20 +4225,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);
@@ -4145,11 +4279,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>
@@ -4205,11 +4339,11 @@
4339 static char **JimSaveEnv(char **env);
4340 static void JimRestoreEnv(char **env);
4341 static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv,
4342 pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr);
4343 static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr);
4344 static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj);
4345 static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len);
4346 static fdtype JimOpenForWrite(const char *filename, int append);
4347 static int JimRewindFd(fdtype fd);
4348
4349 static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg)
@@ -4235,26 +4369,28 @@
4369
4370 static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj)
4371 {
4372 char buf[256];
4373 FILE *fh = JimFdOpenForRead(fd);
4374 int ret = 0;
4375
4376 if (fh == NULL) {
4377 return -1;
4378 }
4379
4380 while (1) {
4381 int retval = fread(buf, 1, sizeof(buf), fh);
4382 if (retval > 0) {
4383 ret = 1;
4384 Jim_AppendString(interp, strObj, buf, retval);
4385 }
4386 if (retval != sizeof(buf)) {
4387 break;
4388 }
4389 }
 
4390 fclose(fh);
4391 return ret;
4392 }
4393
4394 static char **JimBuildEnv(Jim_Interp *interp)
4395 {
4396 int i;
@@ -4269,14 +4405,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);
@@ -4308,25 +4444,38 @@
4444 if (env != original_environ) {
4445 Jim_Free(env);
4446 }
4447 }
4448
4449 #ifndef jim_ext_signal
4450
4451 const char *Jim_SignalId(int sig)
4452 {
4453 static char buf[10];
4454 snprintf(buf, sizeof(buf), "%d", sig);
4455 return buf;
4456 }
4457
4458 const char *Jim_SignalName(int sig)
4459 {
4460 return Jim_SignalId(sig);
4461 }
4462 #endif
4463
4464 static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj)
4465 {
4466 Jim_Obj *errorCode;
4467
4468 if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) {
4469 return JIM_OK;
4470 }
4471 errorCode = Jim_NewListObj(interp, NULL, 0);
4472
4473 if (WIFEXITED(waitStatus)) {
4474 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
4475 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4476 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
 
 
 
 
 
 
4477 }
4478 else {
4479 const char *type;
4480 const char *action;
4481
@@ -4339,38 +4488,35 @@
4488 action = "suspended";
4489 }
4490
4491 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));
4492
4493 if (errStrObj) {
4494 Jim_AppendStrings(interp, errStrObj, "child ", action, " by signal ", Jim_SignalId(WTERMSIG(waitStatus)), "\n", NULL);
4495 }
4496
4497 Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
4498 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
 
4499 Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
 
 
 
 
 
 
4500 }
4501 Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
4502
4503 return JIM_ERR;
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
@@ -4393,14 +4539,17 @@
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;
4551
4552 if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) {
4553 Jim_Obj *listObj;
4554 int i;
4555
@@ -4407,11 +4556,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);
@@ -4425,23 +4574,56 @@
4574
4575 if (numPids < 0) {
4576 return JIM_ERR;
4577 }
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;
4597 }
4598
4599 if (errorId != JIM_BAD_FD) {
4600 int ret;
4601 JimRewindFd(errorId);
4602 ret = JimAppendStreamToString(interp, errorId, errStrObj);
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
4628 static void JimReapDetachedPids(struct WaitInfoTable *table)
4629 {
@@ -4458,11 +4640,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]) {
@@ -4474,36 +4656,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;
@@ -4536,16 +4718,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. */
@@ -4566,20 +4748,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
@@ -4625,11 +4807,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;
@@ -4666,11 +4848,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) {
@@ -4684,11 +4866,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);
@@ -4695,11 +4877,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 }
@@ -4747,20 +4929,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);
@@ -4802,11 +4984,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 {
@@ -4815,16 +4997,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]);
@@ -4835,32 +5017,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 }
@@ -4869,11 +5051,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);
@@ -4934,35 +5116,27 @@
5116 numPids = -1;
5117 goto cleanup;
5118 }
5119
5120
5121 static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj)
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;
5133 }
5134 }
5135 }
5136 Jim_Free(pidPtr);
5137
 
 
 
 
 
 
 
 
 
5138 return result;
5139 }
5140
5141 int Jim_execInit(Jim_Interp *interp)
5142 {
@@ -5121,17 +5295,21 @@
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");
@@ -5139,11 +5317,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);
@@ -5166,11 +5344,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
@@ -5195,12 +5373,11 @@
5373 {
5374 int i;
5375 static char extensions[][5] = {".exe", "", ".bat"};
5376
5377 for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
5378 snprintf(fullPath, MAX_PATH, "%s%s", originalName, extensions[i]);
 
5379
5380 if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) {
5381 continue;
5382 }
5383 if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) {
@@ -5439,11 +5616,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";
@@ -5480,20 +5657,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
@@ -5531,47 +5708,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
@@ -5591,11 +5768,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)
@@ -5607,20 +5784,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 {
@@ -5640,27 +5817,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]);
@@ -5675,11 +5852,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;
@@ -5714,11 +5891,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 }
@@ -5743,53 +5920,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
@@ -5804,32 +5981,33 @@
5981 int Jim_InitStaticExtensions(Jim_Interp *interp)
5982 {
5983 extern int Jim_bootstrapInit(Jim_Interp *);
5984 extern int Jim_aioInit(Jim_Interp *);
5985 extern int Jim_readdirInit(Jim_Interp *);
 
5986 extern int Jim_regexpInit(Jim_Interp *);
5987 extern int Jim_fileInit(Jim_Interp *);
5988 extern int Jim_globInit(Jim_Interp *);
5989 extern int Jim_execInit(Jim_Interp *);
5990 extern int Jim_clockInit(Jim_Interp *);
5991 extern int Jim_arrayInit(Jim_Interp *);
5992 extern int Jim_stdlibInit(Jim_Interp *);
5993 extern int Jim_tclcompatInit(Jim_Interp *);
5994 Jim_bootstrapInit(interp);
5995 Jim_aioInit(interp);
5996 Jim_readdirInit(interp);
 
5997 Jim_regexpInit(interp);
5998 Jim_fileInit(interp);
5999 Jim_globInit(interp);
6000 Jim_execInit(interp);
6001 Jim_clockInit(interp);
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>
@@ -5894,10 +6072,16 @@
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,
@@ -5950,34 +6134,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 }
@@ -6007,19 +6191,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
@@ -6028,20 +6212,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;
@@ -6087,11 +6271,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;
@@ -6128,11 +6312,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 }
@@ -6187,28 +6371,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)
@@ -6222,11 +6406,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)
@@ -6241,11 +6425,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 }
@@ -6266,26 +6450,40 @@
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
@@ -6347,11 +6545,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
@@ -6436,52 +6634,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)
@@ -6490,11 +6688,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
@@ -6516,11 +6714,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
@@ -6539,11 +6737,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);
@@ -6553,19 +6751,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;
@@ -6576,15 +6774,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;
@@ -6657,24 +6855,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;
@@ -6703,16 +6901,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;
@@ -6727,16 +6925,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;
@@ -6789,61 +6987,61 @@
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);
@@ -6864,20 +7062,20 @@
7062 pc->tstart = NULL;
7063 pc->tend = NULL;
7064 pc->tline = 0;
7065 pc->tt = JIM_TT_NONE;
7066 pc->eof = 0;
7067 pc->inquote = 0;
7068 pc->linenr = linenr;
7069 pc->comment = 1;
7070 pc->missing.ch = ' ';
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;
@@ -6884,36 +7082,36 @@
7082 pc->eof = 1;
7083 return JIM_OK;
7084 }
7085 switch (*(pc->p)) {
7086 case '\\':
7087 if (*(pc->p + 1) == '\n' && !pc->inquote) {
7088 return JimParseSep(pc);
7089 }
7090 pc->comment = 0;
7091 return JimParseStr(pc);
7092 case ' ':
7093 case '\t':
7094 case '\r':
7095 case '\f':
7096 if (!pc->inquote)
7097 return JimParseSep(pc);
7098 pc->comment = 0;
7099 return JimParseStr(pc);
7100 case '\n':
7101 case ';':
7102 pc->comment = 1;
7103 if (!pc->inquote)
7104 return JimParseEol(pc);
7105 return JimParseStr(pc);
7106 case '[':
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;
@@ -6970,11 +7168,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 '\\':
@@ -7014,11 +7212,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 '\\':
@@ -7063,11 +7261,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 '\\':
@@ -7143,17 +7341,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
@@ -7179,11 +7377,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 }
@@ -7194,11 +7392,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;
@@ -7221,11 +7419,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
@@ -7246,36 +7444,36 @@
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;
7463 while (1) {
7464 if (pc->len == 0) {
7465 if (pc->inquote) {
7466 pc->missing.ch = '"';
7467 }
7468 pc->tend = pc->p - 1;
7469 pc->tt = JIM_TT_ESC;
7470 return JIM_OK;
7471 }
7472 switch (*pc->p) {
7473 case '\\':
7474 if (!pc->inquote && *(pc->p + 1) == '\n') {
7475 pc->tend = pc->p - 1;
7476 pc->tt = JIM_TT_ESC;
7477 return JIM_OK;
7478 }
7479 if (pc->len >= 2) {
@@ -7284,24 +7482,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;
@@ -7318,34 +7517,34 @@
7517 case '\t':
7518 case '\n':
7519 case '\r':
7520 case '\f':
7521 case ';':
7522 if (!pc->inquote) {
7523 pc->tend = pc->p - 1;
7524 pc->tt = JIM_TT_ESC;
7525 return JIM_OK;
7526 }
7527 else if (*pc->p == '\n') {
7528 pc->linenr++;
7529 }
7530 break;
7531 case '"':
7532 if (pc->inquote) {
7533 pc->tend = pc->p - 1;
7534 pc->tt = JIM_TT_ESC;
7535 pc->p++;
7536 pc->len--;
7537 pc->inquote = 0;
7538 return JIM_OK;
7539 }
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) {
@@ -7394,13 +7593,10 @@
7593 static int JimEscape(char *dest, const char *s, int slen)
7594 {
7595 char *p = dest;
7596 int i, len;
7597
 
 
 
7598 for (i = 0; i < slen; i++) {
7599 switch (s[i]) {
7600 case '\\':
7601 switch (s[i + 1]) {
7602 case 'a':
@@ -7455,34 +7651,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;
@@ -7491,11 +7687,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;
@@ -7505,11 +7701,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;
@@ -7562,37 +7758,23 @@
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);
7774 }
7775
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7776 static int JimParseListSep(struct JimParserCtx *pc);
7777 static int JimParseListStr(struct JimParserCtx *pc);
7778 static int JimParseListQuote(struct JimParserCtx *pc);
7779
7780 static int JimParseList(struct JimParserCtx *pc)
@@ -7649,11 +7831,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;
@@ -7685,11 +7867,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++;
@@ -7705,24 +7887,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;
@@ -7730,32 +7912,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;
@@ -7778,45 +7960,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;
@@ -7825,11 +8007,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 }
@@ -7836,11 +8018,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;
@@ -7896,22 +8078,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
@@ -7932,14 +8114,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);
@@ -7946,25 +8128,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;
@@ -7991,11 +8173,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);
@@ -8007,11 +8189,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
@@ -8069,11 +8251,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
@@ -8171,11 +8353,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);
@@ -8200,19 +8382,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
@@ -8311,11 +8493,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 }
@@ -8382,41 +8564,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 }
@@ -8434,17 +8616,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;
@@ -8472,10 +8654,17 @@
8654 {
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;
@@ -8524,11 +8713,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)
@@ -8600,12 +8789,10 @@
8789 return objPtr;
8790 }
8791
8792 static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
8793 static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
 
 
8794
8795 static const Jim_ObjType scriptObjType = {
8796 "script",
8797 FreeScriptInternalRep,
8798 DupScriptInternalRep,
@@ -8619,21 +8806,25 @@
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);
8826
8827 void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
8828 {
8829 int i;
8830 struct ScriptObj *script = (void *)objPtr->internalRep.ptr;
@@ -8656,23 +8847,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;
@@ -8691,18 +8882,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 }
@@ -8716,20 +8907,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
@@ -8739,11 +8930,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 }
@@ -8756,13 +8947,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
@@ -8771,11 +8962,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 }
@@ -8782,59 +8973,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);
@@ -8860,10 +9051,19 @@
9051 printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr));
9052 }
9053 #endif
9054
9055 }
9056
9057 int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr)
9058 {
9059 ScriptObj *script = JimGetScript(interp, scriptObj);
9060 if (stateCharPtr) {
9061 *stateCharPtr = script->missing;
9062 }
9063 return (script->missing == ' ');
9064 }
9065
9066 static int JimParseCheckMissing(Jim_Interp *interp, int ch)
9067 {
9068 const char *msg;
9069
@@ -8897,11 +9097,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 }
@@ -8916,29 +9116,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;
@@ -8950,25 +9150,25 @@
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 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);
@@ -9003,17 +9203,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 }
@@ -9024,46 +9224,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 }
@@ -9087,16 +9287,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);
@@ -9105,11 +9305,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 {
@@ -9124,17 +9324,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 }
@@ -9141,15 +9341,15 @@
9341 return JIM_OK;
9342 }
9343
9344
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;
@@ -9174,11 +9374,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);
@@ -9220,19 +9420,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
@@ -9245,11 +9445,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;
@@ -9260,24 +9460,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:
@@ -9288,16 +9488,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
@@ -9358,29 +9558,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
@@ -9419,23 +9619,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) {
@@ -9442,11 +9642,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 }
@@ -9455,11 +9655,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;
@@ -9474,11 +9674,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",
@@ -9488,11 +9688,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);
@@ -9508,18 +9708,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) {
@@ -9527,11 +9727,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] == ':') {
@@ -9543,23 +9743,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;
@@ -9574,11 +9774,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;
@@ -9593,14 +9793,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;
@@ -9630,11 +9830,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);
@@ -9691,14 +9891,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;
@@ -9706,23 +9906,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 }
@@ -9742,15 +9942,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;
@@ -9762,13 +9962,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
@@ -9782,26 +9982,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 }
@@ -9851,17 +10051,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;
@@ -9876,11 +10076,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)) {
@@ -9909,11 +10109,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;
@@ -9928,23 +10128,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 }
@@ -9966,11 +10166,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 }
@@ -10008,11 +10208,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);
@@ -10053,11 +10253,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 }
@@ -10076,11 +10276,10 @@
10276 cf->procArgsObjPtr = NULL;
10277 cf->procBodyObjPtr = NULL;
10278 cf->next = NULL;
10279 cf->staticVars = NULL;
10280 cf->localCommands = NULL;
 
10281 cf->tailcallObj = NULL;
10282 cf->tailcallCmd = NULL;
10283 }
10284 else {
10285 cf = Jim_Alloc(sizeof(*cf));
@@ -10098,11 +10297,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;
@@ -10117,20 +10316,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);
@@ -10138,12 +10337,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)
@@ -10176,263 +10375,10 @@
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;
@@ -10479,14 +10425,15 @@
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);
10436 Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM);
10437 Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR);
10438 Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", Jim_IsBigEndian() ? "bigEndian" : "littleEndian");
10439 Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0");
@@ -10500,11 +10447,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
@@ -10553,27 +10500,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 {
@@ -10594,25 +10541,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 }
@@ -10627,19 +10574,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 }
@@ -10658,11 +10605,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
@@ -10679,32 +10626,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 }
@@ -10806,18 +10753,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;
@@ -10824,11 +10771,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 }
@@ -10923,17 +10870,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;
@@ -10955,38 +10902,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;
@@ -11018,10 +10965,50 @@
10965 objPtr->typePtr = &doubleObjType;
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);
@@ -11069,11 +11056,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;
@@ -11091,19 +11078,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++) {
@@ -11219,11 +11207,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;
@@ -11238,25 +11226,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
@@ -11283,17 +11271,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 }
@@ -11324,21 +11312,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 {
@@ -11345,20 +11333,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
@@ -11488,11 +11476,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);
@@ -11510,23 +11498,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)
@@ -11540,11 +11528,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;
@@ -11563,16 +11551,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) {
@@ -11596,11 +11585,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 }
@@ -11782,34 +11771,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--;
@@ -11836,11 +11825,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;
@@ -11876,16 +11865,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,
@@ -11906,17 +11895,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
@@ -11932,11 +11921,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);
@@ -11946,15 +11935,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
@@ -11968,18 +11957,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);
@@ -12004,11 +11993,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 }
@@ -12104,11 +12093,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);
@@ -12118,26 +12107,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);
@@ -12150,11 +12139,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 }
@@ -12187,11 +12176,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 }
@@ -12200,14 +12189,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 }
@@ -12218,21 +12207,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;
@@ -12240,19 +12229,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
@@ -12262,11 +12251,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;
@@ -12319,18 +12308,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 }
@@ -12344,19 +12333,20 @@
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,
@@ -12367,66 +12357,67 @@
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,
@@ -12433,10 +12424,12 @@
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;
@@ -12513,11 +12506,15 @@
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;
@@ -12705,16 +12702,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 }
@@ -12736,11 +12733,10 @@
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);
@@ -12748,30 +12744,36 @@
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;
@@ -12778,55 +12780,67 @@
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
@@ -12834,83 +12848,70 @@
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;
@@ -12959,16 +12960,20 @@
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)
@@ -12977,21 +12982,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
@@ -13004,21 +13009,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);
@@ -13039,11 +13044,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
@@ -13054,27 +13059,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);
@@ -13086,15 +13091,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);
@@ -13110,15 +13115,16 @@
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),
@@ -13142,27 +13148,28 @@
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),
@@ -13188,10 +13195,11 @@
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),
@@ -13198,10 +13206,12 @@
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
@@ -13208,20 +13218,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;
@@ -13247,11 +13257,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 }
@@ -13276,10 +13286,18 @@
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;
@@ -13289,21 +13307,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;
@@ -13327,17 +13345,38 @@
13345 return JIM_OK;
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]) {
@@ -13351,11 +13390,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))) {
@@ -13385,13 +13424,19 @@
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
@@ -13416,13 +13461,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;
@@ -13450,26 +13495,29 @@
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++;
@@ -13476,26 +13524,47 @@
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];
@@ -13508,11 +13577,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
@@ -13520,16 +13589,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;
@@ -13575,11 +13644,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 {
@@ -13617,11 +13686,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];
@@ -13630,25 +13699,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;
@@ -13659,11 +13728,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 }
@@ -13671,128 +13740,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;
@@ -13808,11 +13877,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 }
@@ -13835,11 +13904,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 {
@@ -13848,18 +13917,17 @@
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
@@ -13882,14 +13950,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 }
@@ -13905,20 +13973,22 @@
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;
@@ -13958,11 +14028,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;
@@ -14031,26 +14101,27 @@
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:
@@ -14086,16 +14157,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 }
@@ -14119,20 +14190,27 @@
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;
@@ -14147,29 +14225,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);
@@ -14216,22 +14294,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];
@@ -14243,12 +14321,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 == '%') {
@@ -14258,65 +14336,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];
@@ -14331,11 +14409,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];
@@ -14346,11 +14424,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) {
@@ -14389,11 +14467,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--)
@@ -14412,89 +14490,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 }
@@ -14511,13 +14589,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 }
@@ -14542,65 +14620,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);
@@ -14638,15 +14716,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];
@@ -14660,19 +14738,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]];
@@ -14699,11 +14777,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 }
@@ -14713,26 +14791,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;
@@ -14740,16 +14818,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 }
@@ -14767,11 +14845,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);
@@ -14786,11 +14864,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 {
@@ -14807,17 +14885,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 }
@@ -14835,25 +14913,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;
@@ -14888,14 +14966,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;
@@ -14930,23 +15008,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) {
@@ -14957,28 +15035,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);
@@ -14989,11 +15067,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;
@@ -15033,11 +15111,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 }
@@ -15069,11 +15147,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;
@@ -15080,19 +15158,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;
@@ -15148,11 +15226,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) {
@@ -15161,39 +15239,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) {
@@ -15200,21 +15278,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);
@@ -15224,14 +15302,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);
@@ -15238,11 +15316,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 }
@@ -15252,26 +15330,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) {
@@ -15296,11 +15374,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;
@@ -15308,21 +15386,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 }
@@ -15332,62 +15410,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) {
@@ -15396,60 +15474,56 @@
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;
15507
15508 if (retcode == JIM_EVAL) {
15509 retcode = Jim_EvalObjList(interp, tailcallObj);
15510 if (retcode == JIM_RETURN) {
15511 interp->returnLevel++;
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;
@@ -15561,20 +15635,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
@@ -15600,11 +15674,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)) {
@@ -15631,32 +15705,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;
@@ -15667,11 +15741,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 }
@@ -15685,11 +15759,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--;
@@ -15701,11 +15775,15 @@
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);
@@ -15726,11 +15804,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 }
@@ -15757,11 +15835,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);
@@ -15817,11 +15895,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) {
@@ -16004,11 +16082,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 }
@@ -16047,11 +16125,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;
@@ -16087,11 +16165,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);
@@ -16103,19 +16181,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 }
@@ -16128,48 +16206,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 }
@@ -16177,18 +16255,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) {
@@ -16208,25 +16286,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);
@@ -16268,11 +16346,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) {
@@ -16333,21 +16411,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 {
@@ -16371,34 +16449,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;
@@ -16480,41 +16558,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;
@@ -16622,21 +16700,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];
@@ -16770,11 +16848,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;
@@ -16818,17 +16896,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 }
@@ -16851,11 +16929,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);
@@ -16871,32 +16949,31 @@
16949
16950
16951 static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
16952 {
16953 Jim_Obj *listObjPtr;
16954 int new_obj = 0;
16955 int i;
16956
16957 if (argc < 2) {
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);
16969 new_obj = 1;
16970 }
16971 for (i = 2; i < argc; i++)
16972 Jim_ListAppendElement(interp, listObjPtr, argv[i]);
16973 if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) {
16974 if (new_obj)
16975 Jim_FreeNewObj(interp, listObjPtr);
16976 return JIM_ERR;
16977 }
16978 Jim_SetResult(interp, listObjPtr);
16979 return JIM_OK;
@@ -16954,31 +17031,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 }
@@ -16989,11 +17066,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 }
@@ -17101,26 +17178,26 @@
17178 stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG);
17179 if (!stringObjPtr)
17180 return JIM_ERR;
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;
17192 stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr);
17193 }
17194 for (i = 2; i < argc; i++) {
17195 Jim_AppendObj(interp, stringObjPtr, argv[i]);
17196 }
17197 if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) {
17198 if (new_obj) {
17199 Jim_FreeNewObj(interp, stringObjPtr);
17200 }
17201 return JIM_ERR;
17202 }
17203 }
@@ -17153,11 +17230,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
@@ -17165,17 +17242,16 @@
17242 static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17243 {
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++;
@@ -17188,22 +17264,18 @@
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 {
17275 retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
17276 }
 
17277 interp->framePtr = savedCallFrame;
17278 return retcode;
17279 }
17280 else {
17281 Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?");
@@ -17294,15 +17366,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;
@@ -17319,31 +17391,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
@@ -17350,11 +17422,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 }
@@ -17408,22 +17480,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 }
@@ -17436,17 +17508,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;
@@ -17475,18 +17547,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 }
@@ -17513,11 +17585,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
@@ -17526,11 +17598,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);
@@ -17556,11 +17628,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 }
@@ -17569,17 +17641,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;
@@ -17592,15 +17664,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 }
@@ -17623,21 +17695,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) {
@@ -17650,11 +17722,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--;
@@ -17715,11 +17787,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
@@ -17734,11 +17806,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;
@@ -17747,16 +17819,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;
@@ -17767,11 +17839,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);
@@ -17881,11 +17953,10 @@
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;
@@ -17925,11 +17996,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);
@@ -18079,11 +18150,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
@@ -18090,11 +18161,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 != '-') {
@@ -18119,14 +18190,14 @@
18190 if (option < 0) {
18191 goto wrongargs;
18192 }
18193
18194 if (ignore) {
18195 ignore_mask |= ((jim_wide)1 << option);
18196 }
18197 else {
18198 ignore_mask &= (~((jim_wide)1 << option));
18199 }
18200 }
18201
18202 argc -= i;
18203 if (argc < 1 || argc > 3) {
@@ -18141,28 +18212,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);
@@ -18201,125 +18272,10 @@
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) {
@@ -18350,11 +18306,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);
@@ -18400,11 +18356,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
@@ -18524,16 +18480,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:
@@ -18550,11 +18506,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)
@@ -18620,11 +18576,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
@@ -18636,11 +18592,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;
@@ -18665,19 +18621,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
@@ -18689,15 +18647,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
@@ -18803,13 +18763,12 @@
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 }
@@ -18827,27 +18786,25 @@
18786 if (argc != 3 && argc != 4) {
18787 Jim_WrongNumArgs(interp, 2, argv, "script ?missing?");
18788 return JIM_ERR;
18789 }
18790 else {
 
 
18791 char missing;
18792
18793 Jim_SetResultBool(interp, Jim_ScriptIsComplete(interp, argv[2], &missing));
18794 if (missing != ' ' && argc == 4) {
18795 Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1));
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;
@@ -18924,11 +18881,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:
@@ -18967,11 +18924,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 {
@@ -18980,11 +18937,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;
@@ -19009,11 +18966,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 }
@@ -19043,11 +19000,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 {
@@ -19322,13 +19279,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 }
@@ -19542,11 +19499,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) {
@@ -19560,11 +19517,11 @@
19517 match = i;
19518 }
19519 }
19520 }
19521
19522
19523 if (match >= 0) {
19524 *indexPtr = match;
19525 return JIM_OK;
19526 }
19527
@@ -19597,11 +19554,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;
@@ -19662,11 +19619,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
@@ -19741,43 +19698,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;
@@ -19785,44 +19742,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 {
@@ -19873,11 +19830,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);
@@ -20064,11 +20021,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);
@@ -20091,11 +20048,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 }
@@ -20103,11 +20060,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 }
@@ -20121,11 +20078,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
@@ -20149,29 +20106,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;
@@ -20198,19 +20155,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
@@ -20224,11 +20181,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 }
@@ -20276,36 +20233,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
@@ -20318,18 +20276,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 );
@@ -20373,15 +20331,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
@@ -20388,24 +20346,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++;
@@ -20432,24 +20390,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;
@@ -20456,16 +20414,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;
@@ -20472,25 +20430,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 == ')') {
@@ -20510,11 +20468,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 != '|') {
@@ -20528,11 +20486,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
@@ -20558,11 +20516,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) {
@@ -20630,11 +20588,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)
@@ -20698,17 +20656,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;
@@ -20739,15 +20697,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);
@@ -20757,24 +20715,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 == '\\') {
@@ -20783,11 +20741,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) {
@@ -20797,35 +20755,81 @@
20755 }
20756
20757 reg_addrange(preg, start, end);
20758 continue;
20759 }
20760 if (start == '[' && pattern[0] == ':') {
20761 static const char *character_class[] = {
20762 ":alpha:", ":alnum:", ":space:", ":blank:", ":upper:", ":lower:",
20763 ":digit:", ":xdigit:", ":cntrl:", ":graph:", ":print:", ":punct:",
20764 };
20765 enum {
20766 CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER,
20767 CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT,
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');
20790 break;
20791 case CC_SPACE:
20792 reg_addrange_str(preg, " \t\r\n\f\v");
20793 break;
20794 case CC_BLANK:
20795 reg_addrange_str(preg, " \t");
20796 break;
20797 case CC_UPPER:
20798 reg_addrange(preg, 'A', 'Z');
20799 break;
20800 case CC_LOWER:
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);
20812 reg_addrange(preg, 127, 127);
20813 break;
20814 case CC_PRINT:
20815 reg_addrange(preg, ' ', '~');
20816 break;
20817 case CC_GRAPH:
20818 reg_addrange(preg, '!', '~');
20819 break;
20820 case CC_PUNCT:
20821 reg_addrange(preg, '!', '/');
20822 reg_addrange(preg, ':', '@');
20823 reg_addrange(preg, '[', '`');
20824 reg_addrange(preg, '{', '~');
20825 break;
20826 }
20827 continue;
20828 }
20829 }
20830
20831 reg_addrange(preg, start, start);
20832 }
20833 regc(preg, '\0');
20834
20835 if (*pattern) {
@@ -20844,38 +20848,47 @@
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;
20859 return 0;
20860 case '\\':
20861 ch = *preg->regparse++;
20862 switch (ch) {
20863 case '\0':
20864 preg->err = REG_ERR_TRAILING_BACKSLASH;
20865 return 0;
20866 case 'A':
20867 ret = regnode(preg, BOLX);
20868 break;
20869 case 'Z':
20870 ret = regnode(preg, EOLX);
20871 break;
20872 case '<':
20873 case 'm':
20874 ret = regnode(preg, WORDA);
20875 break;
20876 case '>':
20877 case 'M':
20878 ret = regnode(preg, WORDZ);
20879 break;
20880 case 'd':
20881 case 'D':
20882 ret = regnode(preg, ch == 'd' ? ANYOF : ANYBUT);
20883 reg_addrange(preg, '0', '9');
20884 regc(preg, '\0');
20885 *flagp |= HASWIDTH|SIMPLE;
20886 break;
20887 case 'w':
20888 case 'W':
20889 ret = regnode(preg, ch == 'w' ? ANYOF : ANYBUT);
20890 if ((preg->cflags & REG_ICASE) == 0) {
20891 reg_addrange(preg, 'a', 'z');
20892 }
20893 reg_addrange(preg, 'A', 'Z');
20894 reg_addrange(preg, '0', '9');
@@ -20882,39 +20895,40 @@
20895 reg_addrange(preg, '_', '_');
20896 regc(preg, '\0');
20897 *flagp |= HASWIDTH|SIMPLE;
20898 break;
20899 case 's':
20900 case 'S':
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;
@@ -20922,23 +20936,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');
@@ -20965,15 +20979,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 {
@@ -20983,13 +20997,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;
@@ -21001,11 +21015,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;
@@ -21021,11 +21035,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
@@ -21037,16 +21051,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
@@ -21055,51 +21069,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 }
@@ -21107,22 +21121,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;
@@ -21131,15 +21145,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;
@@ -21176,11 +21190,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 }
@@ -21188,11 +21202,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);
@@ -21232,15 +21246,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 }
@@ -21250,22 +21264,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 }
@@ -21275,13 +21289,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]--;
@@ -21290,39 +21304,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
@@ -21332,48 +21346,60 @@
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 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;
@@ -21409,12 +21435,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);
@@ -21421,11 +21447,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);
@@ -21433,11 +21459,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
@@ -21480,11 +21506,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;
@@ -21516,13 +21542,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);
@@ -21543,11 +21569,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:
@@ -21664,26 +21690,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 }
@@ -21701,11 +21727,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)
@@ -21729,11 +21755,13 @@
21755 #include <errno.h>
21756 #include <string.h>
21757
21758
21759 #ifdef USE_LINENOISE
21760 #ifdef HAVE_UNISTD_H
21761 #include <unistd.h>
21762 #endif
21763 #include "linenoise.h"
21764 #else
21765 #define MAX_LINE_LEN 512
21766 #endif
21767
@@ -21782,11 +21810,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]);
@@ -21817,32 +21845,29 @@
21845 while (1) {
21846 Jim_Obj *scriptObjPtr;
21847 const char *result;
21848 int reslen;
21849 char prompt[20];
 
21850
21851 if (retcode != JIM_OK) {
21852 const char *retcodestr = Jim_ReturnCode(retcode);
21853
21854 if (*retcodestr == '?') {
21855 snprintf(prompt, sizeof(prompt) - 3, "[%d] . ", retcode);
21856 }
21857 else {
21858 snprintf(prompt, sizeof(prompt) - 3, "[%s] . ", retcodestr);
21859 }
21860 }
21861 else {
21862 strcpy(prompt, ". ");
21863 }
 
21864
21865 scriptObjPtr = Jim_NewStringObj(interp, "", 0);
21866 Jim_IncrRefCount(scriptObjPtr);
21867 while (1) {
21868 char state;
 
21869 char *line;
21870
21871 line = Jim_HistoryGetline(prompt);
21872 if (line == NULL) {
21873 if (errno == EINTR) {
@@ -21851,26 +21876,23 @@
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))
 
 
 
 
21887 break;
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
@@ -21881,11 +21903,10 @@
21903 #endif
21904 retcode = Jim_EvalObj(interp, scriptObjPtr);
21905 Jim_DecrRefCount(interp, scriptObjPtr);
21906
21907 if (retcode == JIM_EXIT) {
 
21908 break;
21909 }
21910 if (retcode == JIM_ERR) {
21911 Jim_MakeErrorMessage(interp);
21912 }
@@ -21910,11 +21931,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 }
@@ -21926,45 +21947,71 @@
21947 static void JimPrintErrorMessage(Jim_Interp *interp)
21948 {
21949 Jim_MakeErrorMessage(interp);
21950 fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp)));
21951 }
21952
21953 void usage(const char* executable_name)
21954 {
21955 printf("jimsh version %d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100);
21956 printf("Usage: %s\n", executable_name);
21957 printf("or : %s [options] [filename]\n", executable_name);
21958 printf("\n");
21959 printf("Without options: Interactive mode\n");
21960 printf("\n");
21961 printf("Options:\n");
21962 printf(" --version : prints the version string\n");
21963 printf(" --help : prints this text\n");
21964 printf(" -e CMD : executes command CMD\n");
21965 printf(" NOTE: all subsequent options will be passed as arguments to the command\n");
21966 printf(" [filename] : executes the script contained in the named file\n");
21967 printf(" NOTE: all subsequent options will be passed to the script\n\n");
21968 }
21969
21970 int main(int argc, char *const argv[])
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
22019 DDED autosetup/pkg-config.tcl
--- a/autosetup/pkg-config.tcl
+++ b/autosetup/pkg-config.tcl
@@ -0,0 +1,70 @@
1
+# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/
2
+# All rights reserved
3
+
4
+# @synopsis:
5
+#
6
+# The 'pkg-config' module allows package ipkg-config be found via 'pkg-config'.
7
+#
8
+# If not cross-compiling, the package path should be detpkg-config.
9
+# If cross-compiling, the default package path is the compiler sysroot.
10
+# If the -print-sysroot--sysroot option or by defining SYSROOT.
11
+#
12
+# PKG_CONFIG'SYSROOT'.pkg-configlternativemodule- to 'pkg-config'.
13
+
14
+use cc
15
+
16
+options {
17
+ sysroot:dir => "Override compiler sysroot for pkg-config search path"
18
+}
19
+
20
+# @pkg-config-init ?reqpkg-config system. Unless required system. Unlthe pkg-configkg-config' is not found .
21
+#
22
+# This command will normally be called automatically as repkg-configtly if lack of 'pkpkg-configif ok, or 0 if 'pkg-config'required=0)get-define PKG_CONd' is 0).
23
+#
24
+proc pkg-config-init {{required 1}} {
25
+ if {[is-defined HAVE_PKG_CONFIG]} {
26
+ return [get-define HAVE_PKG_CONFIG]
27
+ }
28
+ set found 0
29
+
30
+ define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
31
+ msg-checking "Checking for pkg-config..."
32
+
33
+ if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
34
+ msg-result "[get-define PKG_CONFIG] (not found)"
35
+ if {$required} {
36
+ user-error "No usable pkg-config"
37
+try {
38
+ set version [ } elseif {[get-define build] nversion]ot [get-define SYSROOT]"
39
+ } elseif {[get-define build] ne [get-define host]} {
40
+ if[get-define CC] -print-sysroot} result errinfo] == 0} {
41
+ # Use the compiler sysroot, if there is one
42
+ define SYSROOT $result
43
+ msg-result "Found compiler sysroot $result"
44
+ } else {
45
+ set msg "pkg-config: Cross compiling, but no compiler sysroot and no --sysroot supplied"
46
+ if {$required} {
47
+ user-error $msg
48
+ } else {
49
+ msg-result $msg
50
+ }
51
+ set found 0
52
+ }
53
+ }
54
+ if {[is-defined SYSROOT]} {
55
+ set sysroot [get-define SYSROOT]
56
+
57
+ # XXX: It's possible that these should be set only when invoking pkg-config
58
+ global env
59
+ set env(PKG_CONFIG_DIR) ""
60
+ # (c) 2016 WorkWpkg-configvoked explicitly if lack of 'pkg-config' is acceptable.
61
+#
62
+# Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$requHAVE_king "Cheroc pkg-config-init {{requi
63
+ } on error msgON $version
64
+
65
+ set found 1
66
+
67
+ if {[opt-val f a usa] ne ""} {
68
+ defi[sg-result "Using]
69
+
70
+ 2016 WorkWare S
--- a/autosetup/pkg-config.tcl
+++ b/autosetup/pkg-config.tcl
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/autosetup/pkg-config.tcl
+++ b/autosetup/pkg-config.tcl
@@ -0,0 +1,70 @@
1 # Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/
2 # All rights reserved
3
4 # @synopsis:
5 #
6 # The 'pkg-config' module allows package ipkg-config be found via 'pkg-config'.
7 #
8 # If not cross-compiling, the package path should be detpkg-config.
9 # If cross-compiling, the default package path is the compiler sysroot.
10 # If the -print-sysroot--sysroot option or by defining SYSROOT.
11 #
12 # PKG_CONFIG'SYSROOT'.pkg-configlternativemodule- to 'pkg-config'.
13
14 use cc
15
16 options {
17 sysroot:dir => "Override compiler sysroot for pkg-config search path"
18 }
19
20 # @pkg-config-init ?reqpkg-config system. Unless required system. Unlthe pkg-configkg-config' is not found .
21 #
22 # This command will normally be called automatically as repkg-configtly if lack of 'pkpkg-configif ok, or 0 if 'pkg-config'required=0)get-define PKG_CONd' is 0).
23 #
24 proc pkg-config-init {{required 1}} {
25 if {[is-defined HAVE_PKG_CONFIG]} {
26 return [get-define HAVE_PKG_CONFIG]
27 }
28 set found 0
29
30 define PKG_CONFIG [get-env PKG_CONFIG pkg-config]
31 msg-checking "Checking for pkg-config..."
32
33 if {[catch {exec [get-define PKG_CONFIG] --version} version]} {
34 msg-result "[get-define PKG_CONFIG] (not found)"
35 if {$required} {
36 user-error "No usable pkg-config"
37 try {
38 set version [ } elseif {[get-define build] nversion]ot [get-define SYSROOT]"
39 } elseif {[get-define build] ne [get-define host]} {
40 if[get-define CC] -print-sysroot} result errinfo] == 0} {
41 # Use the compiler sysroot, if there is one
42 define SYSROOT $result
43 msg-result "Found compiler sysroot $result"
44 } else {
45 set msg "pkg-config: Cross compiling, but no compiler sysroot and no --sysroot supplied"
46 if {$required} {
47 user-error $msg
48 } else {
49 msg-result $msg
50 }
51 set found 0
52 }
53 }
54 if {[is-defined SYSROOT]} {
55 set sysroot [get-define SYSROOT]
56
57 # XXX: It's possible that these should be set only when invoking pkg-config
58 global env
59 set env(PKG_CONFIG_DIR) ""
60 # (c) 2016 WorkWpkg-configvoked explicitly if lack of 'pkg-config' is acceptable.
61 #
62 # Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$requHAVE_king "Cheroc pkg-config-init {{requi
63 } on error msgON $version
64
65 set found 1
66
67 if {[opt-val f a usa] ne ""} {
68 defi[sg-result "Using]
69
70 2016 WorkWare S
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -2,11 +2,11 @@
22
# All rights reserved
33
44
# @synopsis:
55
#
66
# This module supports common system interrogation and options
7
-# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEXT.
7
+# 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
#
1212
module-options {
@@ -104,11 +104,11 @@
104104
#
105105
# Reads the input file <srcdir>/$template and writes the output file $outfile.
106106
# If $outfile is blank/omitted, $template should end with ".in" which
107107
# is removed to create the output file name.
108108
#
109
-# Each pattern of the form @define@ is replaced the the corresponding
109
+# Each pattern of the form @define@ is replaced with the corresponding
110110
# define, if it exists, or left unchanged if not.
111111
#
112112
# The special value @srcdir@ is substituted with the relative
113113
# path to the source directory from the directory where the output
114114
# file is created, while the special value @top_srcdir@ is substituted
115115
116116
ADDED autosetup/tmake.auto
117117
ADDED autosetup/tmake.tcl
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -2,11 +2,11 @@
2 # All rights reserved
3
4 # @synopsis:
5 #
6 # This module supports common system interrogation and options
7 # such as --host, --build, --prefix, and setting srcdir, builddir, and EXEXT.
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 {
@@ -104,11 +104,11 @@
104 #
105 # Reads the input file <srcdir>/$template and writes the output file $outfile.
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 the 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
116 DDED autosetup/tmake.auto
117 DDED autosetup/tmake.tcl
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -2,11 +2,11 @@
2 # All rights reserved
3
4 # @synopsis:
5 #
6 # This module supports common system interrogation and options
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 {
@@ -104,11 +104,11 @@
104 #
105 # Reads the input file <srcdir>/$template and writes the output file $outfile.
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
116 DDED autosetup/tmake.auto
117 DDED autosetup/tmake.tcl
--- a/autosetup/tmake.auto
+++ b/autosetup/tmake.auto
@@ -0,0 +1,62 @@
1
+# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/
2
+# All rights reserved
3
+
4
+# Auto-load module for 'tmake' build system integration
5
+
6
+use init
7
+
8
+autosetup_add_init_type tmake "Tcl-based tmake build system" {
9
+ autosetup_check_create auto.def \
10
+{# Initial auto.def created by 'autosetup --init=tmake'
11
+# vim:set syntax=tcl:
12
+
13
+use cc cc-lib cc-db cc-shared
14
+use tmake
15
+
16
+# Add any user options here
17
+# Really want a --configure that takes over the rest of the command line
18
+options {
19
+}
20
+
21
+cc-check-tools ar ranlib
22
+
23
+set objdir [get-env BUILDDIR objdir]
24
+
25
+make-config-header $objdir/include/autoconf.h
26
+make-tmake-settings $objdir/settings.conf {[A-Z]*}
27
+}
28
+
29
+ autosetup_check_create }
30
+
31
+ autosetup_check_create project.spec \
32
+{# Initial project.spec created by# vim:set syntax=tcl:
33
+define? DESTDIR _install
34
+
35
+# XXX If configure creates additional/different files than include/autoconf.h
36
+# that should be reflected here
37
+
38
+# We use [set AUTOREMAKE] here to avoid rebuilding settings.conf
39
+# if the AUTOREMAKE command changes
40
+Depends {settings.conf include/autoconf.h} auto.def -msg {note Configuring...} -do {
41
+ run [set AUTOREMAKE] >$build/config.out
42
+} -onerror {puts [readfile $build/config.out]} -fatal
43
+Clean config.out
44
+DistClean --source config.log
45
+DistClean settings.conf include/autoconf.h
46
+
47
+# If not configured, configure with default options
48
+# Note that it is expected that configure will normally be run
49
+# separately. This is just a convenience for a host build
50
+define? AUTOREMAKE configure TOPBUILDDIR=$TOPBUILDDIR --conf=auto.def
51
+
52
+Load settings.conf
53
+
54
+# e.g. for up autoconf.h
55
+InclCONFIGURED
56
+
57
+# Hmmm, but should we turn off AutoSubDirs?
58
+#AutoSubDirs off
59
+}
60
+
61
+ if {![file exists build.spec]} {
62
+ puts "Note: I don't see build.spec. Try ru
--- a/autosetup/tmake.auto
+++ b/autosetup/tmake.auto
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/autosetup/tmake.auto
+++ b/autosetup/tmake.auto
@@ -0,0 +1,62 @@
1 # Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/
2 # All rights reserved
3
4 # Auto-load module for 'tmake' build system integration
5
6 use init
7
8 autosetup_add_init_type tmake "Tcl-based tmake build system" {
9 autosetup_check_create auto.def \
10 {# Initial auto.def created by 'autosetup --init=tmake'
11 # vim:set syntax=tcl:
12
13 use cc cc-lib cc-db cc-shared
14 use tmake
15
16 # Add any user options here
17 # Really want a --configure that takes over the rest of the command line
18 options {
19 }
20
21 cc-check-tools ar ranlib
22
23 set objdir [get-env BUILDDIR objdir]
24
25 make-config-header $objdir/include/autoconf.h
26 make-tmake-settings $objdir/settings.conf {[A-Z]*}
27 }
28
29 autosetup_check_create }
30
31 autosetup_check_create project.spec \
32 {# Initial project.spec created by# vim:set syntax=tcl:
33 define? DESTDIR _install
34
35 # XXX If configure creates additional/different files than include/autoconf.h
36 # that should be reflected here
37
38 # We use [set AUTOREMAKE] here to avoid rebuilding settings.conf
39 # if the AUTOREMAKE command changes
40 Depends {settings.conf include/autoconf.h} auto.def -msg {note Configuring...} -do {
41 run [set AUTOREMAKE] >$build/config.out
42 } -onerror {puts [readfile $build/config.out]} -fatal
43 Clean config.out
44 DistClean --source config.log
45 DistClean settings.conf include/autoconf.h
46
47 # If not configured, configure with default options
48 # Note that it is expected that configure will normally be run
49 # separately. This is just a convenience for a host build
50 define? AUTOREMAKE configure TOPBUILDDIR=$TOPBUILDDIR --conf=auto.def
51
52 Load settings.conf
53
54 # e.g. for up autoconf.h
55 InclCONFIGURED
56
57 # Hmmm, but should we turn off AutoSubDirs?
58 #AutoSubDirs off
59 }
60
61 if {![file exists build.spec]} {
62 puts "Note: I don't see build.spec. Try ru
--- a/autosetup/tmake.tcl
+++ b/autosetup/tmake.tcl
@@ -0,0 +1,27 @@
1
+"*")
2
+# and writes a tmake-compatible .conf file defining those variables.
3
+# For example, if ABC is "3 monkeys" and ABC is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include:
4
+#
5
+## define ABC {3 monkeys}
6
+#
7
+# If the file would be unchanged, it is not written make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*}
8
+proc make-tmake-settings {file args} {
9
+ file mkdir [file dirname $file]
10
+ set lines {}
11
+
12
+ if {[llength $args] == 0} {
13
+ set args *
14
+ }
15
+
16
+ foreach n [lsort [dict keys [all-defines]]] {
17
+ foreach p $args {
18
+ if {[string match $p $n]} {
19
+ set value [get-define $n]
20
+ lappend lines "define $n [list $value]"
21
+ break
22
+ }
23
+ }
24
+ }
25
+ set buf [join $lines \n]
26
+ write-if-changed $file $buf {
27
+ msg-r
--- a/autosetup/tmake.tcl
+++ b/autosetup/tmake.tcl
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/autosetup/tmake.tcl
+++ b/autosetup/tmake.tcl
@@ -0,0 +1,27 @@
1 "*")
2 # and writes a tmake-compatible .conf file defining those variables.
3 # For example, if ABC is "3 monkeys" and ABC is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include:
4 #
5 ## define ABC {3 monkeys}
6 #
7 # If the file would be unchanged, it is not written make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*}
8 proc make-tmake-settings {file args} {
9 file mkdir [file dirname $file]
10 set lines {}
11
12 if {[llength $args] == 0} {
13 set args *
14 }
15
16 foreach n [lsort [dict keys [all-defines]]] {
17 foreach p $args {
18 if {[string match $p $n]} {
19 set value [get-define $n]
20 lappend lines "define $n [list $value]"
21 break
22 }
23 }
24 }
25 set buf [join $lines \n]
26 write-if-changed $file $buf {
27 msg-r

Keyboard Shortcuts

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