Fossil SCM

Merge in autosetup update.

drh 2013-04-01 11:26 trunk merge
Commit 63daf1453c8617c3e84ddf0513e3ac92ca377dce
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1
-This is autosetup v0.6.4. See http://msteveb.github.com/autosetup/
1
+This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/
22
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1 This is autosetup v0.6.4. See http://msteveb.github.com/autosetup/
2
--- autosetup/README.autosetup
+++ autosetup/README.autosetup
@@ -1,1 +1,1 @@
1 This is autosetup v0.6.5. See http://msteveb.github.com/autosetup/
2
+192 -114
--- 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.4
8
+set autosetup(version) 0.6.5
99
1010
# Can be set to 1 to debug early-init problems
1111
set autosetup(debug) 0
1212
1313
##################################################################
@@ -85,11 +85,11 @@
8585
version => "display the version of autosetup"
8686
ref:=text manual:=text
8787
reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'"
8888
debug => "display debugging output as autosetup runs"
8989
install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)"
90
- force init => "create an initial 'configure' script if none exists"
90
+ force init:=help => "create initial auto.def, etc. Use --init=help for known types"
9191
# Undocumented options
9292
option-checking=1
9393
nopager
9494
quiet
9595
timing
@@ -116,10 +116,15 @@
116116
# If the local module exists, source it now to allow for
117117
# project-local customisations
118118
if {[file exists $autosetup(libdir)/local.tcl]} {
119119
use local
120120
}
121
+
122
+ # Now any auto-load modules
123
+ foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] {
124
+ automf_load source $file
125
+ }
121126
122127
if {[opt-val help] ne ""} {
123128
incr autosetup(showhelp)
124129
use help
125130
autosetup_help [opt-val help]
@@ -128,13 +133,13 @@
128133
if {[opt-val {manual ref reference}] ne ""} {
129134
use help
130135
autosetup_reference [opt-val {manual ref reference}]
131136
}
132137
133
- if {[opt-bool init]} {
138
+ if {[opt-val init] ne ""} {
134139
use init
135
- autosetup_init
140
+ autosetup_init [opt-val init]
136141
}
137142
138143
if {[opt-val install] ne ""} {
139144
use install
140145
autosetup_install [opt-val install]
@@ -141,11 +146,11 @@
141146
}
142147
143148
if {![file exists $autosetup(autodef)]} {
144149
# Check for invalid option first
145150
options {}
146
- user-error "No auto.def found in $autosetup(srcdir)"
151
+ user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)"
147152
}
148153
149154
# Parse extra arguments into autosetup(cmdline)
150155
foreach arg $argv {
151156
if {[regexp {([^=]*)=(.*)} $arg -> n v]} {
@@ -165,18 +170,23 @@
165170
define AUTOREMAKE $cmd
166171
167172
# Log how we were invoked
168173
configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
169174
175
+ # Note that auto.def is *not* loaded in the global scope
170176
source $autosetup(autodef)
171177
172178
# Could warn here if options {} was not specified
173179
174180
show-notices
175181
176182
if {$autosetup(debug)} {
177
- parray define
183
+ msg-result "Writing all defines to config.log"
184
+ configlog "================ defines ======================"
185
+ foreach n [lsort [array names define]] {
186
+ configlog "define $n $define($n)"
187
+ }
178188
}
179189
180190
exit 0
181191
}
182192
@@ -419,22 +429,27 @@
419429
}
420430
421431
proc config_guess {} {
422432
if {[file-isexec $::autosetup(dir)/config.guess]} {
423433
exec-with-stderr sh $::autosetup(dir)/config.guess
434
+ if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} {
435
+ user-error $alias
436
+ }
437
+ return $alias
424438
} else {
425439
configlog "No config.guess, so using uname"
426440
string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r]
427441
}
428442
}
429443
430444
proc config_sub {alias} {
431445
if {[file-isexec $::autosetup(dir)/config.sub]} {
432
- exec-with-stderr sh $::autosetup(dir)/config.sub $alias
433
- } else {
434
- return $alias
446
+ if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} {
447
+ user-error $alias
448
+ }
435449
}
450
+ return $alias
436451
}
437452
438453
# @define name ?value=1?
439454
#
440455
# Defines the named variable to the given value.
@@ -752,12 +767,17 @@
752767
lappend ::autosetup(notices) $msg
753768
}
754769
755770
# Incorrect usage in the auto.def file. Identify the location.
756771
proc autosetup-error {msg} {
772
+ autosetup-full-error [error-location $msg]
773
+}
774
+
775
+# Like autosetup-error, except $msg is the full error message.
776
+proc autosetup-full-error {msg} {
757777
show-notices
758
- puts stderr [error-location $msg]
778
+ puts stderr $msg
759779
exit 1
760780
}
761781
762782
proc show-notices {} {
763783
if {$::autosetup(msg-checking)} {
@@ -863,32 +883,55 @@
863883
#
864884
865885
# @use module ...
866886
#
867887
# Load the given library modules.
868
-# e.g. use cc cc-shared
888
+# e.g. 'use cc cc-shared'
889
+#
890
+# Note that module 'X' is implemented in either 'autosetup/X.tcl'
891
+# or 'autosetup/X/init.tcl'
892
+#
893
+# The latter form is useful for a complex module which requires additional
894
+# support file. In this form, '$::usedir' is set to the module directory
895
+# when it is loaded.
869896
#
870897
proc use {args} {
871898
foreach m $args {
872899
if {[info exists ::libmodule($m)]} {
873900
continue
874901
}
875902
set ::libmodule($m) 1
876903
if {[info exists ::modsource($m)]} {
877
- uplevel #0 eval $::modsource($m)
904
+ automf_load eval $::modsource($m)
878905
} else {
879
- set source $::autosetup(libdir)/${m}.tcl
880
- if {[file exists $source]} {
881
- uplevel #0 [list source $source]
906
+ set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl]
907
+ set found 0
908
+ foreach source $sources {
909
+ if {[file exists $source]} {
910
+ incr found
911
+ break
912
+ }
913
+ }
914
+ if {$found} {
915
+ # For the convenience of the "use" source, point to the directory
916
+ # it is being loaded from
917
+ set ::usedir [file dirname $source]
918
+ automf_load source $source
882919
autosetup_add_dep $source
883920
} else {
884
- puts "Looking for $source"
885921
autosetup-error "use: No such module: $m"
886922
}
887923
}
888924
}
889925
}
926
+
927
+# Load module source in the global scope by executing the given command
928
+proc automf_load {args} {
929
+ if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} {
930
+ autosetup-full-error [error-dump $msg $opts]
931
+ }
932
+}
890933
891934
# Initial settings
892935
set autosetup(exe) $::argv0
893936
set autosetup(istcl) 1
894937
set autosetup(start) [clock millis]
@@ -1144,13 +1187,13 @@
11441187
}
11451188
11461189
# If not already paged and stdout is a tty, pipe the output through the pager
11471190
# This is done by reinvoking autosetup with --nopager added
11481191
proc use_pager {} {
1149
- if {![opt-bool nopager] && [getenv PAGER ""] ne "" && ![string match "not a tty" [exec tty]]} {
1192
+ if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} {
11501193
catch {
1151
- exec [info nameofexecutable] $::argv0 --nopager {*}$::argv | [getenv PAGER] >@stdout <@stdin 2>/dev/null
1194
+ exec [info nameofexecutable] $::argv0 --nopager {*}$::argv |& [getenv PAGER] >@stdout <@stdin
11521195
}
11531196
exit 0
11541197
}
11551198
}
11561199
@@ -1276,59 +1319,60 @@
12761319
# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
12771320
# All rights reserved
12781321
12791322
# Module to help create auto.def and configure
12801323
1281
-proc autosetup_init {} {
1282
- set create_configure 1
1283
- if {[file exists configure]} {
1284
- if {!$::autosetup(force)} {
1285
- # Could this be an autosetup configure?
1286
- if {![string match "*\nWRAPPER=*" [readfile configure]]} {
1287
- puts "I see configure, but not created by autosetup, so I won't overwrite it."
1288
- puts "Use autosetup --init --force to overwrite."
1289
- set create_configure 0
1290
- }
1291
- } else {
1292
- puts "I will overwrite the existing configure because you used --force."
1293
- }
1294
- } else {
1295
- puts "I don't see configure, so I will create it."
1296
- }
1297
- if {$create_configure} {
1298
- if {!$::autosetup(installed)} {
1299
- user-notice "Warning: Initialising from the development version of autosetup"
1300
-
1301
- writefile configure "#!/bin/sh\nWRAPPER=\"\$0\"; export WRAPPER; exec $::autosetup(dir)/autosetup \"\$@\"\n"
1302
- } else {
1303
- writefile configure \
1304
-{#!/bin/sh
1305
-dir="`dirname "$0"`/autosetup"
1306
-WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
1307
-}
1308
- }
1309
- catch {exec chmod 755 configure}
1310
- }
1311
- if {![file exists auto.def]} {
1312
- puts "I don't see auto.def, so I will create a default one."
1313
- writefile auto.def {# Initial auto.def created by 'autosetup --init'
1314
-
1315
-use cc
1316
-
1317
-# Add any user options here
1318
-options {
1319
-}
1320
-
1321
-make-config-header config.h
1322
-make-template Makefile.in
1323
-}
1324
- }
1325
- if {![file exists Makefile.in]} {
1326
- puts "Note: I don't see Makefile.in. You will probably need to create one."
1327
- }
1328
-
1329
- exit 0
1324
+proc autosetup_init {type} {
1325
+ set help 0
1326
+ if {$type in {? help}} {
1327
+ incr help
1328
+ } elseif {![dict exists $::autosetup(inittypes) $type]} {
1329
+ puts "Unknown type, --init=$type"
1330
+ incr help
1331
+ }
1332
+ if {$help} {
1333
+ puts "Use one of the following types (e.g. --init=make)\n"
1334
+ foreach type [lsort [dict keys $::autosetup(inittypes)]] {
1335
+ lassign [dict get $::autosetup(inittypes) $type] desc
1336
+ # XXX: Use the options-show code to wrap the description
1337
+ puts [format "%-10s %s" $type $desc]
1338
+ }
1339
+ exit 0
1340
+ }
1341
+ lassign [dict get $::autosetup(inittypes) $type] desc script
1342
+
1343
+ puts "Initialising $type: $desc\n"
1344
+
1345
+ # All initialisations happens in the top level srcdir
1346
+ cd $::autosetup(srcdir)
1347
+
1348
+ uplevel #0 $script
1349
+
1350
+ exit 0
1351
+}
1352
+
1353
+proc autosetup_add_init_type {type desc script} {
1354
+ dict set ::autosetup(inittypes) $type [list $desc $script]
1355
+}
1356
+
1357
+# This is for in creating build-system init scripts
1358
+#
1359
+# If the file doesn't exist, create it containing $contents
1360
+# If the file does exist, only overwrite if --force is specified.
1361
+#
1362
+proc autosetup_check_create {filename contents} {
1363
+ if {[file exists $filename]} {
1364
+ if {!$::autosetup(force)} {
1365
+ puts "I see $filename already exists."
1366
+ return
1367
+ } else {
1368
+ puts "I will overwrite the existing $filename because you used --force."
1369
+ }
1370
+ } else {
1371
+ puts "I don't see $filename, so I will create it."
1372
+ }
1373
+ writefile $filename $contents
13301374
}
13311375
}
13321376
13331377
# ----- module install -----
13341378
@@ -1343,11 +1387,11 @@
13431387
cd $dir
13441388
file mkdir autosetup
13451389
13461390
set f [open autosetup/autosetup w]
13471391
1348
- set publicmodules {}
1392
+ set publicmodules $::autosetup(libdir)/default.auto
13491393
13501394
# First the main script, but only up until "CUT HERE"
13511395
set in [open $::autosetup(dir)/autosetup]
13521396
while {[gets $in buf] >= 0} {
13531397
if {$buf ne "##-- CUT HERE --##"} {
@@ -1391,14 +1435,39 @@
13911435
13921436
} error]} {
13931437
user-error "Failed to install autosetup: $error"
13941438
}
13951439
puts "Installed [autosetup_version] to autosetup/"
1396
- catch {exec [info nameofexecutable] autosetup/autosetup --init >@stdout 2>@stderr}
1440
+
1441
+ # Now create 'configure' if necessary
1442
+ autosetup_create_configure
13971443
13981444
exit 0
13991445
}
1446
+
1447
+proc autosetup_create_configure {} {
1448
+ if {[file exists configure]} {
1449
+ if {!$::autosetup(force)} {
1450
+ # Could this be an autosetup configure?
1451
+ if {![string match "*\nWRAPPER=*" [readfile configure]]} {
1452
+ puts "I see configure, but not created by autosetup, so I won't overwrite it."
1453
+ puts "Remove it or use --force to overwrite."
1454
+ return
1455
+ }
1456
+ } else {
1457
+ puts "I will overwrite the existing configure because you used --force."
1458
+ }
1459
+ } else {
1460
+ puts "I don't see configure, so I will create it."
1461
+ }
1462
+ writefile configure \
1463
+{#!/bin/sh
1464
+dir="`dirname "$0"`/autosetup"
1465
+WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
1466
+}
1467
+ catch {exec chmod 755 configure}
1468
+}
14001469
14011470
# Append the contents of $file to filehandle $f
14021471
proc autosetup_install_append {f file} {
14031472
set in [open $file]
14041473
puts $f [read $in]
@@ -1539,19 +1608,32 @@
15391608
if {[llength $args]} {
15401609
return [lindex $args 0]
15411610
}
15421611
return -code error "environment variable \"$name\" does not exist"
15431612
}
1544
-} elseif {$autosetup(iswin)} {
1545
- # On Windows, backslash convert all environment variables
1546
- # (Assume that Tcl does this for us)
1547
- proc getenv {name args} {
1548
- string map {\\ /} [env $name {*}$args]
1613
+ proc isatty? {channel} {
1614
+ dict exists [fconfigure $channel] -xchar
15491615
}
15501616
} else {
1551
- # Jim on unix is simple
1552
- alias getenv env
1617
+ if {$autosetup(iswin)} {
1618
+ # On Windows, backslash convert all environment variables
1619
+ # (Assume that Tcl does this for us)
1620
+ proc getenv {name args} {
1621
+ string map {\\ /} [env $name {*}$args]
1622
+ }
1623
+ } else {
1624
+ # Jim on unix is simple
1625
+ alias getenv env
1626
+ }
1627
+ proc isatty? {channel} {
1628
+ set tty 0
1629
+ catch {
1630
+ # isatty is a recent addition to Jim Tcl
1631
+ set tty [$channel isatty]
1632
+ }
1633
+ return $tty
1634
+ }
15531635
}
15541636
15551637
# In case 'file normalize' doesn't exist
15561638
#
15571639
proc file-normalize {path} {
@@ -1596,50 +1678,46 @@
15961678
#puts "Skipping $info(file):$info(line)"
15971679
}
15981680
return $msg
15991681
}
16001682
1601
-# Similar to error-location, but called when user code generates an error
1602
-# In this case we want to show the stack trace in user code, but not in autosetup code
1603
-# (unless --debug is enabled)
1683
+# If everything is working properly, the only errors which occur
1684
+# should be generated in user code (e.g. auto.def).
1685
+# By default, we only want to show the error location in user code.
1686
+# We use [info frame] to achieve this, but it works differently on Tcl and Jim.
1687
+#
1688
+# This is designed to be called for incorrect usage in auto.def, via autosetup-error
16041689
#
16051690
proc error-stacktrace {msg} {
1606
- if {$::autosetup(istcl)} {
1607
- if {[regexp {file "([^ ]*)" line ([0-9]*)} $::errorInfo dummy file line]} {
1608
- return "[relative-path $file]:$line $msg\n$::errorInfo"
1609
- }
1610
- return $::errorInfo
1611
- } else {
1612
- # Prepend a live stacktrace to the error stacktrace, omitting the current level
1613
- set stacktrace [concat [info stacktrace] [lrange [stacktrace] 3 end]]
1614
-
1615
- if {!$::autosetup(debug)} {
1616
- # Omit any levels from autosetup or with no file
1617
- set newstacktrace {}
1618
- foreach {p f l} $stacktrace {
1619
- if {[string match "*autosetup" $f] || $f eq ""} {
1620
- #puts "Skipping $p $f:$l"
1621
- continue
1622
- }
1623
- lappend newstacktrace $p $f $l
1624
- }
1625
- set stacktrace $newstacktrace
1626
- }
1627
-
1628
- # Convert filenames to relative paths
1629
- set newstacktrace {}
1630
- foreach {p f l} $stacktrace {
1631
- lappend newstacktrace $p [relative-path $f] $l
1632
- }
1633
- lassign $newstacktrace p f l
1634
- if {$f ne ""} {
1635
- set prefix "$f:$l: "
1636
- } else {
1637
- set prefix ""
1638
- }
1639
-
1640
- return "${prefix}Error: $msg\n[stackdump $newstacktrace]"
1691
+ if {$::autosetup(debug)} {
1692
+ return -code error $msg
1693
+ }
1694
+ # Search back through the stack trace for the first error in a .def file
1695
+ for {set i 1} {$i < [info level]} {incr i} {
1696
+ if {$::autosetup(istcl)} {
1697
+ array set info [info frame -$i]
1698
+ } else {
1699
+ lassign [info frame -$i] info(caller) info(file) info(line)
1700
+ }
1701
+ if {[string match *.def $info(file)]} {
1702
+ return "[relative-path $info(file)]:$info(line): Error: $msg"
1703
+ }
1704
+ #puts "Skipping $info(file):$info(line)"
1705
+ }
1706
+ return $msg
1707
+}
1708
+
1709
+# Given the return from [catch {...} msg opts], returns an appropriate
1710
+# error message. A nice one for Jim and a less-nice one for Tcl.
1711
+#
1712
+# This is designed for developer errors, e.g. in module code
1713
+#
1714
+proc error-dump {msg opts} {
1715
+ if {$::autosetup(istcl)} {
1716
+ return "Error: [dict get $opts -errorinfo]"
1717
+ } else {
1718
+ return "Error: $msg\n[stackdump $opts(-errorinfo)]"
16411719
}
16421720
}
16431721
}
16441722
16451723
# ----- module text-formatting -----
16461724
--- 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.4
9
10 # Can be set to 1 to debug early-init problems
11 set autosetup(debug) 0
12
13 ##################################################################
@@ -85,11 +85,11 @@
85 version => "display the version of autosetup"
86 ref:=text manual:=text
87 reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'"
88 debug => "display debugging output as autosetup runs"
89 install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)"
90 force init => "create an initial 'configure' script if none exists"
91 # Undocumented options
92 option-checking=1
93 nopager
94 quiet
95 timing
@@ -116,10 +116,15 @@
116 # If the local module exists, source it now to allow for
117 # project-local customisations
118 if {[file exists $autosetup(libdir)/local.tcl]} {
119 use local
120 }
 
 
 
 
 
121
122 if {[opt-val help] ne ""} {
123 incr autosetup(showhelp)
124 use help
125 autosetup_help [opt-val help]
@@ -128,13 +133,13 @@
128 if {[opt-val {manual ref reference}] ne ""} {
129 use help
130 autosetup_reference [opt-val {manual ref reference}]
131 }
132
133 if {[opt-bool init]} {
134 use init
135 autosetup_init
136 }
137
138 if {[opt-val install] ne ""} {
139 use install
140 autosetup_install [opt-val install]
@@ -141,11 +146,11 @@
141 }
142
143 if {![file exists $autosetup(autodef)]} {
144 # Check for invalid option first
145 options {}
146 user-error "No auto.def found in $autosetup(srcdir)"
147 }
148
149 # Parse extra arguments into autosetup(cmdline)
150 foreach arg $argv {
151 if {[regexp {([^=]*)=(.*)} $arg -> n v]} {
@@ -165,18 +170,23 @@
165 define AUTOREMAKE $cmd
166
167 # Log how we were invoked
168 configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]"
169
 
170 source $autosetup(autodef)
171
172 # Could warn here if options {} was not specified
173
174 show-notices
175
176 if {$autosetup(debug)} {
177 parray define
 
 
 
 
178 }
179
180 exit 0
181 }
182
@@ -419,22 +429,27 @@
419 }
420
421 proc config_guess {} {
422 if {[file-isexec $::autosetup(dir)/config.guess]} {
423 exec-with-stderr sh $::autosetup(dir)/config.guess
 
 
 
 
424 } else {
425 configlog "No config.guess, so using uname"
426 string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r]
427 }
428 }
429
430 proc config_sub {alias} {
431 if {[file-isexec $::autosetup(dir)/config.sub]} {
432 exec-with-stderr sh $::autosetup(dir)/config.sub $alias
433 } else {
434 return $alias
435 }
 
436 }
437
438 # @define name ?value=1?
439 #
440 # Defines the named variable to the given value.
@@ -752,12 +767,17 @@
752 lappend ::autosetup(notices) $msg
753 }
754
755 # Incorrect usage in the auto.def file. Identify the location.
756 proc autosetup-error {msg} {
 
 
 
 
 
757 show-notices
758 puts stderr [error-location $msg]
759 exit 1
760 }
761
762 proc show-notices {} {
763 if {$::autosetup(msg-checking)} {
@@ -863,32 +883,55 @@
863 #
864
865 # @use module ...
866 #
867 # Load the given library modules.
868 # e.g. use cc cc-shared
 
 
 
 
 
 
 
869 #
870 proc use {args} {
871 foreach m $args {
872 if {[info exists ::libmodule($m)]} {
873 continue
874 }
875 set ::libmodule($m) 1
876 if {[info exists ::modsource($m)]} {
877 uplevel #0 eval $::modsource($m)
878 } else {
879 set source $::autosetup(libdir)/${m}.tcl
880 if {[file exists $source]} {
881 uplevel #0 [list source $source]
 
 
 
 
 
 
 
 
 
 
882 autosetup_add_dep $source
883 } else {
884 puts "Looking for $source"
885 autosetup-error "use: No such module: $m"
886 }
887 }
888 }
889 }
 
 
 
 
 
 
 
890
891 # Initial settings
892 set autosetup(exe) $::argv0
893 set autosetup(istcl) 1
894 set autosetup(start) [clock millis]
@@ -1144,13 +1187,13 @@
1144 }
1145
1146 # If not already paged and stdout is a tty, pipe the output through the pager
1147 # This is done by reinvoking autosetup with --nopager added
1148 proc use_pager {} {
1149 if {![opt-bool nopager] && [getenv PAGER ""] ne "" && ![string match "not a tty" [exec tty]]} {
1150 catch {
1151 exec [info nameofexecutable] $::argv0 --nopager {*}$::argv | [getenv PAGER] >@stdout <@stdin 2>/dev/null
1152 }
1153 exit 0
1154 }
1155 }
1156
@@ -1276,59 +1319,60 @@
1276 # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
1277 # All rights reserved
1278
1279 # Module to help create auto.def and configure
1280
1281 proc autosetup_init {} {
1282 set create_configure 1
1283 if {[file exists configure]} {
1284 if {!$::autosetup(force)} {
1285 # Could this be an autosetup configure?
1286 if {![string match "*\nWRAPPER=*" [readfile configure]]} {
1287 puts "I see configure, but not created by autosetup, so I won't overwrite it."
1288 puts "Use autosetup --init --force to overwrite."
1289 set create_configure 0
1290 }
1291 } else {
1292 puts "I will overwrite the existing configure because you used --force."
1293 }
1294 } else {
1295 puts "I don't see configure, so I will create it."
1296 }
1297 if {$create_configure} {
1298 if {!$::autosetup(installed)} {
1299 user-notice "Warning: Initialising from the development version of autosetup"
1300
1301 writefile configure "#!/bin/sh\nWRAPPER=\"\$0\"; export WRAPPER; exec $::autosetup(dir)/autosetup \"\$@\"\n"
1302 } else {
1303 writefile configure \
1304 {#!/bin/sh
1305 dir="`dirname "$0"`/autosetup"
1306 WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
1307 }
1308 }
1309 catch {exec chmod 755 configure}
1310 }
1311 if {![file exists auto.def]} {
1312 puts "I don't see auto.def, so I will create a default one."
1313 writefile auto.def {# Initial auto.def created by 'autosetup --init'
1314
1315 use cc
1316
1317 # Add any user options here
1318 options {
1319 }
1320
1321 make-config-header config.h
1322 make-template Makefile.in
1323 }
1324 }
1325 if {![file exists Makefile.in]} {
1326 puts "Note: I don't see Makefile.in. You will probably need to create one."
1327 }
1328
1329 exit 0
 
1330 }
1331 }
1332
1333 # ----- module install -----
1334
@@ -1343,11 +1387,11 @@
1343 cd $dir
1344 file mkdir autosetup
1345
1346 set f [open autosetup/autosetup w]
1347
1348 set publicmodules {}
1349
1350 # First the main script, but only up until "CUT HERE"
1351 set in [open $::autosetup(dir)/autosetup]
1352 while {[gets $in buf] >= 0} {
1353 if {$buf ne "##-- CUT HERE --##"} {
@@ -1391,14 +1435,39 @@
1391
1392 } error]} {
1393 user-error "Failed to install autosetup: $error"
1394 }
1395 puts "Installed [autosetup_version] to autosetup/"
1396 catch {exec [info nameofexecutable] autosetup/autosetup --init >@stdout 2>@stderr}
 
 
1397
1398 exit 0
1399 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1400
1401 # Append the contents of $file to filehandle $f
1402 proc autosetup_install_append {f file} {
1403 set in [open $file]
1404 puts $f [read $in]
@@ -1539,19 +1608,32 @@
1539 if {[llength $args]} {
1540 return [lindex $args 0]
1541 }
1542 return -code error "environment variable \"$name\" does not exist"
1543 }
1544 } elseif {$autosetup(iswin)} {
1545 # On Windows, backslash convert all environment variables
1546 # (Assume that Tcl does this for us)
1547 proc getenv {name args} {
1548 string map {\\ /} [env $name {*}$args]
1549 }
1550 } else {
1551 # Jim on unix is simple
1552 alias getenv env
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1553 }
1554
1555 # In case 'file normalize' doesn't exist
1556 #
1557 proc file-normalize {path} {
@@ -1596,50 +1678,46 @@
1596 #puts "Skipping $info(file):$info(line)"
1597 }
1598 return $msg
1599 }
1600
1601 # Similar to error-location, but called when user code generates an error
1602 # In this case we want to show the stack trace in user code, but not in autosetup code
1603 # (unless --debug is enabled)
 
 
 
1604 #
1605 proc error-stacktrace {msg} {
1606 if {$::autosetup(istcl)} {
1607 if {[regexp {file "([^ ]*)" line ([0-9]*)} $::errorInfo dummy file line]} {
1608 return "[relative-path $file]:$line $msg\n$::errorInfo"
1609 }
1610 return $::errorInfo
1611 } else {
1612 # Prepend a live stacktrace to the error stacktrace, omitting the current level
1613 set stacktrace [concat [info stacktrace] [lrange [stacktrace] 3 end]]
1614
1615 if {!$::autosetup(debug)} {
1616 # Omit any levels from autosetup or with no file
1617 set newstacktrace {}
1618 foreach {p f l} $stacktrace {
1619 if {[string match "*autosetup" $f] || $f eq ""} {
1620 #puts "Skipping $p $f:$l"
1621 continue
1622 }
1623 lappend newstacktrace $p $f $l
1624 }
1625 set stacktrace $newstacktrace
1626 }
1627
1628 # Convert filenames to relative paths
1629 set newstacktrace {}
1630 foreach {p f l} $stacktrace {
1631 lappend newstacktrace $p [relative-path $f] $l
1632 }
1633 lassign $newstacktrace p f l
1634 if {$f ne ""} {
1635 set prefix "$f:$l: "
1636 } else {
1637 set prefix ""
1638 }
1639
1640 return "${prefix}Error: $msg\n[stackdump $newstacktrace]"
1641 }
1642 }
1643 }
1644
1645 # ----- module text-formatting -----
1646
--- 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 ##################################################################
@@ -85,11 +85,11 @@
85 version => "display the version of autosetup"
86 ref:=text manual:=text
87 reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'"
88 debug => "display debugging output as autosetup runs"
89 install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)"
90 force init:=help => "create initial auto.def, etc. Use --init=help for known types"
91 # Undocumented options
92 option-checking=1
93 nopager
94 quiet
95 timing
@@ -116,10 +116,15 @@
116 # If the local module exists, source it now to allow for
117 # project-local customisations
118 if {[file exists $autosetup(libdir)/local.tcl]} {
119 use local
120 }
121
122 # Now any auto-load modules
123 foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] {
124 automf_load source $file
125 }
126
127 if {[opt-val help] ne ""} {
128 incr autosetup(showhelp)
129 use help
130 autosetup_help [opt-val help]
@@ -128,13 +133,13 @@
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]
@@ -141,11 +146,11 @@
146 }
147
148 if {![file exists $autosetup(autodef)]} {
149 # Check for invalid option first
150 options {}
151 user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)"
152 }
153
154 # Parse extra arguments into autosetup(cmdline)
155 foreach arg $argv {
156 if {[regexp {([^=]*)=(.*)} $arg -> n v]} {
@@ -165,18 +170,23 @@
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
176 source $autosetup(autodef)
177
178 # Could warn here if options {} was not specified
179
180 show-notices
181
182 if {$autosetup(debug)} {
183 msg-result "Writing all defines to config.log"
184 configlog "================ defines ======================"
185 foreach n [lsort [array names define]] {
186 configlog "define $n $define($n)"
187 }
188 }
189
190 exit 0
191 }
192
@@ -419,22 +429,27 @@
429 }
430
431 proc config_guess {} {
432 if {[file-isexec $::autosetup(dir)/config.guess]} {
433 exec-with-stderr sh $::autosetup(dir)/config.guess
434 if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} {
435 user-error $alias
436 }
437 return $alias
438 } else {
439 configlog "No config.guess, so using uname"
440 string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r]
441 }
442 }
443
444 proc config_sub {alias} {
445 if {[file-isexec $::autosetup(dir)/config.sub]} {
446 if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} {
447 user-error $alias
448 }
449 }
450 return $alias
451 }
452
453 # @define name ?value=1?
454 #
455 # Defines the named variable to the given value.
@@ -752,12 +767,17 @@
767 lappend ::autosetup(notices) $msg
768 }
769
770 # Incorrect usage in the auto.def file. Identify the location.
771 proc autosetup-error {msg} {
772 autosetup-full-error [error-location $msg]
773 }
774
775 # Like autosetup-error, except $msg is the full error message.
776 proc autosetup-full-error {msg} {
777 show-notices
778 puts stderr $msg
779 exit 1
780 }
781
782 proc show-notices {} {
783 if {$::autosetup(msg-checking)} {
@@ -863,32 +883,55 @@
883 #
884
885 # @use module ...
886 #
887 # Load the given library modules.
888 # e.g. 'use cc cc-shared'
889 #
890 # Note that module 'X' is implemented in either 'autosetup/X.tcl'
891 # or 'autosetup/X/init.tcl'
892 #
893 # The latter form is useful for a complex module which requires additional
894 # support file. In this form, '$::usedir' is set to the module directory
895 # when it is loaded.
896 #
897 proc use {args} {
898 foreach m $args {
899 if {[info exists ::libmodule($m)]} {
900 continue
901 }
902 set ::libmodule($m) 1
903 if {[info exists ::modsource($m)]} {
904 automf_load eval $::modsource($m)
905 } else {
906 set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl]
907 set found 0
908 foreach source $sources {
909 if {[file exists $source]} {
910 incr found
911 break
912 }
913 }
914 if {$found} {
915 # For the convenience of the "use" source, point to the directory
916 # it is being loaded from
917 set ::usedir [file dirname $source]
918 automf_load source $source
919 autosetup_add_dep $source
920 } else {
 
921 autosetup-error "use: No such module: $m"
922 }
923 }
924 }
925 }
926
927 # Load module source in the global scope by executing the given command
928 proc automf_load {args} {
929 if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} {
930 autosetup-full-error [error-dump $msg $opts]
931 }
932 }
933
934 # Initial settings
935 set autosetup(exe) $::argv0
936 set autosetup(istcl) 1
937 set autosetup(start) [clock millis]
@@ -1144,13 +1187,13 @@
1187 }
1188
1189 # If not already paged and stdout is a tty, pipe the output through the pager
1190 # This is done by reinvoking autosetup with --nopager added
1191 proc use_pager {} {
1192 if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} {
1193 catch {
1194 exec [info nameofexecutable] $::argv0 --nopager {*}$::argv |& [getenv PAGER] >@stdout <@stdin
1195 }
1196 exit 0
1197 }
1198 }
1199
@@ -1276,59 +1319,60 @@
1319 # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
1320 # All rights reserved
1321
1322 # Module to help create auto.def and configure
1323
1324 proc autosetup_init {type} {
1325 set help 0
1326 if {$type in {? help}} {
1327 incr help
1328 } elseif {![dict exists $::autosetup(inittypes) $type]} {
1329 puts "Unknown type, --init=$type"
1330 incr help
1331 }
1332 if {$help} {
1333 puts "Use one of the following types (e.g. --init=make)\n"
1334 foreach type [lsort [dict keys $::autosetup(inittypes)]] {
1335 lassign [dict get $::autosetup(inittypes) $type] desc
1336 # XXX: Use the options-show code to wrap the description
1337 puts [format "%-10s %s" $type $desc]
1338 }
1339 exit 0
1340 }
1341 lassign [dict get $::autosetup(inittypes) $type] desc script
1342
1343 puts "Initialising $type: $desc\n"
1344
1345 # All initialisations happens in the top level srcdir
1346 cd $::autosetup(srcdir)
1347
1348 uplevel #0 $script
1349
1350 exit 0
1351 }
1352
1353 proc autosetup_add_init_type {type desc script} {
1354 dict set ::autosetup(inittypes) $type [list $desc $script]
1355 }
1356
1357 # This is for in creating build-system init scripts
1358 #
1359 # If the file doesn't exist, create it containing $contents
1360 # If the file does exist, only overwrite if --force is specified.
1361 #
1362 proc autosetup_check_create {filename contents} {
1363 if {[file exists $filename]} {
1364 if {!$::autosetup(force)} {
1365 puts "I see $filename already exists."
1366 return
1367 } else {
1368 puts "I will overwrite the existing $filename because you used --force."
1369 }
1370 } else {
1371 puts "I don't see $filename, so I will create it."
1372 }
1373 writefile $filename $contents
1374 }
1375 }
1376
1377 # ----- module install -----
1378
@@ -1343,11 +1387,11 @@
1387 cd $dir
1388 file mkdir autosetup
1389
1390 set f [open autosetup/autosetup w]
1391
1392 set publicmodules $::autosetup(libdir)/default.auto
1393
1394 # First the main script, but only up until "CUT HERE"
1395 set in [open $::autosetup(dir)/autosetup]
1396 while {[gets $in buf] >= 0} {
1397 if {$buf ne "##-- CUT HERE --##"} {
@@ -1391,14 +1435,39 @@
1435
1436 } error]} {
1437 user-error "Failed to install autosetup: $error"
1438 }
1439 puts "Installed [autosetup_version] to autosetup/"
1440
1441 # Now create 'configure' if necessary
1442 autosetup_create_configure
1443
1444 exit 0
1445 }
1446
1447 proc autosetup_create_configure {} {
1448 if {[file exists configure]} {
1449 if {!$::autosetup(force)} {
1450 # Could this be an autosetup configure?
1451 if {![string match "*\nWRAPPER=*" [readfile configure]]} {
1452 puts "I see configure, but not created by autosetup, so I won't overwrite it."
1453 puts "Remove it or use --force to overwrite."
1454 return
1455 }
1456 } else {
1457 puts "I will overwrite the existing configure because you used --force."
1458 }
1459 } else {
1460 puts "I don't see configure, so I will create it."
1461 }
1462 writefile configure \
1463 {#!/bin/sh
1464 dir="`dirname "$0"`/autosetup"
1465 WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@"
1466 }
1467 catch {exec chmod 755 configure}
1468 }
1469
1470 # Append the contents of $file to filehandle $f
1471 proc autosetup_install_append {f file} {
1472 set in [open $file]
1473 puts $f [read $in]
@@ -1539,19 +1608,32 @@
1608 if {[llength $args]} {
1609 return [lindex $args 0]
1610 }
1611 return -code error "environment variable \"$name\" does not exist"
1612 }
1613 proc isatty? {channel} {
1614 dict exists [fconfigure $channel] -xchar
 
 
 
1615 }
1616 } else {
1617 if {$autosetup(iswin)} {
1618 # On Windows, backslash convert all environment variables
1619 # (Assume that Tcl does this for us)
1620 proc getenv {name args} {
1621 string map {\\ /} [env $name {*}$args]
1622 }
1623 } else {
1624 # Jim on unix is simple
1625 alias getenv env
1626 }
1627 proc isatty? {channel} {
1628 set tty 0
1629 catch {
1630 # isatty is a recent addition to Jim Tcl
1631 set tty [$channel isatty]
1632 }
1633 return $tty
1634 }
1635 }
1636
1637 # In case 'file normalize' doesn't exist
1638 #
1639 proc file-normalize {path} {
@@ -1596,50 +1678,46 @@
1678 #puts "Skipping $info(file):$info(line)"
1679 }
1680 return $msg
1681 }
1682
1683 # If everything is working properly, the only errors which occur
1684 # should be generated in user code (e.g. auto.def).
1685 # By default, we only want to show the error location in user code.
1686 # We use [info frame] to achieve this, but it works differently on Tcl and Jim.
1687 #
1688 # This is designed to be called for incorrect usage in auto.def, via autosetup-error
1689 #
1690 proc error-stacktrace {msg} {
1691 if {$::autosetup(debug)} {
1692 return -code error $msg
1693 }
1694 # Search back through the stack trace for the first error in a .def file
1695 for {set i 1} {$i < [info level]} {incr i} {
1696 if {$::autosetup(istcl)} {
1697 array set info [info frame -$i]
1698 } else {
1699 lassign [info frame -$i] info(caller) info(file) info(line)
1700 }
1701 if {[string match *.def $info(file)]} {
1702 return "[relative-path $info(file)]:$info(line): Error: $msg"
1703 }
1704 #puts "Skipping $info(file):$info(line)"
1705 }
1706 return $msg
1707 }
1708
1709 # Given the return from [catch {...} msg opts], returns an appropriate
1710 # error message. A nice one for Jim and a less-nice one for Tcl.
1711 #
1712 # This is designed for developer errors, e.g. in module code
1713 #
1714 proc error-dump {msg opts} {
1715 if {$::autosetup(istcl)} {
1716 return "Error: [dict get $opts -errorinfo]"
1717 } else {
1718 return "Error: $msg\n[stackdump $opts(-errorinfo)]"
 
 
 
 
 
 
 
1719 }
1720 }
1721 }
1722
1723 # ----- module text-formatting -----
1724
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -73,5 +73,89 @@
7373
msg-result "unknown"
7474
}
7575
}
7676
return $rc
7777
}
78
+
79
+# @cc-check-flags flag ?...?
80
+#
81
+# Checks whether the given C/C++ compiler flags can be used. Defines feature
82
+# names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and
83
+# appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'.
84
+proc cc-check-flags {args} {
85
+ set result 1
86
+ array set opts [cc-get-settings]
87
+ switch -exact -- $opts(-lang) {
88
+ c++ {
89
+ set lang C++
90
+ set prefix CXXFLAG
91
+ }
92
+ c {
93
+ set lang C
94
+ set prefix CFLAG
95
+ }
96
+ default {
97
+ autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)"
98
+ }
99
+ }
100
+ foreach flag $args {
101
+ msg-checking "Checking whether the $lang compiler accepts $flag..."
102
+ if {[cctest -cflags $flag]} {
103
+ msg-result yes
104
+ define-feature $prefix$flag
105
+ cc-with [list -cflags [list $flag]]
106
+ define-append ${prefix}S $flag
107
+ } else {
108
+ msg-result no
109
+ set result 0
110
+ }
111
+ }
112
+ return $result
113
+}
114
+
115
+# @cc-check-standards ver ?...?
116
+#
117
+# Checks whether the C/C++ compiler accepts one of the specified '-std=$ver'
118
+# options, and appends the first working one to '-cflags' and 'CFLAGS' or
119
+# 'CXXFLAGS'.
120
+proc cc-check-standards {args} {
121
+ array set opts [cc-get-settings]
122
+ foreach std $args {
123
+ if {[cc-check-flags -std=$std]} {
124
+ return $std
125
+ }
126
+ }
127
+ return ""
128
+}
129
+
130
+# Checks whether $keyword is usable as alignof
131
+proc cctest_alignof {keyword} {
132
+ msg-checking "Checking for $keyword..."
133
+ if {[cctest -code [subst -nobackslashes {
134
+ printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x'));
135
+ }]]} then {
136
+ msg-result ok
137
+ define-feature $keyword
138
+ } else {
139
+ msg-result "not found"
140
+ }
141
+}
142
+
143
+# @cc-check-c11
144
+#
145
+# Checks for several C11/C++11 extensions and their alternatives. Currently
146
+# checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'.
147
+proc cc-check-c11 {} {
148
+ msg-checking "Checking for _Static_assert..."
149
+ if {[cctest -code {
150
+ _Static_assert(1, "static assertions are available");
151
+ }]} then {
152
+ msg-result ok
153
+ define-feature _Static_assert
154
+ } else {
155
+ msg-result "not found"
156
+ }
157
+
158
+ cctest_alignof _Alignof
159
+ cctest_alignof __alignof__
160
+ cctest_alignof __alignof
161
+}
78162
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -73,5 +73,89 @@
73 msg-result "unknown"
74 }
75 }
76 return $rc
77 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
--- autosetup/cc-lib.tcl
+++ autosetup/cc-lib.tcl
@@ -73,5 +73,89 @@
73 msg-result "unknown"
74 }
75 }
76 return $rc
77 }
78
79 # @cc-check-flags flag ?...?
80 #
81 # Checks whether the given C/C++ compiler flags can be used. Defines feature
82 # names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and
83 # appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'.
84 proc cc-check-flags {args} {
85 set result 1
86 array set opts [cc-get-settings]
87 switch -exact -- $opts(-lang) {
88 c++ {
89 set lang C++
90 set prefix CXXFLAG
91 }
92 c {
93 set lang C
94 set prefix CFLAG
95 }
96 default {
97 autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)"
98 }
99 }
100 foreach flag $args {
101 msg-checking "Checking whether the $lang compiler accepts $flag..."
102 if {[cctest -cflags $flag]} {
103 msg-result yes
104 define-feature $prefix$flag
105 cc-with [list -cflags [list $flag]]
106 define-append ${prefix}S $flag
107 } else {
108 msg-result no
109 set result 0
110 }
111 }
112 return $result
113 }
114
115 # @cc-check-standards ver ?...?
116 #
117 # Checks whether the C/C++ compiler accepts one of the specified '-std=$ver'
118 # options, and appends the first working one to '-cflags' and 'CFLAGS' or
119 # 'CXXFLAGS'.
120 proc cc-check-standards {args} {
121 array set opts [cc-get-settings]
122 foreach std $args {
123 if {[cc-check-flags -std=$std]} {
124 return $std
125 }
126 }
127 return ""
128 }
129
130 # Checks whether $keyword is usable as alignof
131 proc cctest_alignof {keyword} {
132 msg-checking "Checking for $keyword..."
133 if {[cctest -code [subst -nobackslashes {
134 printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x'));
135 }]]} then {
136 msg-result ok
137 define-feature $keyword
138 } else {
139 msg-result "not found"
140 }
141 }
142
143 # @cc-check-c11
144 #
145 # Checks for several C11/C++11 extensions and their alternatives. Currently
146 # checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'.
147 proc cc-check-c11 {} {
148 msg-checking "Checking for _Static_assert..."
149 if {[cctest -code {
150 _Static_assert(1, "static assertions are available");
151 }]} then {
152 msg-result ok
153 define-feature _Static_assert
154 } else {
155 msg-result "not found"
156 }
157
158 cctest_alignof _Alignof
159 cctest_alignof __alignof__
160 cctest_alignof __alignof
161 }
162
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -5,74 +5,99 @@
55
#
66
# The 'cc-shared' module provides support for shared libraries and shared objects.
77
# It defines the following variables:
88
#
99
## SH_CFLAGS Flags to use compiling sources destined for a shared library
10
-## SH_LDFLAGS Flags to use linking a shared library
10
+## SH_LDFLAGS Flags to use linking (creating) a shared library
11
+## SH_SOPREFIX Prefix to use to set the soname when creating a shared library
12
+## SH_SOEXT Extension for shared libs
13
+## SH_SOEXTVER Format for versioned shared libs - %s = version
1114
## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
1215
## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
1316
## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
1417
## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
1518
## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
19
+## STRIPLIBFLAGS Arguments to strip to strip a dynamic library
1620
1721
module-options {}
1822
19
-foreach i {SH_LINKFLAGS SH_CFLAGS SH_LDFLAGS SHOBJ_CFLAGS SHOBJ_LDFLAGS} {
20
- define $i ""
21
-}
22
-
23
+# Defaults: gcc on unix
24
+define SHOBJ_CFLAGS -fpic
25
+define SHOBJ_LDFLAGS -shared
26
+define SH_CFLAGS -fpic
27
+define SH_LDFLAGS -shared
28
+define SH_LINKFLAGS -rdynamic
29
+define SH_SOEXT .so
30
+define SH_SOEXTVER .so.%s
31
+define SH_SOPREFIX -Wl,-soname,
2332
define LD_LIBRARY_PATH LD_LIBRARY_PATH
33
+define STRIPLIBFLAGS --strip-unneeded
34
+
35
+# Note: This is a helpful reference for identifying the toolchain
36
+# http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers
2437
2538
switch -glob -- [get-define host] {
2639
*-*-darwin* {
27
- define SH_CFLAGS -dynamic
28
- define SH_LDFLAGS "-dynamiclib"
2940
define SHOBJ_CFLAGS "-dynamic -fno-common"
3041
define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup"
31
- define SHOBJ_LDFLAGS_R "-bundle"
32
- define LD_LIBRARY_PATH DYLD_LIBRARY_PATH
33
- }
34
- *-*-ming* {
35
- define SH_LDFLAGS -shared
36
- define SHOBJ_LDFLAGS -shared
37
- define SHOBJ_LDFLAGS_R -shared
38
- }
39
- *-*-cygwin {
40
- define SH_LDFLAGS -shared
41
- define SHOBJ_LDFLAGS -shared
42
+ define SHOBJ_LDFLAGS_R -bundle
43
+ define SH_CFLAGS -dynamic
44
+ define SH_LDFLAGS -dynamiclib
45
+ define SH_LINKFLAGS ""
46
+ define SH_SOEXT .dylib
47
+ define SH_SOEXTVER .%s.dylib
48
+ define SH_SOPREFIX -Wl,-install_name,
49
+ define LD_LIBRARY_PATH DYLD_LIBRARY_PATH
50
+ define STRIPLIBFLAGS -x
51
+ }
52
+ *-*-ming* - *-*-cygwin - *-*-msys {
53
+ define SHOBJ_CFLAGS ""
54
+ define SHOBJ_LDFLAGS -shared
55
+ define SH_CFLAGS ""
56
+ define SH_LDFLAGS -shared
57
+ define SH_LINKFLAGS ""
58
+ define SH_SOEXT .dll
59
+ define SH_SOEXTVER .dll
60
+ define SH_SOPREFIX ""
61
+ define LD_LIBRARY_PATH PATH
62
+ }
63
+ sparc* {
64
+ if {[msg-quiet cc-check-decls __SUNPRO_C]} {
65
+ msg-result "Found sun stdio compiler"
66
+ # sun stdio compiler
67
+ # XXX: These haven't been fully tested.
68
+ define SHOBJ_CFLAGS -KPIC
69
+ define SHOBJ_LDFLAGS "-G"
70
+ define SH_CFLAGS -KPIC
71
+ define SH_LINKFLAGS -Wl,-export-dynamic
72
+ define SH_SOPREFIX -Wl,-h,
73
+ } else {
74
+ # sparc has a very small GOT table limit, so use -fPIC
75
+ define SH_CFLAGS -fPIC
76
+ define SHOBJ_CFLAGS -fPIC
77
+ }
4278
}
4379
*-*-solaris* {
44
- # XXX: These haven't been fully tested.
45
- #define SH_LINKFLAGS -Wl,-export-dynamic
46
- define SH_CFLAGS -Kpic
47
- define SHOBJ_CFLAGS -Kpic
48
- define SHOBJ_LDFLAGS "-G"
80
+ if {[msg-quiet cc-check-decls __SUNPRO_C]} {
81
+ msg-result "Found sun stdio compiler"
82
+ # sun stdio compiler
83
+ # XXX: These haven't been fully tested.
84
+ define SHOBJ_CFLAGS -KPIC
85
+ define SHOBJ_LDFLAGS "-G"
86
+ define SH_CFLAGS -KPIC
87
+ define SH_LINKFLAGS -Wl,-export-dynamic
88
+ define SH_SOPREFIX -Wl,-h,
89
+ }
4990
}
5091
*-*-hpux {
5192
# XXX: These haven't been tested
52
- define SH_LINKFLAGS -Wl,+s
53
- define SH_CFLAGS +z
5493
define SHOBJ_CFLAGS "+O3 +z"
5594
define SHOBJ_LDFLAGS -b
95
+ define SH_CFLAGS +z
96
+ define SH_LINKFLAGS -Wl,+s
5697
define LD_LIBRARY_PATH SHLIB_PATH
5798
}
58
- sparc* {
59
- # sparc has a very small GOT table limit, so use -fPIC
60
- define SH_LINKFLAGS -rdynamic
61
- define SH_CFLAGS -fPIC
62
- define SH_LDFLAGS -shared
63
- define SHOBJ_CFLAGS -fPIC
64
- define SHOBJ_LDFLAGS -shared
65
- }
66
- * {
67
- # Generic Unix settings
68
- define SH_LINKFLAGS -rdynamic
69
- define SH_CFLAGS -fpic
70
- define SH_LDFLAGS -shared
71
- define SHOBJ_CFLAGS -fpic
72
- define SHOBJ_LDFLAGS -shared
73
- }
7499
}
75100
76101
if {![is-defined SHOBJ_LDFLAGS_R]} {
77102
define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
78103
}
79104
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -5,74 +5,99 @@
5 #
6 # The 'cc-shared' module provides support for shared libraries and shared objects.
7 # It defines the following variables:
8 #
9 ## SH_CFLAGS Flags to use compiling sources destined for a shared library
10 ## SH_LDFLAGS Flags to use linking a shared library
 
 
 
11 ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object
12 ## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed
13 ## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved
14 ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects
15 ## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries
 
16
17 module-options {}
18
19 foreach i {SH_LINKFLAGS SH_CFLAGS SH_LDFLAGS SHOBJ_CFLAGS SHOBJ_LDFLAGS} {
20 define $i ""
21 }
22
 
 
 
 
 
23 define LD_LIBRARY_PATH LD_LIBRARY_PATH
 
 
 
 
24
25 switch -glob -- [get-define host] {
26 *-*-darwin* {
27 define SH_CFLAGS -dynamic
28 define SH_LDFLAGS "-dynamiclib"
29 define SHOBJ_CFLAGS "-dynamic -fno-common"
30 define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup"
31 define SHOBJ_LDFLAGS_R "-bundle"
32 define LD_LIBRARY_PATH DYLD_LIBRARY_PATH
33 }
34 *-*-ming* {
35 define SH_LDFLAGS -shared
36 define SHOBJ_LDFLAGS -shared
37 define SHOBJ_LDFLAGS_R -shared
38 }
39 *-*-cygwin {
40 define SH_LDFLAGS -shared
41 define SHOBJ_LDFLAGS -shared
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42 }
43 *-*-solaris* {
44 # XXX: These haven't been fully tested.
45 #define SH_LINKFLAGS -Wl,-export-dynamic
46 define SH_CFLAGS -Kpic
47 define SHOBJ_CFLAGS -Kpic
48 define SHOBJ_LDFLAGS "-G"
 
 
 
 
 
49 }
50 *-*-hpux {
51 # XXX: These haven't been tested
52 define SH_LINKFLAGS -Wl,+s
53 define SH_CFLAGS +z
54 define SHOBJ_CFLAGS "+O3 +z"
55 define SHOBJ_LDFLAGS -b
 
 
56 define LD_LIBRARY_PATH SHLIB_PATH
57 }
58 sparc* {
59 # sparc has a very small GOT table limit, so use -fPIC
60 define SH_LINKFLAGS -rdynamic
61 define SH_CFLAGS -fPIC
62 define SH_LDFLAGS -shared
63 define SHOBJ_CFLAGS -fPIC
64 define SHOBJ_LDFLAGS -shared
65 }
66 * {
67 # Generic Unix settings
68 define SH_LINKFLAGS -rdynamic
69 define SH_CFLAGS -fpic
70 define SH_LDFLAGS -shared
71 define SHOBJ_CFLAGS -fpic
72 define SHOBJ_LDFLAGS -shared
73 }
74 }
75
76 if {![is-defined SHOBJ_LDFLAGS_R]} {
77 define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
78 }
79
--- autosetup/cc-shared.tcl
+++ autosetup/cc-shared.tcl
@@ -5,74 +5,99 @@
5 #
6 # The 'cc-shared' module provides support for shared libraries and shared objects.
7 # It defines the following variables:
8 #
9 ## SH_CFLAGS Flags to use compiling sources destined for a shared library
10 ## SH_LDFLAGS Flags to use linking (creating) a shared library
11 ## SH_SOPREFIX Prefix to use to set the soname when creating a shared library
12 ## SH_SOEXT Extension for shared libs
13 ## SH_SOEXTVER Format for versioned shared libs - %s = version
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 define SHOBJ_LDFLAGS -shared
26 define SH_CFLAGS -fpic
27 define SH_LDFLAGS -shared
28 define SH_LINKFLAGS -rdynamic
29 define SH_SOEXT .so
30 define SH_SOEXTVER .so.%s
31 define SH_SOPREFIX -Wl,-soname,
32 define LD_LIBRARY_PATH LD_LIBRARY_PATH
33 define STRIPLIBFLAGS --strip-unneeded
34
35 # Note: This is a helpful reference for identifying the toolchain
36 # http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers
37
38 switch -glob -- [get-define host] {
39 *-*-darwin* {
 
 
40 define SHOBJ_CFLAGS "-dynamic -fno-common"
41 define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup"
42 define SHOBJ_LDFLAGS_R -bundle
43 define SH_CFLAGS -dynamic
44 define SH_LDFLAGS -dynamiclib
45 define SH_LINKFLAGS ""
46 define SH_SOEXT .dylib
47 define SH_SOEXTVER .%s.dylib
48 define SH_SOPREFIX -Wl,-install_name,
49 define LD_LIBRARY_PATH DYLD_LIBRARY_PATH
50 define STRIPLIBFLAGS -x
51 }
52 *-*-ming* - *-*-cygwin - *-*-msys {
53 define SHOBJ_CFLAGS ""
54 define SHOBJ_LDFLAGS -shared
55 define SH_CFLAGS ""
56 define SH_LDFLAGS -shared
57 define SH_LINKFLAGS ""
58 define SH_SOEXT .dll
59 define SH_SOEXTVER .dll
60 define SH_SOPREFIX ""
61 define LD_LIBRARY_PATH PATH
62 }
63 sparc* {
64 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
65 msg-result "Found sun stdio compiler"
66 # sun stdio compiler
67 # XXX: These haven't been fully tested.
68 define SHOBJ_CFLAGS -KPIC
69 define SHOBJ_LDFLAGS "-G"
70 define SH_CFLAGS -KPIC
71 define SH_LINKFLAGS -Wl,-export-dynamic
72 define SH_SOPREFIX -Wl,-h,
73 } else {
74 # sparc has a very small GOT table limit, so use -fPIC
75 define SH_CFLAGS -fPIC
76 define SHOBJ_CFLAGS -fPIC
77 }
78 }
79 *-*-solaris* {
80 if {[msg-quiet cc-check-decls __SUNPRO_C]} {
81 msg-result "Found sun stdio compiler"
82 # sun stdio compiler
83 # XXX: These haven't been fully tested.
84 define SHOBJ_CFLAGS -KPIC
85 define SHOBJ_LDFLAGS "-G"
86 define SH_CFLAGS -KPIC
87 define SH_LINKFLAGS -Wl,-export-dynamic
88 define SH_SOPREFIX -Wl,-h,
89 }
90 }
91 *-*-hpux {
92 # XXX: These haven't been tested
 
 
93 define SHOBJ_CFLAGS "+O3 +z"
94 define SHOBJ_LDFLAGS -b
95 define SH_CFLAGS +z
96 define SH_LINKFLAGS -Wl,+s
97 define LD_LIBRARY_PATH SHLIB_PATH
98 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99 }
100
101 if {![is-defined SHOBJ_LDFLAGS_R]} {
102 define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS]
103 }
104
+32 -20
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -114,11 +114,11 @@
114114
proc cc-check-includes {args} {
115115
cc-check-some-feature $args {
116116
set with {}
117117
if {[dict exists $::autosetup(cc-include-deps) $each]} {
118118
set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]]
119
- msg-quiet cc-check-includes $deps
119
+ msg-quiet cc-check-includes {*}$deps
120120
foreach i $deps {
121121
if {[have-feature $i]} {
122122
lappend with $i
123123
}
124124
}
@@ -131,16 +131,18 @@
131131
cctest -includes $each
132132
}
133133
}
134134
}
135135
136
-# @cc-include-needs include required
136
+# @cc-include-needs include required ...
137137
#
138138
# Ensures that when checking for 'include', a check is first
139
-# made for 'required', and if found, it is #included
140
-proc cc-include-needs {file depfile} {
141
- dict set ::autosetup(cc-include-deps) $file $depfile 1
139
+# made for each 'required' file, and if found, it is #included
140
+proc cc-include-needs {file args} {
141
+ foreach depfile $args {
142
+ dict set ::autosetup(cc-include-deps) $file $depfile 1
143
+ }
142144
}
143145
144146
# @cc-check-types type ...
145147
#
146148
# Checks that the types exist.
@@ -254,21 +256,29 @@
254256
# For example, when checking for "ar", first AR is checked on the command
255257
# line and then in the environment. If not found, "${host}-ar" or
256258
# simply "ar" is assumed depending upon whether cross compiling.
257259
# The path is searched for this executable, and if found AR is defined
258260
# to the executable name.
261
+# Note that even when cross compiling, the simple "ar" is used as a fallback,
262
+# but a warning is generated. This is necessary for some toolchains.
259263
#
260264
# It is an error if the executable is not found.
261265
#
262266
proc cc-check-tools {args} {
263267
foreach tool $args {
264268
set TOOL [string toupper $tool]
265269
set exe [get-env $TOOL [get-define cross]$tool]
266
- if {![find-executable $exe]} {
267
- user-error "Failed to find $exe"
270
+ if {[find-executable {*}$exe]} {
271
+ define $TOOL $exe
272
+ continue
273
+ }
274
+ if {[find-executable {*}$tool]} {
275
+ msg-result "Warning: Failed to find $exe, falling back to $tool which may be incorrect"
276
+ define $TOOL $tool
277
+ continue
268278
}
269
- define $TOOL $exe
279
+ user-error "Failed to find $exe"
270280
}
271281
}
272282
273283
# @cc-check-progs prog ...
274284
#
@@ -489,18 +499,12 @@
489499
490500
if {!$opts(-link)} {
491501
set tmp conftest__.o
492502
lappend cmdline -c
493503
}
494
- lappend cmdline {*}$opts(-cflags)
495
-
496
- switch -glob -- [get-define host] {
497
- *-*-darwin* {
498
- # Don't generate .dSYM directories
499
- lappend cmdline -gstabs
500
- }
501
- }
504
+ lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
505
+
502506
lappend cmdline $src -o $tmp {*}$opts(-libs)
503507
504508
# At this point we have the complete command line and the
505509
# complete source to be compiled. Get the result from cache if
506510
# we can
@@ -587,20 +591,20 @@
587591
}
588592
-none {
589593
continue
590594
}
591595
-str {
592
- set value \"$value\"
596
+ set value \"[string map [list \\ \\\\ \" \\\"] $value]\"
593597
}
594598
-auto {
595599
# Automatically determine the type
596600
if {$value eq "0"} {
597601
lappend lines "/* #undef $n */"
598602
continue
599603
}
600604
if {![string is integer -strict $value]} {
601
- set value \"$value\"
605
+ set value \"[string map [list \\ \\\\ \" \\\"] $value]\"
602606
}
603607
}
604608
"" {
605609
continue
606610
}
@@ -657,12 +661,10 @@
657661
}
658662
659663
# CXXFLAGS default to CFLAGS if not specified
660664
define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]]
661665
662
-cc-check-tools ld
663
-
664666
# May need a CC_FOR_BUILD, so look for one
665667
define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false]
666668
667669
if {[get-define CC] eq ""} {
668670
user-error "Could not find a C compiler. Tried: [join $try ", "]"
@@ -677,9 +679,19 @@
677679
msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]"
678680
if {[get-define CXX] ne "false"} {
679681
msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS]"
680682
}
681683
msg-result "Build C compiler...[get-define CC_FOR_BUILD]"
684
+
685
+# On Darwin, we prefer to use -gstabs to avoid creating .dSYM directories
686
+# but some compilers don't support -gstabs, so test for it here.
687
+switch -glob -- [get-define host] {
688
+ *-*-darwin* {
689
+ if {[cctest -cflags {-gstabs}]} {
690
+ define cc-default-debug -gstabs
691
+ }
692
+ }
693
+}
682694
683695
if {![cc-check-includes stdlib.h]} {
684696
user-error "Compiler does not work. See config.log"
685697
}
686698
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -114,11 +114,11 @@
114 proc cc-check-includes {args} {
115 cc-check-some-feature $args {
116 set with {}
117 if {[dict exists $::autosetup(cc-include-deps) $each]} {
118 set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]]
119 msg-quiet cc-check-includes $deps
120 foreach i $deps {
121 if {[have-feature $i]} {
122 lappend with $i
123 }
124 }
@@ -131,16 +131,18 @@
131 cctest -includes $each
132 }
133 }
134 }
135
136 # @cc-include-needs include required
137 #
138 # Ensures that when checking for 'include', a check is first
139 # made for 'required', and if found, it is #included
140 proc cc-include-needs {file depfile} {
141 dict set ::autosetup(cc-include-deps) $file $depfile 1
 
 
142 }
143
144 # @cc-check-types type ...
145 #
146 # Checks that the types exist.
@@ -254,21 +256,29 @@
254 # For example, when checking for "ar", first AR is checked on the command
255 # line and then in the environment. If not found, "${host}-ar" or
256 # simply "ar" is assumed depending upon whether cross compiling.
257 # The path is searched for this executable, and if found AR is defined
258 # to the executable name.
 
 
259 #
260 # It is an error if the executable is not found.
261 #
262 proc cc-check-tools {args} {
263 foreach tool $args {
264 set TOOL [string toupper $tool]
265 set exe [get-env $TOOL [get-define cross]$tool]
266 if {![find-executable $exe]} {
267 user-error "Failed to find $exe"
 
 
 
 
 
 
268 }
269 define $TOOL $exe
270 }
271 }
272
273 # @cc-check-progs prog ...
274 #
@@ -489,18 +499,12 @@
489
490 if {!$opts(-link)} {
491 set tmp conftest__.o
492 lappend cmdline -c
493 }
494 lappend cmdline {*}$opts(-cflags)
495
496 switch -glob -- [get-define host] {
497 *-*-darwin* {
498 # Don't generate .dSYM directories
499 lappend cmdline -gstabs
500 }
501 }
502 lappend cmdline $src -o $tmp {*}$opts(-libs)
503
504 # At this point we have the complete command line and the
505 # complete source to be compiled. Get the result from cache if
506 # we can
@@ -587,20 +591,20 @@
587 }
588 -none {
589 continue
590 }
591 -str {
592 set value \"$value\"
593 }
594 -auto {
595 # Automatically determine the type
596 if {$value eq "0"} {
597 lappend lines "/* #undef $n */"
598 continue
599 }
600 if {![string is integer -strict $value]} {
601 set value \"$value\"
602 }
603 }
604 "" {
605 continue
606 }
@@ -657,12 +661,10 @@
657 }
658
659 # CXXFLAGS default to CFLAGS if not specified
660 define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]]
661
662 cc-check-tools ld
663
664 # May need a CC_FOR_BUILD, so look for one
665 define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false]
666
667 if {[get-define CC] eq ""} {
668 user-error "Could not find a C compiler. Tried: [join $try ", "]"
@@ -677,9 +679,19 @@
677 msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]"
678 if {[get-define CXX] ne "false"} {
679 msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS]"
680 }
681 msg-result "Build C compiler...[get-define CC_FOR_BUILD]"
 
 
 
 
 
 
 
 
 
 
682
683 if {![cc-check-includes stdlib.h]} {
684 user-error "Compiler does not work. See config.log"
685 }
686
--- autosetup/cc.tcl
+++ autosetup/cc.tcl
@@ -114,11 +114,11 @@
114 proc cc-check-includes {args} {
115 cc-check-some-feature $args {
116 set with {}
117 if {[dict exists $::autosetup(cc-include-deps) $each]} {
118 set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]]
119 msg-quiet cc-check-includes {*}$deps
120 foreach i $deps {
121 if {[have-feature $i]} {
122 lappend with $i
123 }
124 }
@@ -131,16 +131,18 @@
131 cctest -includes $each
132 }
133 }
134 }
135
136 # @cc-include-needs include required ...
137 #
138 # Ensures that when checking for 'include', a check is first
139 # made for each 'required' file, and if found, it is #included
140 proc cc-include-needs {file args} {
141 foreach depfile $args {
142 dict set ::autosetup(cc-include-deps) $file $depfile 1
143 }
144 }
145
146 # @cc-check-types type ...
147 #
148 # Checks that the types exist.
@@ -254,21 +256,29 @@
256 # For example, when checking for "ar", first AR is checked on the command
257 # line and then in the environment. If not found, "${host}-ar" or
258 # simply "ar" is assumed depending upon whether cross compiling.
259 # The path is searched for this executable, and if found AR is defined
260 # to the executable name.
261 # Note that even when cross compiling, the simple "ar" is used as a fallback,
262 # but a warning is generated. This is necessary for some toolchains.
263 #
264 # It is an error if the executable is not found.
265 #
266 proc cc-check-tools {args} {
267 foreach tool $args {
268 set TOOL [string toupper $tool]
269 set exe [get-env $TOOL [get-define cross]$tool]
270 if {[find-executable {*}$exe]} {
271 define $TOOL $exe
272 continue
273 }
274 if {[find-executable {*}$tool]} {
275 msg-result "Warning: Failed to find $exe, falling back to $tool which may be incorrect"
276 define $TOOL $tool
277 continue
278 }
279 user-error "Failed to find $exe"
280 }
281 }
282
283 # @cc-check-progs prog ...
284 #
@@ -489,18 +499,12 @@
499
500 if {!$opts(-link)} {
501 set tmp conftest__.o
502 lappend cmdline -c
503 }
504 lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""]
505
 
 
 
 
 
 
506 lappend cmdline $src -o $tmp {*}$opts(-libs)
507
508 # At this point we have the complete command line and the
509 # complete source to be compiled. Get the result from cache if
510 # we can
@@ -587,20 +591,20 @@
591 }
592 -none {
593 continue
594 }
595 -str {
596 set value \"[string map [list \\ \\\\ \" \\\"] $value]\"
597 }
598 -auto {
599 # Automatically determine the type
600 if {$value eq "0"} {
601 lappend lines "/* #undef $n */"
602 continue
603 }
604 if {![string is integer -strict $value]} {
605 set value \"[string map [list \\ \\\\ \" \\\"] $value]\"
606 }
607 }
608 "" {
609 continue
610 }
@@ -657,12 +661,10 @@
661 }
662
663 # CXXFLAGS default to CFLAGS if not specified
664 define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]]
665
 
 
666 # May need a CC_FOR_BUILD, so look for one
667 define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false]
668
669 if {[get-define CC] eq ""} {
670 user-error "Could not find a C compiler. Tried: [join $try ", "]"
@@ -677,9 +679,19 @@
679 msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]"
680 if {[get-define CXX] ne "false"} {
681 msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS]"
682 }
683 msg-result "Build C compiler...[get-define CC_FOR_BUILD]"
684
685 # On Darwin, we prefer to use -gstabs to avoid creating .dSYM directories
686 # but some compilers don't support -gstabs, so test for it here.
687 switch -glob -- [get-define host] {
688 *-*-darwin* {
689 if {[cctest -cflags {-gstabs}]} {
690 define cc-default-debug -gstabs
691 }
692 }
693 }
694
695 if {![cc-check-includes stdlib.h]} {
696 user-error "Compiler does not work. See config.log"
697 }
698
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -802,10 +802,13 @@
802802
echo ${UNAME_MACHINE}-pc-cygwin
803803
exit ;;
804804
*:MINGW*:*)
805805
echo ${UNAME_MACHINE}-pc-mingw32
806806
exit ;;
807
+ i*:MSYS*:*)
808
+ echo ${UNAME_MACHINE}-pc-msys
809
+ exit ;;
807810
i*:windows32*:*)
808811
# uname -m includes "-pc" on this system.
809812
echo ${UNAME_MACHINE}-mingw32
810813
exit ;;
811814
i*:PW*:*)
812815
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -802,10 +802,13 @@
802 echo ${UNAME_MACHINE}-pc-cygwin
803 exit ;;
804 *:MINGW*:*)
805 echo ${UNAME_MACHINE}-pc-mingw32
806 exit ;;
 
 
 
807 i*:windows32*:*)
808 # uname -m includes "-pc" on this system.
809 echo ${UNAME_MACHINE}-mingw32
810 exit ;;
811 i*:PW*:*)
812
--- autosetup/config.guess
+++ autosetup/config.guess
@@ -802,10 +802,13 @@
802 echo ${UNAME_MACHINE}-pc-cygwin
803 exit ;;
804 *:MINGW*:*)
805 echo ${UNAME_MACHINE}-pc-mingw32
806 exit ;;
807 i*:MSYS*:*)
808 echo ${UNAME_MACHINE}-pc-msys
809 exit ;;
810 i*:windows32*:*)
811 # uname -m includes "-pc" on this system.
812 echo ${UNAME_MACHINE}-mingw32
813 exit ;;
814 i*:PW*:*)
815
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -796,10 +796,14 @@
796796
;;
797797
mvs)
798798
basic_machine=i370-ibm
799799
os=-mvs
800800
;;
801
+ msys)
802
+ basic_machine=i386-pc
803
+ os=-msys
804
+ ;;
801805
ncr3000)
802806
basic_machine=i486-ncr
803807
os=-sysv4
804808
;;
805809
netbsd386)
@@ -1313,11 +1317,11 @@
13131317
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
13141318
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
13151319
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
13161320
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
13171321
| -chorusos* | -chorusrdb* | -cegcc* \
1318
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1322
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
13191323
| -mingw32* | -linux-gnu* | -linux-android* \
13201324
| -linux-newlib* | -linux-uclibc* \
13211325
| -uxpv* | -beos* | -mpeix* | -udk* \
13221326
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
13231327
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
13241328
13251329
ADDED autosetup/default.auto
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -796,10 +796,14 @@
796 ;;
797 mvs)
798 basic_machine=i370-ibm
799 os=-mvs
800 ;;
 
 
 
 
801 ncr3000)
802 basic_machine=i486-ncr
803 os=-sysv4
804 ;;
805 netbsd386)
@@ -1313,11 +1317,11 @@
1313 | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
1314 | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
1315 | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
1316 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
1317 | -chorusos* | -chorusrdb* | -cegcc* \
1318 | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1319 | -mingw32* | -linux-gnu* | -linux-android* \
1320 | -linux-newlib* | -linux-uclibc* \
1321 | -uxpv* | -beos* | -mpeix* | -udk* \
1322 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
1323 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
1324
1325 DDED autosetup/default.auto
--- autosetup/config.sub
+++ autosetup/config.sub
@@ -796,10 +796,14 @@
796 ;;
797 mvs)
798 basic_machine=i370-ibm
799 os=-mvs
800 ;;
801 msys)
802 basic_machine=i386-pc
803 os=-msys
804 ;;
805 ncr3000)
806 basic_machine=i486-ncr
807 os=-sysv4
808 ;;
809 netbsd386)
@@ -1313,11 +1317,11 @@
1317 | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
1318 | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
1319 | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
1320 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
1321 | -chorusos* | -chorusrdb* | -cegcc* \
1322 | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1323 | -mingw32* | -linux-gnu* | -linux-android* \
1324 | -linux-newlib* | -linux-uclibc* \
1325 | -uxpv* | -beos* | -mpeix* | -udk* \
1326 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
1327 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
1328
1329 DDED autosetup/default.auto
--- a/autosetup/default.auto
+++ b/autosetup/default.auto
@@ -0,0 +1,25 @@
1
+# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/
2
+# All rights reserved
3
+
4
+# Auto-load module for 'make' build system integration
5
+
6
+use init
7
+
8
+autosetup_add_init_type make {Simple "make" build system} {
9
+ autosetup_check_create auto.def \
10
+{# Initial auto.def created by 'autosetup --init=make'
11
+
12
+use cc
13
+
14
+# Add any user options here
15
+options {
16
+}
17
+
18
+make-config-header config.h
19
+make-template Makefile.in
20
+}
21
+
22
+ if {![file exists Makefile.in]} {
23
+ puts "Note: I don't see Makefile.in. You will probably need to create one."
24
+ }
25
+}
--- a/autosetup/default.auto
+++ b/autosetup/default.auto
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/autosetup/default.auto
+++ b/autosetup/default.auto
@@ -0,0 +1,25 @@
1 # Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/
2 # All rights reserved
3
4 # Auto-load module for 'make' build system integration
5
6 use init
7
8 autosetup_add_init_type make {Simple "make" build system} {
9 autosetup_check_create auto.def \
10 {# Initial auto.def created by 'autosetup --init=make'
11
12 use cc
13
14 # Add any user options here
15 options {
16 }
17
18 make-config-header config.h
19 make-template Makefile.in
20 }
21
22 if {![file exists Makefile.in]} {
23 puts "Note: I don't see Makefile.in. You will probably need to create one."
24 }
25 }
+478 -255
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -37,10 +37,11 @@
3737
#define TCL_PLATFORM_OS "unknown"
3838
#define TCL_PLATFORM_PLATFORM "unix"
3939
#define TCL_PLATFORM_PATH_SEPARATOR ":"
4040
#define HAVE_VFORK
4141
#define HAVE_WAITPID
42
+#define HAVE_ISATTY
4243
#define HAVE_SYS_TIME_H
4344
#define HAVE_DIRENT_H
4445
#define HAVE_UNISTD_H
4546
#endif
4647
#ifndef JIM_WIN32COMPAT_H
@@ -532,10 +533,11 @@
532533
structure. */
533534
int local;
534535
Jim_Obj *liveList;
535536
Jim_Obj *freeList;
536537
Jim_Obj *currentScriptObj;
538
+ Jim_Obj *nullScriptObj;
537539
Jim_Obj *emptyObj;
538540
Jim_Obj *trueObj;
539541
Jim_Obj *falseObj;
540542
unsigned long referenceNextId;
541543
struct Jim_HashTable references;
@@ -1078,13 +1080,108 @@
10781080
"\n"
10791081
"\n"
10801082
"\n"
10811083
"\n"
10821084
"\n"
1085
+"\n"
10831086
"\n"
10841087
"package require readdir\n"
10851088
"\n"
1089
+"\n"
1090
+"proc glob.globdir {dir pattern} {\n"
1091
+" set result {}\n"
1092
+" set files [readdir $dir]\n"
1093
+" lappend files . ..\n"
1094
+"\n"
1095
+" foreach name $files {\n"
1096
+" if {[string match $pattern $name]} {\n"
1097
+"\n"
1098
+" if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n"
1099
+" continue\n"
1100
+" }\n"
1101
+" lappend result $name\n"
1102
+" }\n"
1103
+" }\n"
1104
+"\n"
1105
+" return $result\n"
1106
+"}\n"
1107
+"\n"
1108
+"\n"
1109
+"\n"
1110
+"\n"
1111
+"proc glob.explode {pattern} {\n"
1112
+" set oldexp {}\n"
1113
+" set newexp {\"\"}\n"
1114
+"\n"
1115
+" while 1 {\n"
1116
+" set oldexp $newexp\n"
1117
+" set newexp {}\n"
1118
+" set ob [string first \\{ $pattern]\n"
1119
+" set cb [string first \\} $pattern]\n"
1120
+"\n"
1121
+" if {$ob < $cb && $ob != -1} {\n"
1122
+" set mid [string range $pattern 0 $ob-1]\n"
1123
+" set subexp [lassign [glob.explode [string range $pattern $ob+1 end]] pattern]\n"
1124
+" if {$pattern eq \"\"} {\n"
1125
+" error \"unmatched open brace in glob pattern\"\n"
1126
+" }\n"
1127
+" set pattern [string range $pattern 1 end]\n"
1128
+"\n"
1129
+" foreach subs $subexp {\n"
1130
+" foreach sub [split $subs ,] {\n"
1131
+" foreach old $oldexp {\n"
1132
+" lappend newexp $old$mid$sub\n"
1133
+" }\n"
1134
+" }\n"
1135
+" }\n"
1136
+" } elseif {$cb != -1} {\n"
1137
+" set suf [string range $pattern 0 $cb-1]\n"
1138
+" set rest [string range $pattern $cb end]\n"
1139
+" break\n"
1140
+" } else {\n"
1141
+" set suf $pattern\n"
1142
+" set rest \"\"\n"
1143
+" break\n"
1144
+" }\n"
1145
+" }\n"
1146
+"\n"
1147
+" foreach old $oldexp {\n"
1148
+" lappend newexp $old$suf\n"
1149
+" }\n"
1150
+" linsert $newexp 0 $rest\n"
1151
+"}\n"
1152
+"\n"
1153
+"\n"
1154
+"\n"
1155
+"proc glob.glob {base pattern} {\n"
1156
+" set dir [file dirname $pattern]\n"
1157
+" if {$pattern eq $dir || $pattern eq \"\"} {\n"
1158
+" return [list [file join $base $dir] $pattern]\n"
1159
+" } elseif {$pattern eq [file tail $pattern]} {\n"
1160
+" set dir \"\"\n"
1161
+" }\n"
1162
+"\n"
1163
+"\n"
1164
+" set dirlist [glob.glob $base $dir]\n"
1165
+" set pattern [file tail $pattern]\n"
1166
+"\n"
1167
+"\n"
1168
+" set result {}\n"
1169
+" foreach {realdir dir} $dirlist {\n"
1170
+" if {![file isdir $realdir]} {\n"
1171
+" continue\n"
1172
+" }\n"
1173
+" if {[string index $dir end] ne \"/\" && $dir ne \"\"} {\n"
1174
+" append dir /\n"
1175
+" }\n"
1176
+" foreach name [glob.globdir $realdir $pattern] {\n"
1177
+" lappend result [file join $realdir $name] $dir$name\n"
1178
+" }\n"
1179
+" }\n"
1180
+" return $result\n"
1181
+"}\n"
1182
+"\n"
10861183
"\n"
10871184
"\n"
10881185
"\n"
10891186
"\n"
10901187
"\n"
@@ -1093,114 +1190,75 @@
10931190
"\n"
10941191
"\n"
10951192
"\n"
10961193
"\n"
10971194
"proc glob {args} {\n"
1098
-"\n"
1099
-"\n"
1100
-"\n"
1101
-"\n"
1102
-" local proc glob.readdir_pattern {dir pattern} {\n"
1103
-" set result {}\n"
1104
-"\n"
1105
-"\n"
1106
-" if {$pattern in {. ..}} {\n"
1107
-" return $pattern\n"
1108
-" }\n"
1109
-"\n"
1110
-"\n"
1111
-" if {[string match {*[[*?]*} $pattern]} {\n"
1112
-"\n"
1113
-" set files [readdir -nocomplain $dir]\n"
1114
-" } elseif {[file isdir $dir] && [file exists $dir/$pattern]} {\n"
1115
-" set files [list $pattern]\n"
1116
-" } else {\n"
1117
-" set files \"\"\n"
1118
-" }\n"
1119
-"\n"
1120
-" foreach name $files {\n"
1121
-" if {[string match $pattern $name]} {\n"
1122
-"\n"
1123
-" if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n"
1124
-" continue\n"
1125
-" }\n"
1195
+" set nocomplain 0\n"
1196
+" set base \"\"\n"
1197
+"\n"
1198
+" set n 0\n"
1199
+" foreach arg $args {\n"
1200
+" if {[info exists param]} {\n"
1201
+" set $param $arg\n"
1202
+" unset param\n"
1203
+" incr n\n"
1204
+" continue\n"
1205
+" }\n"
1206
+" switch -glob -- $arg {\n"
1207
+" -d* {\n"
1208
+" set switch $arg\n"
1209
+" set param base\n"
1210
+" }\n"
1211
+" -n* {\n"
1212
+" set nocomplain 1\n"
1213
+" }\n"
1214
+" -t* {\n"
1215
+"\n"
1216
+" }\n"
1217
+"\n"
1218
+" -* {\n"
1219
+" return -code error \"bad option \\\"$switch\\\": must be -directory, -nocomplain, -tails, or --\"\n"
1220
+" }\n"
1221
+" -- {\n"
1222
+" incr n\n"
1223
+" break\n"
1224
+" }\n"
1225
+" * {\n"
1226
+" break\n"
1227
+" }\n"
1228
+" }\n"
1229
+" incr n\n"
1230
+" }\n"
1231
+" if {[info exists param]} {\n"
1232
+" return -code error \"missing argument to \\\"$switch\\\"\"\n"
1233
+" }\n"
1234
+" if {[llength $args] <= $n} {\n"
1235
+" return -code error \"wrong # args: should be \\\"glob ?options? pattern ?pattern ...?\\\"\"\n"
1236
+" }\n"
1237
+"\n"
1238
+" set args [lrange $args $n end]\n"
1239
+"\n"
1240
+" set result {}\n"
1241
+" foreach pattern $args {\n"
1242
+" set pattern [string map {\n"
1243
+" \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n"
1244
+" } $pattern]\n"
1245
+" set patexps [lassign [glob.explode $pattern] rest]\n"
1246
+" if {$rest ne \"\"} {\n"
1247
+" return -code error \"unmatched close brace in glob pattern\"\n"
1248
+" }\n"
1249
+" foreach patexp $patexps {\n"
1250
+" set patexp [string map {\n"
1251
+" \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n"
1252
+" } $patexp]\n"
1253
+" foreach {realname name} [glob.glob $base $patexp] {\n"
11261254
" lappend result $name\n"
11271255
" }\n"
11281256
" }\n"
1129
-"\n"
1130
-" return $result\n"
1131
-" }\n"
1132
-"\n"
1133
-"\n"
1134
-"\n"
1135
-"\n"
1136
-"\n"
1137
-" proc glob.expandbraces {pattern} {\n"
1138
-"\n"
1139
-"\n"
1140
-" if {[set fb [string first \"\\{\" $pattern]] < 0} {\n"
1141
-" return [list $pattern]\n"
1142
-" }\n"
1143
-" if {[set nb [string first \"\\}\" $pattern $fb]] < 0} {\n"
1144
-" return [list $pattern]\n"
1145
-" }\n"
1146
-" set before [string range $pattern 0 $fb-1]\n"
1147
-" set braced [string range $pattern $fb+1 $nb-1]\n"
1148
-" set after [string range $pattern $nb+1 end]\n"
1149
-"\n"
1150
-" lmap part [split $braced ,] {\n"
1151
-" set pat $before$part$after\n"
1152
-" }\n"
1153
-" }\n"
1154
-"\n"
1155
-"\n"
1156
-" proc glob.glob {pattern} {\n"
1157
-" set dir [file dirname $pattern]\n"
1158
-" if {$dir eq $pattern} {\n"
1159
-"\n"
1160
-" return [list $dir]\n"
1161
-" }\n"
1162
-"\n"
1163
-"\n"
1164
-" set dirlist [glob.glob $dir]\n"
1165
-" set pattern [file tail $pattern]\n"
1166
-"\n"
1167
-"\n"
1168
-" set result {}\n"
1169
-" foreach dir $dirlist {\n"
1170
-" set globdir $dir\n"
1171
-" if {[string match \"*/\" $dir]} {\n"
1172
-" set sep \"\"\n"
1173
-" } elseif {$dir eq \".\"} {\n"
1174
-" set globdir \"\"\n"
1175
-" set sep \"\"\n"
1176
-" } else {\n"
1177
-" set sep /\n"
1178
-" }\n"
1179
-" foreach pat [glob.expandbraces $pattern] {\n"
1180
-" foreach name [glob.readdir_pattern $dir $pat] {\n"
1181
-" lappend result $globdir$sep$name\n"
1182
-" }\n"
1183
-" }\n"
1184
-" }\n"
1185
-" return $result\n"
1186
-" }\n"
1187
-"\n"
1188
-"\n"
1189
-" set nocomplain 0\n"
1190
-"\n"
1191
-" if {[lindex $args 0] eq \"-nocomplain\"} {\n"
1192
-" set nocomplain 1\n"
1193
-" set args [lrange $args 1 end]\n"
1194
-" }\n"
1195
-"\n"
1196
-" set result {}\n"
1197
-" foreach pattern $args {\n"
1198
-" lappend result {*}[glob.glob $pattern]\n"
1199
-" }\n"
1200
-"\n"
1201
-" if {$nocomplain == 0 && [llength $result] == 0} {\n"
1257
+" }\n"
1258
+"\n"
1259
+" if {!$nocomplain && [llength $result] == 0} {\n"
12021260
" return -code error \"no files matched glob patterns\"\n"
12031261
" }\n"
12041262
"\n"
12051263
" return $result\n"
12061264
"}\n"
@@ -1628,10 +1686,11 @@
16281686
" file delete $path\n"
16291687
"}\n"
16301688
);
16311689
}
16321690
1691
+
16331692
16341693
#include <stdio.h>
16351694
#include <string.h>
16361695
#include <errno.h>
16371696
#include <fcntl.h>
@@ -1651,10 +1710,17 @@
16511710
#endif
16521711
16531712
16541713
#define AIO_CMD_LEN 32
16551714
#define AIO_BUF_LEN 256
1715
+
1716
+#ifndef HAVE_FTELLO
1717
+ #define ftello ftell
1718
+#endif
1719
+#ifndef HAVE_FSEEKO
1720
+ #define fseeko fseek
1721
+#endif
16561722
16571723
#define AIO_KEEPOPEN 1
16581724
16591725
#if defined(JIM_IPV6)
16601726
#define IPV6 1
@@ -1935,10 +2001,22 @@
19352001
}
19362002
JimAioSetError(interp, af->filename);
19372003
return JIM_ERR;
19382004
}
19392005
2006
+static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2007
+{
2008
+#ifdef HAVE_ISATTY
2009
+ AioFile *af = Jim_CmdPrivData(interp);
2010
+ Jim_SetResultInt(interp, isatty(fileno(af->fp)));
2011
+#else
2012
+ Jim_SetResultInt(interp, 0);
2013
+#endif
2014
+
2015
+ return JIM_OK;
2016
+}
2017
+
19402018
19412019
static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19422020
{
19432021
AioFile *af = Jim_CmdPrivData(interp);
19442022
@@ -1965,11 +2043,11 @@
19652043
19662044
static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19672045
{
19682046
AioFile *af = Jim_CmdPrivData(interp);
19692047
int orig = SEEK_SET;
1970
- long offset;
2048
+ jim_wide offset;
19712049
19722050
if (argc == 2) {
19732051
if (Jim_CompareStringImmediate(interp, argv[1], "start"))
19742052
orig = SEEK_SET;
19752053
else if (Jim_CompareStringImmediate(interp, argv[1], "current"))
@@ -1978,14 +2056,14 @@
19782056
orig = SEEK_END;
19792057
else {
19802058
return -1;
19812059
}
19822060
}
1983
- if (Jim_GetLong(interp, argv[0], &offset) != JIM_OK) {
2061
+ if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) {
19842062
return JIM_ERR;
19852063
}
1986
- if (fseek(af->fp, offset, orig) == -1) {
2064
+ if (fseeko(af->fp, offset, orig) == -1) {
19872065
JimAioSetError(interp, af->filename);
19882066
return JIM_ERR;
19892067
}
19902068
return JIM_OK;
19912069
}
@@ -1992,11 +2070,11 @@
19922070
19932071
static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
19942072
{
19952073
AioFile *af = Jim_CmdPrivData(interp);
19962074
1997
- Jim_SetResultInt(interp, ftell(af->fp));
2075
+ Jim_SetResultInt(interp, ftello(af->fp));
19982076
return JIM_OK;
19992077
}
20002078
20012079
static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
20022080
{
@@ -2167,10 +2245,17 @@
21672245
"?-nonewline? str",
21682246
aio_cmd_puts,
21692247
1,
21702248
2,
21712249
2250
+ },
2251
+ { "isatty",
2252
+ NULL,
2253
+ aio_cmd_isatty,
2254
+ 0,
2255
+ 0,
2256
+
21722257
},
21732258
{ "flush",
21742259
NULL,
21752260
aio_cmd_flush,
21762261
0,
@@ -3048,11 +3133,13 @@
30483133
static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
30493134
{
30503135
const char *path = Jim_String(argv[0]);
30513136
const char *p = strrchr(path, '/');
30523137
3053
- if (!p) {
3138
+ if (!p && path[0] == '.' && path[1] == '.' && path[2] == '\0') {
3139
+ Jim_SetResultString(interp, "..", -1);
3140
+ } else if (!p) {
30543141
Jim_SetResultString(interp, ".", -1);
30553142
}
30563143
else if (p == path) {
30573144
Jim_SetResultString(interp, "/", -1);
30583145
}
@@ -3116,16 +3203,17 @@
31163203
const char *path = Jim_String(argv[0]);
31173204
char *newname = Jim_Alloc(MAXPATHLEN + 1);
31183205
31193206
if (realpath(path, newname)) {
31203207
Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1));
3208
+ return JIM_OK;
31213209
}
31223210
else {
31233211
Jim_Free(newname);
3124
- Jim_SetResult(interp, argv[0]);
3212
+ Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno));
3213
+ return JIM_ERR;
31253214
}
3126
- return JIM_OK;
31273215
#else
31283216
Jim_SetResultString(interp, "Not implemented", -1);
31293217
return JIM_ERR;
31303218
#endif
31313219
}
@@ -4934,11 +5022,11 @@
49345022
return env;
49355023
}
49365024
49375025
static void JimRestoreEnv(char **env)
49385026
{
4939
- JimFreeEnv(env, NULL);
5027
+ JimFreeEnv(env, Jim_GetEnviron());
49405028
}
49415029
49425030
static Jim_Obj *
49435031
JimWinBuildCommandLine(Jim_Interp *interp, char **argv)
49445032
{
@@ -5869,16 +5957,103 @@
58695957
endptr++;
58705958
}
58715959
}
58725960
return JIM_OK;
58735961
}
5962
+
5963
+static int JimNumberBase(const char *str, int *base, int *sign)
5964
+{
5965
+ int i = 0;
5966
+
5967
+ *base = 10;
5968
+
5969
+ while (isspace(UCHAR(str[i]))) {
5970
+ i++;
5971
+ }
5972
+
5973
+ if (str[i] == '-') {
5974
+ *sign = -1;
5975
+ i++;
5976
+ }
5977
+ else {
5978
+ if (str[i] == '+') {
5979
+ i++;
5980
+ }
5981
+ *sign = 1;
5982
+ }
5983
+
5984
+ if (str[i] != '0') {
5985
+
5986
+ return 0;
5987
+ }
5988
+
5989
+
5990
+ switch (str[i + 1]) {
5991
+ case 'x': case 'X': *base = 16; break;
5992
+ case 'o': case 'O': *base = 8; break;
5993
+ case 'b': case 'B': *base = 2; break;
5994
+ default: return 0;
5995
+ }
5996
+ i += 2;
5997
+
5998
+ if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
5999
+
6000
+ return i;
6001
+ }
6002
+
6003
+ return 10;
6004
+}
6005
+
6006
+static long jim_strtol(const char *str, char **endptr)
6007
+{
6008
+ int sign;
6009
+ int base;
6010
+ int i = JimNumberBase(str, &base, &sign);
6011
+
6012
+ if (base != 10) {
6013
+ long value = strtol(str + i, endptr, base);
6014
+ if (endptr == NULL || *endptr != str + i) {
6015
+ return value * sign;
6016
+ }
6017
+ }
6018
+
6019
+
6020
+ return strtol(str, endptr, 10);
6021
+}
6022
+
6023
+
6024
+static jim_wide jim_strtoull(const char *str, char **endptr)
6025
+{
6026
+#ifdef HAVE_LONG_LONG
6027
+ int sign;
6028
+ int base;
6029
+ int i = JimNumberBase(str, &base, &sign);
6030
+
6031
+ if (base != 10) {
6032
+ jim_wide value = strtoull(str + i, endptr, base);
6033
+ if (endptr == NULL || *endptr != str + i) {
6034
+ return value * sign;
6035
+ }
6036
+ }
6037
+
6038
+
6039
+ return strtoull(str, endptr, 10);
6040
+#else
6041
+ return (unsigned long)jim_strtol(str, endptr);
6042
+#endif
6043
+}
58746044
58756045
int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
58766046
{
58776047
char *endptr;
58786048
5879
- *widePtr = strtoull(str, &endptr, base);
6049
+ if (base) {
6050
+ *widePtr = strtoull(str, &endptr, base);
6051
+ }
6052
+ else {
6053
+ *widePtr = jim_strtoull(str, &endptr);
6054
+ }
58806055
58816056
return JimCheckConversion(str, endptr);
58826057
}
58836058
58846059
int Jim_DoubleToString(char *buf, double doubleValue)
@@ -7390,27 +7565,10 @@
73907565
Jim_Free(objPtr->bytes);
73917566
}
73927567
objPtr->bytes = NULL;
73937568
}
73947569
7395
-#define Jim_SetStringRep(o, b, l) \
7396
- do { (o)->bytes = b; (o)->length = l; } while (0)
7397
-
7398
-void Jim_InitStringRep(Jim_Obj *objPtr, const char *bytes, int length)
7399
-{
7400
- if (length == 0) {
7401
- objPtr->bytes = JimEmptyStringRep;
7402
- objPtr->length = 0;
7403
- }
7404
- else {
7405
- objPtr->bytes = Jim_Alloc(length + 1);
7406
- objPtr->length = length;
7407
- memcpy(objPtr->bytes, bytes, length);
7408
- objPtr->bytes[length] = '\0';
7409
- }
7410
-}
7411
-
74127570
74137571
Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr)
74147572
{
74157573
Jim_Obj *dupPtr;
74167574
@@ -7417,12 +7575,22 @@
74177575
dupPtr = Jim_NewObj(interp);
74187576
if (objPtr->bytes == NULL) {
74197577
74207578
dupPtr->bytes = NULL;
74217579
}
7580
+ else if (objPtr->length == 0) {
7581
+
7582
+ dupPtr->bytes = JimEmptyStringRep;
7583
+ dupPtr->length = 0;
7584
+ dupPtr->typePtr = NULL;
7585
+ return dupPtr;
7586
+ }
74227587
else {
7423
- Jim_InitStringRep(dupPtr, objPtr->bytes, objPtr->length);
7588
+ dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
7589
+ dupPtr->length = objPtr->length;
7590
+
7591
+ memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
74247592
}
74257593
74267594
74277595
dupPtr->typePtr = objPtr->typePtr;
74287596
if (objPtr->typePtr != NULL) {
@@ -7596,13 +7764,12 @@
75967764
75977765
Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len)
75987766
{
75997767
Jim_Obj *objPtr = Jim_NewObj(interp);
76007768
7601
- if (len == -1)
7602
- len = strlen(s);
7603
- Jim_SetStringRep(objPtr, s, len);
7769
+ objPtr->bytes = s;
7770
+ objPtr->length = len == -1 ? strlen(s) : len;
76047771
objPtr->typePtr = NULL;
76057772
return objPtr;
76067773
}
76077774
76087775
static void StringAppendString(Jim_Obj *objPtr, const char *str, int len)
@@ -7818,11 +7985,11 @@
78187985
78197986
if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) {
78207987
return NULL;
78217988
}
78227989
7823
- if (last <= first) {
7990
+ if (last < first) {
78247991
return strObjPtr;
78257992
}
78267993
78277994
str = Jim_String(strObjPtr);
78287995
@@ -8169,19 +8336,19 @@
81698336
Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj);
81708337
}
81718338
81728339
void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
81738340
{
8174
- dupPtr->internalRep = srcPtr->internalRep;
8341
+ dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue;
81758342
Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj);
81768343
}
81778344
81788345
static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr,
81798346
Jim_Obj *fileNameObj, int lineNumber)
81808347
{
81818348
JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object"));
8182
- JimPanic((objPtr->typePtr != NULL, "JimSetSourceInfo called with typePtr != NULL"));
8349
+ JimPanic((objPtr->typePtr == &sourceObjType, "JimSetSourceInfo called with non-source object"));
81838350
Jim_IncrRefCount(fileNameObj);
81848351
objPtr->internalRep.sourceValue.fileNameObj = fileNameObj;
81858352
objPtr->internalRep.sourceValue.lineNumber = lineNumber;
81868353
objPtr->typePtr = &sourceObjType;
81878354
}
@@ -8557,13 +8724,16 @@
85578724
return JIM_OK;
85588725
}
85598726
85608727
ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr)
85618728
{
8562
- struct ScriptObj *script = Jim_GetIntRepPtr(objPtr);
8729
+ if (objPtr == interp->emptyObj) {
8730
+
8731
+ objPtr = interp->nullScriptObj;
8732
+ }
85638733
8564
- if (objPtr->typePtr != &scriptObjType || script->substFlags) {
8734
+ if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
85658735
SetScriptFromAny(interp, objPtr, NULL);
85668736
}
85678737
return (ScriptObj *) Jim_GetIntRepPtr(objPtr);
85688738
}
85698739
@@ -10045,16 +10215,18 @@
1004510215
i->result = i->emptyObj;
1004610216
i->stackTrace = Jim_NewListObj(i, NULL, 0);
1004710217
i->unknown = Jim_NewStringObj(i, "unknown", -1);
1004810218
i->errorProc = i->emptyObj;
1004910219
i->currentScriptObj = Jim_NewEmptyStringObj(i);
10220
+ i->nullScriptObj = Jim_NewEmptyStringObj(i);
1005010221
Jim_IncrRefCount(i->emptyObj);
1005110222
Jim_IncrRefCount(i->errorFileNameObj);
1005210223
Jim_IncrRefCount(i->result);
1005310224
Jim_IncrRefCount(i->stackTrace);
1005410225
Jim_IncrRefCount(i->unknown);
1005510226
Jim_IncrRefCount(i->currentScriptObj);
10227
+ Jim_IncrRefCount(i->nullScriptObj);
1005610228
Jim_IncrRefCount(i->errorProc);
1005710229
Jim_IncrRefCount(i->trueObj);
1005810230
Jim_IncrRefCount(i->falseObj);
1005910231
1006010232
@@ -10084,10 +10256,11 @@
1008410256
Jim_DecrRefCount(i, i->stackTrace);
1008510257
Jim_DecrRefCount(i, i->errorProc);
1008610258
Jim_DecrRefCount(i, i->unknown);
1008710259
Jim_DecrRefCount(i, i->errorFileNameObj);
1008810260
Jim_DecrRefCount(i, i->currentScriptObj);
10261
+ Jim_DecrRefCount(i, i->nullScriptObj);
1008910262
Jim_FreeHashTable(&i->commands);
1009010263
#ifdef JIM_REFERENCES
1009110264
Jim_FreeHashTable(&i->references);
1009210265
#endif
1009310266
Jim_FreeHashTable(&i->packages);
@@ -10159,11 +10332,11 @@
1015910332
if (levelObjPtr) {
1016010333
str = Jim_String(levelObjPtr);
1016110334
if (str[0] == '#') {
1016210335
char *endptr;
1016310336
10164
- level = strtol(str + 1, &endptr, 0);
10337
+ level = jim_strtol(str + 1, &endptr);
1016510338
if (str[1] == '\0' || endptr[0] != '\0') {
1016610339
level = -1;
1016710340
}
1016810341
}
1016910342
else {
@@ -10822,13 +10995,11 @@
1082210995
1082310996
if (objPtr->typePtr == &listObjType) {
1082410997
return JIM_OK;
1082510998
}
1082610999
10827
-#if 0
10828
-
10829
- if (Jim_IsDict(objPtr)) {
11000
+ if (Jim_IsDict(objPtr) && !Jim_IsShared(objPtr)) {
1083011001
Jim_Obj **listObjPtrPtr;
1083111002
int len;
1083211003
int i;
1083311004
1083411005
Jim_DictPairs(interp, objPtr, &listObjPtrPtr, &len);
@@ -10843,11 +11014,10 @@
1084311014
objPtr->internalRep.listValue.maxLen = len;
1084411015
objPtr->internalRep.listValue.ele = listObjPtrPtr;
1084511016
1084611017
return JIM_OK;
1084711018
}
10848
-#endif
1084911019
1085011020
1085111021
if (objPtr->typePtr == &sourceObjType) {
1085211022
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
1085311023
linenr = objPtr->internalRep.sourceValue.lineNumber;
@@ -10866,20 +11036,22 @@
1086611036
objPtr->internalRep.listValue.len = 0;
1086711037
objPtr->internalRep.listValue.maxLen = 0;
1086811038
objPtr->internalRep.listValue.ele = NULL;
1086911039
1087011040
10871
- JimParserInit(&parser, str, strLen, linenr);
10872
- while (!parser.eof) {
10873
- Jim_Obj *elementPtr;
10874
-
10875
- JimParseList(&parser);
10876
- if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC)
10877
- continue;
10878
- elementPtr = JimParserGetTokenObj(interp, &parser);
10879
- JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline);
10880
- ListAppendElement(objPtr, elementPtr);
11041
+ if (strLen) {
11042
+ JimParserInit(&parser, str, strLen, linenr);
11043
+ while (!parser.eof) {
11044
+ Jim_Obj *elementPtr;
11045
+
11046
+ JimParseList(&parser);
11047
+ if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC)
11048
+ continue;
11049
+ elementPtr = JimParserGetTokenObj(interp, &parser);
11050
+ JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline);
11051
+ ListAppendElement(objPtr, elementPtr);
11052
+ }
1088111053
}
1088211054
Jim_DecrRefCount(interp, fileNameObj);
1088311055
return JIM_OK;
1088411056
}
1088511057
@@ -11682,11 +11854,11 @@
1168211854
end = 1;
1168311855
str += 3;
1168411856
idx = 0;
1168511857
}
1168611858
else {
11687
- idx = strtol(str, &endptr, 0);
11859
+ idx = jim_strtol(str, &endptr);
1168811860
1168911861
if (endptr == str) {
1169011862
goto badindex;
1169111863
}
1169211864
str = endptr;
@@ -11694,11 +11866,11 @@
1169411866
1169511867
1169611868
if (*str == '+' || *str == '-') {
1169711869
int sign = (*str == '+' ? 1 : -1);
1169811870
11699
- idx += sign * strtol(++str, &endptr, 0);
11871
+ idx += sign * jim_strtol(++str, &endptr);
1170011872
if (str == endptr || *endptr) {
1170111873
goto badindex;
1170211874
}
1170311875
str = endptr;
1170411876
}
@@ -12769,32 +12941,57 @@
1276912941
}
1277012942
1277112943
static int JimParseExprNumber(struct JimParserCtx *pc)
1277212944
{
1277312945
int allowdot = 1;
12774
- int allowhex = 0;
12946
+ int base = 10;
1277512947
1277612948
1277712949
pc->tt = JIM_TT_EXPR_INT;
1277812950
pc->tstart = pc->p;
1277912951
pc->tline = pc->linenr;
12952
+
12953
+
12954
+ if (pc->p[0] == '0') {
12955
+ switch (pc->p[1]) {
12956
+ case 'x':
12957
+ case 'X':
12958
+ base = 16;
12959
+ allowdot = 0;
12960
+ pc->p += 2;
12961
+ pc->len -= 2;
12962
+ break;
12963
+ case 'o':
12964
+ case 'O':
12965
+ base = 8;
12966
+ allowdot = 0;
12967
+ pc->p += 2;
12968
+ pc->len -= 2;
12969
+ break;
12970
+ case 'b':
12971
+ case 'B':
12972
+ base = 2;
12973
+ allowdot = 0;
12974
+ pc->p += 2;
12975
+ pc->len -= 2;
12976
+ break;
12977
+ }
12978
+ }
12979
+
1278012980
while (isdigit(UCHAR(*pc->p))
12781
- || (allowhex && isxdigit(UCHAR(*pc->p)))
12981
+ || (base == 16 && isxdigit(UCHAR(*pc->p)))
12982
+ || (base == 8 && *pc->p >= '0' && *pc->p <= '7')
12983
+ || (base == 2 && (*pc->p == '0' || *pc->p == '1'))
1278212984
|| (allowdot && *pc->p == '.')
12783
- || (pc->p - pc->tstart == 1 && *pc->tstart == '0' && (*pc->p == 'x' || *pc->p == 'X'))
1278412985
) {
12785
- if ((*pc->p == 'x') || (*pc->p == 'X')) {
12786
- allowhex = 1;
12787
- allowdot = 0;
12788
- }
1278912986
if (*pc->p == '.') {
1279012987
allowdot = 0;
1279112988
pc->tt = JIM_TT_EXPR_DOUBLE;
1279212989
}
1279312990
pc->p++;
1279412991
pc->len--;
12795
- if (!allowhex && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+'
12992
+ if (base == 10 && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+'
1279612993
|| isdigit(UCHAR(pc->p[1])))) {
1279712994
pc->p += 2;
1279812995
pc->len -= 2;
1279912996
pc->tt = JIM_TT_EXPR_DOUBLE;
1280012997
}
@@ -13183,29 +13380,39 @@
1318313380
case JIM_TT_ESC:
1318413381
case JIM_TT_VAR:
1318513382
case JIM_TT_DICTSUGAR:
1318613383
case JIM_TT_EXPRSUGAR:
1318713384
case JIM_TT_CMD:
13188
- token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
1318913385
token->type = t->type;
13386
+strexpr:
13387
+ token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
1319013388
if (t->type == JIM_TT_CMD) {
1319113389
1319213390
JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
1319313391
}
1319413392
expr->len++;
1319513393
break;
1319613394
1319713395
case JIM_TT_EXPR_INT:
13198
- token->objPtr = Jim_NewIntObj(interp, strtoull(t->token, NULL, 0));
13199
- token->type = t->type;
13200
- expr->len++;
13201
- break;
13202
-
1320313396
case JIM_TT_EXPR_DOUBLE:
13204
- token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, NULL));
13205
- token->type = t->type;
13206
- expr->len++;
13397
+ {
13398
+ char *endptr;
13399
+ if (t->type == JIM_TT_EXPR_INT) {
13400
+ token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13401
+ }
13402
+ else {
13403
+ token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13404
+ }
13405
+ if (endptr != t->token + t->len) {
13406
+
13407
+ Jim_FreeNewObj(interp, token->objPtr);
13408
+ token->type = JIM_TT_STR;
13409
+ goto strexpr;
13410
+ }
13411
+ token->type = t->type;
13412
+ expr->len++;
13413
+ }
1320713414
break;
1320813415
1320913416
case JIM_TT_SUBEXPR_START:
1321013417
Jim_StackPush(&stack, t);
1321113418
prevtt = JIM_TT_NONE;
@@ -13984,13 +14191,15 @@
1398414191
1398514192
int base = descr->type == 'o' ? 8
1398614193
: descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
1398714194
1398814195
13989
- w = strtoull(tok, &endp, base);
13990
- if (endp == tok && base == 0) {
13991
- w = strtoull(tok, &endp, 10);
14196
+ if (base == 0) {
14197
+ w = jim_strtoull(tok, &endp);
14198
+ }
14199
+ else {
14200
+ w = strtoull(tok, &endp, base);
1399214201
}
1399314202
1399414203
if (endp != tok) {
1399514204
1399614205
*valObjPtr = Jim_NewIntObj(interp, w);
@@ -14817,10 +15026,15 @@
1481715026
(cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
1481815027
JimSetProcWrongArgs(interp, argv[0], cmd);
1481915028
return JIM_ERR;
1482015029
}
1482115030
15031
+ if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15032
+
15033
+ return JIM_OK;
15034
+ }
15035
+
1482215036
1482315037
if (interp->framePtr->level == interp->maxCallFrameDepth) {
1482415038
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
1482515039
return JIM_ERR;
1482615040
}
@@ -15079,78 +15293,49 @@
1507915293
Jim_DecrRefCount(interp, scriptObjPtr);
1508015294
1508115295
return retcode;
1508215296
}
1508315297
15084
-static int JimParseSubstStr(struct JimParserCtx *pc)
15298
+static void JimParseSubst(struct JimParserCtx *pc, int flags)
1508515299
{
1508615300
pc->tstart = pc->p;
1508715301
pc->tline = pc->linenr;
15088
- while (pc->len && *pc->p != '$' && *pc->p != '[') {
15302
+
15303
+ if (pc->len == 0) {
15304
+ pc->tend = pc->p;
15305
+ pc->tt = JIM_TT_EOL;
15306
+ pc->eof = 1;
15307
+ return;
15308
+ }
15309
+ if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) {
15310
+ JimParseCmd(pc);
15311
+ return;
15312
+ }
15313
+ if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15314
+ if (JimParseVar(pc) == JIM_OK) {
15315
+ return;
15316
+ }
15317
+
15318
+ pc->tstart = pc->p;
15319
+ flags |= JIM_SUBST_NOVAR;
15320
+ }
15321
+ while (pc->len) {
15322
+ if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15323
+ break;
15324
+ }
15325
+ if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) {
15326
+ break;
15327
+ }
1508915328
if (*pc->p == '\\' && pc->len > 1) {
1509015329
pc->p++;
1509115330
pc->len--;
1509215331
}
1509315332
pc->p++;
1509415333
pc->len--;
1509515334
}
1509615335
pc->tend = pc->p - 1;
15097
- pc->tt = JIM_TT_ESC;
15098
- return JIM_OK;
15099
-}
15100
-
15101
-static int JimParseSubst(struct JimParserCtx *pc, int flags)
15102
-{
15103
- int retval;
15104
-
15105
- if (pc->len == 0) {
15106
- pc->tstart = pc->tend = pc->p;
15107
- pc->tline = pc->linenr;
15108
- pc->tt = JIM_TT_EOL;
15109
- pc->eof = 1;
15110
- return JIM_OK;
15111
- }
15112
- switch (*pc->p) {
15113
- case '[':
15114
- retval = JimParseCmd(pc);
15115
- if (flags & JIM_SUBST_NOCMD) {
15116
- pc->tstart--;
15117
- pc->tend++;
15118
- pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC;
15119
- }
15120
- return retval;
15121
- break;
15122
- case '$':
15123
- if (JimParseVar(pc) == JIM_ERR) {
15124
- pc->tstart = pc->tend = pc->p++;
15125
- pc->len--;
15126
- pc->tline = pc->linenr;
15127
- pc->tt = JIM_TT_STR;
15128
- }
15129
- else {
15130
- if (flags & JIM_SUBST_NOVAR) {
15131
- pc->tstart--;
15132
- if (flags & JIM_SUBST_NOESC)
15133
- pc->tt = JIM_TT_STR;
15134
- else
15135
- pc->tt = JIM_TT_ESC;
15136
- if (*pc->tstart == '{') {
15137
- pc->tstart--;
15138
- if (*(pc->tend + 1))
15139
- pc->tend++;
15140
- }
15141
- }
15142
- }
15143
- break;
15144
- default:
15145
- retval = JimParseSubstStr(pc);
15146
- if (flags & JIM_SUBST_NOESC)
15147
- pc->tt = JIM_TT_STR;
15148
- return retval;
15149
- break;
15150
- }
15151
- return JIM_OK;
15336
+ pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC;
1515215337
}
1515315338
1515415339
1515515340
static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags)
1515615341
{
@@ -17173,10 +17358,13 @@
1717317358
OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE
1717417359
};
1717517360
static const char * const nocase_options[] = {
1717617361
"-nocase", NULL
1717717362
};
17363
+ static const char * const nocase_length_options[] = {
17364
+ "-nocase", "-length", NULL
17365
+ };
1717817366
1717917367
if (argc < 2) {
1718017368
Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?");
1718117369
return JIM_ERR;
1718217370
}
@@ -17200,27 +17388,58 @@
1720017388
Jim_SetResultInt(interp, len);
1720117389
return JIM_OK;
1720217390
1720317391
case OPT_COMPARE:
1720417392
case OPT_EQUAL:
17205
- if (argc != 4 &&
17206
- (argc != 5 ||
17207
- Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL,
17208
- JIM_ENUM_ABBREV) != JIM_OK)) {
17209
- Jim_WrongNumArgs(interp, 2, argv, "?-nocase? string1 string2");
17210
- return JIM_ERR;
17211
- }
17212
- if (opt_case == 0) {
17213
- argv++;
17214
- }
17215
- if (option == OPT_COMPARE || !opt_case) {
17216
- Jim_SetResultInt(interp, Jim_StringCompareObj(interp, argv[2], argv[3], !opt_case));
17217
- }
17218
- else {
17219
- Jim_SetResultBool(interp, Jim_StringEqObj(argv[2], argv[3]));
17220
- }
17221
- return JIM_OK;
17393
+ {
17394
+
17395
+ long opt_length = -1;
17396
+ int n = argc - 4;
17397
+ int i = 2;
17398
+ while (n > 0) {
17399
+ int subopt;
17400
+ if (Jim_GetEnum(interp, argv[i++], nocase_length_options, &subopt, NULL,
17401
+ JIM_ENUM_ABBREV) != JIM_OK) {
17402
+badcompareargs:
17403
+ Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
17404
+ return JIM_ERR;
17405
+ }
17406
+ if (subopt == 0) {
17407
+
17408
+ opt_case = 0;
17409
+ n--;
17410
+ }
17411
+ else {
17412
+
17413
+ if (n < 2) {
17414
+ goto badcompareargs;
17415
+ }
17416
+ if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
17417
+ return JIM_ERR;
17418
+ }
17419
+ n -= 2;
17420
+ }
17421
+ }
17422
+ if (n) {
17423
+ goto badcompareargs;
17424
+ }
17425
+ argv += argc - 2;
17426
+ if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17427
+
17428
+ Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
17429
+ }
17430
+ else {
17431
+ if (opt_length >= 0) {
17432
+ n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
17433
+ }
17434
+ else {
17435
+ n = Jim_StringCompareObj(interp, argv[0], argv[1], !opt_case);
17436
+ }
17437
+ Jim_SetResultInt(interp, option == OPT_COMPARE ? n : n == 0);
17438
+ }
17439
+ return JIM_OK;
17440
+ }
1722217441
1722317442
case OPT_MATCH:
1722417443
if (argc != 4 &&
1722517444
(argc != 5 ||
1722617445
Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL,
@@ -17281,11 +17500,11 @@
1728117500
1728217501
case OPT_REPLACE:{
1728317502
Jim_Obj *objPtr;
1728417503
1728517504
if (argc != 5 && argc != 6) {
17286
- Jim_WrongNumArgs(interp, 2, argv, "string first last ?newstring?");
17505
+ Jim_WrongNumArgs(interp, 2, argv, "string first last ?string?");
1728717506
return JIM_ERR;
1728817507
}
1728917508
objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL);
1729017509
if (objPtr == NULL) {
1729117510
return JIM_ERR;
@@ -17739,13 +17958,13 @@
1773917958
1774017959
listObjPtr = Jim_NewListObj(interp, NULL, 0);
1774117960
1774217961
htiter = Jim_GetHashTableIterator(&interp->references);
1774317962
while ((he = Jim_NextHashEntry(htiter)) != NULL) {
17744
- char buf[JIM_REFERENCE_SPACE];
17963
+ char buf[JIM_REFERENCE_SPACE + 1];
1774517964
Jim_Reference *refPtr = he->u.val;
17746
- const jim_wide *refId = he->key;
17965
+ const unsigned long *refId = he->key;
1774717966
1774817967
JimFormatReference(buf, refPtr, *refId);
1774917968
Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
1775017969
}
1775117970
Jim_FreeHashTableIterator(htiter);
@@ -17988,11 +18207,10 @@
1798818207
static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1798918208
{
1799018209
int cmd;
1799118210
Jim_Obj *objPtr;
1799218211
int mode = 0;
17993
- int nons = 0;
1799418212
1799518213
static const char * const commands[] = {
1799618214
"body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals",
1799718215
"vars", "version", "patchlevel", "complete", "args", "hostname",
1799818216
"script", "source", "stacktrace", "nameofexecutable", "returncodes",
@@ -18003,20 +18221,25 @@
1800318221
INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS,
1800418222
INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE,
1800518223
INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS
1800618224
};
1800718225
18008
- if (argc < 2) {
18009
- Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
18010
- return JIM_ERR;
18011
- }
18226
+#ifdef jim_ext_namespace
18227
+ int nons = 0;
18228
+
1801218229
if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
1801318230
1801418231
argc--;
1801518232
argv++;
1801618233
nons = 1;
1801718234
}
18235
+#endif
18236
+
18237
+ if (argc < 2) {
18238
+ Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
18239
+ return JIM_ERR;
18240
+ }
1801818241
if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
1801918242
!= JIM_OK) {
1802018243
return JIM_ERR;
1802118244
}
1802218245
1802318246
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -37,10 +37,11 @@
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_SYS_TIME_H
43 #define HAVE_DIRENT_H
44 #define HAVE_UNISTD_H
45 #endif
46 #ifndef JIM_WIN32COMPAT_H
@@ -532,10 +533,11 @@
532 structure. */
533 int local;
534 Jim_Obj *liveList;
535 Jim_Obj *freeList;
536 Jim_Obj *currentScriptObj;
 
537 Jim_Obj *emptyObj;
538 Jim_Obj *trueObj;
539 Jim_Obj *falseObj;
540 unsigned long referenceNextId;
541 struct Jim_HashTable references;
@@ -1078,13 +1080,108 @@
1078 "\n"
1079 "\n"
1080 "\n"
1081 "\n"
1082 "\n"
 
1083 "\n"
1084 "package require readdir\n"
1085 "\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1086 "\n"
1087 "\n"
1088 "\n"
1089 "\n"
1090 "\n"
@@ -1093,114 +1190,75 @@
1093 "\n"
1094 "\n"
1095 "\n"
1096 "\n"
1097 "proc glob {args} {\n"
1098 "\n"
1099 "\n"
1100 "\n"
1101 "\n"
1102 " local proc glob.readdir_pattern {dir pattern} {\n"
1103 " set result {}\n"
1104 "\n"
1105 "\n"
1106 " if {$pattern in {. ..}} {\n"
1107 " return $pattern\n"
1108 " }\n"
1109 "\n"
1110 "\n"
1111 " if {[string match {*[[*?]*} $pattern]} {\n"
1112 "\n"
1113 " set files [readdir -nocomplain $dir]\n"
1114 " } elseif {[file isdir $dir] && [file exists $dir/$pattern]} {\n"
1115 " set files [list $pattern]\n"
1116 " } else {\n"
1117 " set files \"\"\n"
1118 " }\n"
1119 "\n"
1120 " foreach name $files {\n"
1121 " if {[string match $pattern $name]} {\n"
1122 "\n"
1123 " if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n"
1124 " continue\n"
1125 " }\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1126 " lappend result $name\n"
1127 " }\n"
1128 " }\n"
1129 "\n"
1130 " return $result\n"
1131 " }\n"
1132 "\n"
1133 "\n"
1134 "\n"
1135 "\n"
1136 "\n"
1137 " proc glob.expandbraces {pattern} {\n"
1138 "\n"
1139 "\n"
1140 " if {[set fb [string first \"\\{\" $pattern]] < 0} {\n"
1141 " return [list $pattern]\n"
1142 " }\n"
1143 " if {[set nb [string first \"\\}\" $pattern $fb]] < 0} {\n"
1144 " return [list $pattern]\n"
1145 " }\n"
1146 " set before [string range $pattern 0 $fb-1]\n"
1147 " set braced [string range $pattern $fb+1 $nb-1]\n"
1148 " set after [string range $pattern $nb+1 end]\n"
1149 "\n"
1150 " lmap part [split $braced ,] {\n"
1151 " set pat $before$part$after\n"
1152 " }\n"
1153 " }\n"
1154 "\n"
1155 "\n"
1156 " proc glob.glob {pattern} {\n"
1157 " set dir [file dirname $pattern]\n"
1158 " if {$dir eq $pattern} {\n"
1159 "\n"
1160 " return [list $dir]\n"
1161 " }\n"
1162 "\n"
1163 "\n"
1164 " set dirlist [glob.glob $dir]\n"
1165 " set pattern [file tail $pattern]\n"
1166 "\n"
1167 "\n"
1168 " set result {}\n"
1169 " foreach dir $dirlist {\n"
1170 " set globdir $dir\n"
1171 " if {[string match \"*/\" $dir]} {\n"
1172 " set sep \"\"\n"
1173 " } elseif {$dir eq \".\"} {\n"
1174 " set globdir \"\"\n"
1175 " set sep \"\"\n"
1176 " } else {\n"
1177 " set sep /\n"
1178 " }\n"
1179 " foreach pat [glob.expandbraces $pattern] {\n"
1180 " foreach name [glob.readdir_pattern $dir $pat] {\n"
1181 " lappend result $globdir$sep$name\n"
1182 " }\n"
1183 " }\n"
1184 " }\n"
1185 " return $result\n"
1186 " }\n"
1187 "\n"
1188 "\n"
1189 " set nocomplain 0\n"
1190 "\n"
1191 " if {[lindex $args 0] eq \"-nocomplain\"} {\n"
1192 " set nocomplain 1\n"
1193 " set args [lrange $args 1 end]\n"
1194 " }\n"
1195 "\n"
1196 " set result {}\n"
1197 " foreach pattern $args {\n"
1198 " lappend result {*}[glob.glob $pattern]\n"
1199 " }\n"
1200 "\n"
1201 " if {$nocomplain == 0 && [llength $result] == 0} {\n"
1202 " return -code error \"no files matched glob patterns\"\n"
1203 " }\n"
1204 "\n"
1205 " return $result\n"
1206 "}\n"
@@ -1628,10 +1686,11 @@
1628 " file delete $path\n"
1629 "}\n"
1630 );
1631 }
1632
 
1633
1634 #include <stdio.h>
1635 #include <string.h>
1636 #include <errno.h>
1637 #include <fcntl.h>
@@ -1651,10 +1710,17 @@
1651 #endif
1652
1653
1654 #define AIO_CMD_LEN 32
1655 #define AIO_BUF_LEN 256
 
 
 
 
 
 
 
1656
1657 #define AIO_KEEPOPEN 1
1658
1659 #if defined(JIM_IPV6)
1660 #define IPV6 1
@@ -1935,10 +2001,22 @@
1935 }
1936 JimAioSetError(interp, af->filename);
1937 return JIM_ERR;
1938 }
1939
 
 
 
 
 
 
 
 
 
 
 
 
1940
1941 static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1942 {
1943 AioFile *af = Jim_CmdPrivData(interp);
1944
@@ -1965,11 +2043,11 @@
1965
1966 static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1967 {
1968 AioFile *af = Jim_CmdPrivData(interp);
1969 int orig = SEEK_SET;
1970 long offset;
1971
1972 if (argc == 2) {
1973 if (Jim_CompareStringImmediate(interp, argv[1], "start"))
1974 orig = SEEK_SET;
1975 else if (Jim_CompareStringImmediate(interp, argv[1], "current"))
@@ -1978,14 +2056,14 @@
1978 orig = SEEK_END;
1979 else {
1980 return -1;
1981 }
1982 }
1983 if (Jim_GetLong(interp, argv[0], &offset) != JIM_OK) {
1984 return JIM_ERR;
1985 }
1986 if (fseek(af->fp, offset, orig) == -1) {
1987 JimAioSetError(interp, af->filename);
1988 return JIM_ERR;
1989 }
1990 return JIM_OK;
1991 }
@@ -1992,11 +2070,11 @@
1992
1993 static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
1994 {
1995 AioFile *af = Jim_CmdPrivData(interp);
1996
1997 Jim_SetResultInt(interp, ftell(af->fp));
1998 return JIM_OK;
1999 }
2000
2001 static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2002 {
@@ -2167,10 +2245,17 @@
2167 "?-nonewline? str",
2168 aio_cmd_puts,
2169 1,
2170 2,
2171
 
 
 
 
 
 
 
2172 },
2173 { "flush",
2174 NULL,
2175 aio_cmd_flush,
2176 0,
@@ -3048,11 +3133,13 @@
3048 static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3049 {
3050 const char *path = Jim_String(argv[0]);
3051 const char *p = strrchr(path, '/');
3052
3053 if (!p) {
 
 
3054 Jim_SetResultString(interp, ".", -1);
3055 }
3056 else if (p == path) {
3057 Jim_SetResultString(interp, "/", -1);
3058 }
@@ -3116,16 +3203,17 @@
3116 const char *path = Jim_String(argv[0]);
3117 char *newname = Jim_Alloc(MAXPATHLEN + 1);
3118
3119 if (realpath(path, newname)) {
3120 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1));
 
3121 }
3122 else {
3123 Jim_Free(newname);
3124 Jim_SetResult(interp, argv[0]);
 
3125 }
3126 return JIM_OK;
3127 #else
3128 Jim_SetResultString(interp, "Not implemented", -1);
3129 return JIM_ERR;
3130 #endif
3131 }
@@ -4934,11 +5022,11 @@
4934 return env;
4935 }
4936
4937 static void JimRestoreEnv(char **env)
4938 {
4939 JimFreeEnv(env, NULL);
4940 }
4941
4942 static Jim_Obj *
4943 JimWinBuildCommandLine(Jim_Interp *interp, char **argv)
4944 {
@@ -5869,16 +5957,103 @@
5869 endptr++;
5870 }
5871 }
5872 return JIM_OK;
5873 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5874
5875 int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
5876 {
5877 char *endptr;
5878
5879 *widePtr = strtoull(str, &endptr, base);
 
 
 
 
 
5880
5881 return JimCheckConversion(str, endptr);
5882 }
5883
5884 int Jim_DoubleToString(char *buf, double doubleValue)
@@ -7390,27 +7565,10 @@
7390 Jim_Free(objPtr->bytes);
7391 }
7392 objPtr->bytes = NULL;
7393 }
7394
7395 #define Jim_SetStringRep(o, b, l) \
7396 do { (o)->bytes = b; (o)->length = l; } while (0)
7397
7398 void Jim_InitStringRep(Jim_Obj *objPtr, const char *bytes, int length)
7399 {
7400 if (length == 0) {
7401 objPtr->bytes = JimEmptyStringRep;
7402 objPtr->length = 0;
7403 }
7404 else {
7405 objPtr->bytes = Jim_Alloc(length + 1);
7406 objPtr->length = length;
7407 memcpy(objPtr->bytes, bytes, length);
7408 objPtr->bytes[length] = '\0';
7409 }
7410 }
7411
7412
7413 Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr)
7414 {
7415 Jim_Obj *dupPtr;
7416
@@ -7417,12 +7575,22 @@
7417 dupPtr = Jim_NewObj(interp);
7418 if (objPtr->bytes == NULL) {
7419
7420 dupPtr->bytes = NULL;
7421 }
 
 
 
 
 
 
 
7422 else {
7423 Jim_InitStringRep(dupPtr, objPtr->bytes, objPtr->length);
 
 
 
7424 }
7425
7426
7427 dupPtr->typePtr = objPtr->typePtr;
7428 if (objPtr->typePtr != NULL) {
@@ -7596,13 +7764,12 @@
7596
7597 Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len)
7598 {
7599 Jim_Obj *objPtr = Jim_NewObj(interp);
7600
7601 if (len == -1)
7602 len = strlen(s);
7603 Jim_SetStringRep(objPtr, s, len);
7604 objPtr->typePtr = NULL;
7605 return objPtr;
7606 }
7607
7608 static void StringAppendString(Jim_Obj *objPtr, const char *str, int len)
@@ -7818,11 +7985,11 @@
7818
7819 if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) {
7820 return NULL;
7821 }
7822
7823 if (last <= first) {
7824 return strObjPtr;
7825 }
7826
7827 str = Jim_String(strObjPtr);
7828
@@ -8169,19 +8336,19 @@
8169 Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj);
8170 }
8171
8172 void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
8173 {
8174 dupPtr->internalRep = srcPtr->internalRep;
8175 Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj);
8176 }
8177
8178 static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr,
8179 Jim_Obj *fileNameObj, int lineNumber)
8180 {
8181 JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object"));
8182 JimPanic((objPtr->typePtr != NULL, "JimSetSourceInfo called with typePtr != NULL"));
8183 Jim_IncrRefCount(fileNameObj);
8184 objPtr->internalRep.sourceValue.fileNameObj = fileNameObj;
8185 objPtr->internalRep.sourceValue.lineNumber = lineNumber;
8186 objPtr->typePtr = &sourceObjType;
8187 }
@@ -8557,13 +8724,16 @@
8557 return JIM_OK;
8558 }
8559
8560 ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr)
8561 {
8562 struct ScriptObj *script = Jim_GetIntRepPtr(objPtr);
 
 
 
8563
8564 if (objPtr->typePtr != &scriptObjType || script->substFlags) {
8565 SetScriptFromAny(interp, objPtr, NULL);
8566 }
8567 return (ScriptObj *) Jim_GetIntRepPtr(objPtr);
8568 }
8569
@@ -10045,16 +10215,18 @@
10045 i->result = i->emptyObj;
10046 i->stackTrace = Jim_NewListObj(i, NULL, 0);
10047 i->unknown = Jim_NewStringObj(i, "unknown", -1);
10048 i->errorProc = i->emptyObj;
10049 i->currentScriptObj = Jim_NewEmptyStringObj(i);
 
10050 Jim_IncrRefCount(i->emptyObj);
10051 Jim_IncrRefCount(i->errorFileNameObj);
10052 Jim_IncrRefCount(i->result);
10053 Jim_IncrRefCount(i->stackTrace);
10054 Jim_IncrRefCount(i->unknown);
10055 Jim_IncrRefCount(i->currentScriptObj);
 
10056 Jim_IncrRefCount(i->errorProc);
10057 Jim_IncrRefCount(i->trueObj);
10058 Jim_IncrRefCount(i->falseObj);
10059
10060
@@ -10084,10 +10256,11 @@
10084 Jim_DecrRefCount(i, i->stackTrace);
10085 Jim_DecrRefCount(i, i->errorProc);
10086 Jim_DecrRefCount(i, i->unknown);
10087 Jim_DecrRefCount(i, i->errorFileNameObj);
10088 Jim_DecrRefCount(i, i->currentScriptObj);
 
10089 Jim_FreeHashTable(&i->commands);
10090 #ifdef JIM_REFERENCES
10091 Jim_FreeHashTable(&i->references);
10092 #endif
10093 Jim_FreeHashTable(&i->packages);
@@ -10159,11 +10332,11 @@
10159 if (levelObjPtr) {
10160 str = Jim_String(levelObjPtr);
10161 if (str[0] == '#') {
10162 char *endptr;
10163
10164 level = strtol(str + 1, &endptr, 0);
10165 if (str[1] == '\0' || endptr[0] != '\0') {
10166 level = -1;
10167 }
10168 }
10169 else {
@@ -10822,13 +10995,11 @@
10822
10823 if (objPtr->typePtr == &listObjType) {
10824 return JIM_OK;
10825 }
10826
10827 #if 0
10828
10829 if (Jim_IsDict(objPtr)) {
10830 Jim_Obj **listObjPtrPtr;
10831 int len;
10832 int i;
10833
10834 Jim_DictPairs(interp, objPtr, &listObjPtrPtr, &len);
@@ -10843,11 +11014,10 @@
10843 objPtr->internalRep.listValue.maxLen = len;
10844 objPtr->internalRep.listValue.ele = listObjPtrPtr;
10845
10846 return JIM_OK;
10847 }
10848 #endif
10849
10850
10851 if (objPtr->typePtr == &sourceObjType) {
10852 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
10853 linenr = objPtr->internalRep.sourceValue.lineNumber;
@@ -10866,20 +11036,22 @@
10866 objPtr->internalRep.listValue.len = 0;
10867 objPtr->internalRep.listValue.maxLen = 0;
10868 objPtr->internalRep.listValue.ele = NULL;
10869
10870
10871 JimParserInit(&parser, str, strLen, linenr);
10872 while (!parser.eof) {
10873 Jim_Obj *elementPtr;
10874
10875 JimParseList(&parser);
10876 if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC)
10877 continue;
10878 elementPtr = JimParserGetTokenObj(interp, &parser);
10879 JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline);
10880 ListAppendElement(objPtr, elementPtr);
 
 
10881 }
10882 Jim_DecrRefCount(interp, fileNameObj);
10883 return JIM_OK;
10884 }
10885
@@ -11682,11 +11854,11 @@
11682 end = 1;
11683 str += 3;
11684 idx = 0;
11685 }
11686 else {
11687 idx = strtol(str, &endptr, 0);
11688
11689 if (endptr == str) {
11690 goto badindex;
11691 }
11692 str = endptr;
@@ -11694,11 +11866,11 @@
11694
11695
11696 if (*str == '+' || *str == '-') {
11697 int sign = (*str == '+' ? 1 : -1);
11698
11699 idx += sign * strtol(++str, &endptr, 0);
11700 if (str == endptr || *endptr) {
11701 goto badindex;
11702 }
11703 str = endptr;
11704 }
@@ -12769,32 +12941,57 @@
12769 }
12770
12771 static int JimParseExprNumber(struct JimParserCtx *pc)
12772 {
12773 int allowdot = 1;
12774 int allowhex = 0;
12775
12776
12777 pc->tt = JIM_TT_EXPR_INT;
12778 pc->tstart = pc->p;
12779 pc->tline = pc->linenr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12780 while (isdigit(UCHAR(*pc->p))
12781 || (allowhex && isxdigit(UCHAR(*pc->p)))
 
 
12782 || (allowdot && *pc->p == '.')
12783 || (pc->p - pc->tstart == 1 && *pc->tstart == '0' && (*pc->p == 'x' || *pc->p == 'X'))
12784 ) {
12785 if ((*pc->p == 'x') || (*pc->p == 'X')) {
12786 allowhex = 1;
12787 allowdot = 0;
12788 }
12789 if (*pc->p == '.') {
12790 allowdot = 0;
12791 pc->tt = JIM_TT_EXPR_DOUBLE;
12792 }
12793 pc->p++;
12794 pc->len--;
12795 if (!allowhex && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+'
12796 || isdigit(UCHAR(pc->p[1])))) {
12797 pc->p += 2;
12798 pc->len -= 2;
12799 pc->tt = JIM_TT_EXPR_DOUBLE;
12800 }
@@ -13183,29 +13380,39 @@
13183 case JIM_TT_ESC:
13184 case JIM_TT_VAR:
13185 case JIM_TT_DICTSUGAR:
13186 case JIM_TT_EXPRSUGAR:
13187 case JIM_TT_CMD:
13188 token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13189 token->type = t->type;
 
 
13190 if (t->type == JIM_TT_CMD) {
13191
13192 JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13193 }
13194 expr->len++;
13195 break;
13196
13197 case JIM_TT_EXPR_INT:
13198 token->objPtr = Jim_NewIntObj(interp, strtoull(t->token, NULL, 0));
13199 token->type = t->type;
13200 expr->len++;
13201 break;
13202
13203 case JIM_TT_EXPR_DOUBLE:
13204 token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, NULL));
13205 token->type = t->type;
13206 expr->len++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13207 break;
13208
13209 case JIM_TT_SUBEXPR_START:
13210 Jim_StackPush(&stack, t);
13211 prevtt = JIM_TT_NONE;
@@ -13984,13 +14191,15 @@
13984
13985 int base = descr->type == 'o' ? 8
13986 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
13987
13988
13989 w = strtoull(tok, &endp, base);
13990 if (endp == tok && base == 0) {
13991 w = strtoull(tok, &endp, 10);
 
 
13992 }
13993
13994 if (endp != tok) {
13995
13996 *valObjPtr = Jim_NewIntObj(interp, w);
@@ -14817,10 +15026,15 @@
14817 (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
14818 JimSetProcWrongArgs(interp, argv[0], cmd);
14819 return JIM_ERR;
14820 }
14821
 
 
 
 
 
14822
14823 if (interp->framePtr->level == interp->maxCallFrameDepth) {
14824 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
14825 return JIM_ERR;
14826 }
@@ -15079,78 +15293,49 @@
15079 Jim_DecrRefCount(interp, scriptObjPtr);
15080
15081 return retcode;
15082 }
15083
15084 static int JimParseSubstStr(struct JimParserCtx *pc)
15085 {
15086 pc->tstart = pc->p;
15087 pc->tline = pc->linenr;
15088 while (pc->len && *pc->p != '$' && *pc->p != '[') {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15089 if (*pc->p == '\\' && pc->len > 1) {
15090 pc->p++;
15091 pc->len--;
15092 }
15093 pc->p++;
15094 pc->len--;
15095 }
15096 pc->tend = pc->p - 1;
15097 pc->tt = JIM_TT_ESC;
15098 return JIM_OK;
15099 }
15100
15101 static int JimParseSubst(struct JimParserCtx *pc, int flags)
15102 {
15103 int retval;
15104
15105 if (pc->len == 0) {
15106 pc->tstart = pc->tend = pc->p;
15107 pc->tline = pc->linenr;
15108 pc->tt = JIM_TT_EOL;
15109 pc->eof = 1;
15110 return JIM_OK;
15111 }
15112 switch (*pc->p) {
15113 case '[':
15114 retval = JimParseCmd(pc);
15115 if (flags & JIM_SUBST_NOCMD) {
15116 pc->tstart--;
15117 pc->tend++;
15118 pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC;
15119 }
15120 return retval;
15121 break;
15122 case '$':
15123 if (JimParseVar(pc) == JIM_ERR) {
15124 pc->tstart = pc->tend = pc->p++;
15125 pc->len--;
15126 pc->tline = pc->linenr;
15127 pc->tt = JIM_TT_STR;
15128 }
15129 else {
15130 if (flags & JIM_SUBST_NOVAR) {
15131 pc->tstart--;
15132 if (flags & JIM_SUBST_NOESC)
15133 pc->tt = JIM_TT_STR;
15134 else
15135 pc->tt = JIM_TT_ESC;
15136 if (*pc->tstart == '{') {
15137 pc->tstart--;
15138 if (*(pc->tend + 1))
15139 pc->tend++;
15140 }
15141 }
15142 }
15143 break;
15144 default:
15145 retval = JimParseSubstStr(pc);
15146 if (flags & JIM_SUBST_NOESC)
15147 pc->tt = JIM_TT_STR;
15148 return retval;
15149 break;
15150 }
15151 return JIM_OK;
15152 }
15153
15154
15155 static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags)
15156 {
@@ -17173,10 +17358,13 @@
17173 OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE
17174 };
17175 static const char * const nocase_options[] = {
17176 "-nocase", NULL
17177 };
 
 
 
17178
17179 if (argc < 2) {
17180 Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?");
17181 return JIM_ERR;
17182 }
@@ -17200,27 +17388,58 @@
17200 Jim_SetResultInt(interp, len);
17201 return JIM_OK;
17202
17203 case OPT_COMPARE:
17204 case OPT_EQUAL:
17205 if (argc != 4 &&
17206 (argc != 5 ||
17207 Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL,
17208 JIM_ENUM_ABBREV) != JIM_OK)) {
17209 Jim_WrongNumArgs(interp, 2, argv, "?-nocase? string1 string2");
17210 return JIM_ERR;
17211 }
17212 if (opt_case == 0) {
17213 argv++;
17214 }
17215 if (option == OPT_COMPARE || !opt_case) {
17216 Jim_SetResultInt(interp, Jim_StringCompareObj(interp, argv[2], argv[3], !opt_case));
17217 }
17218 else {
17219 Jim_SetResultBool(interp, Jim_StringEqObj(argv[2], argv[3]));
17220 }
17221 return JIM_OK;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17222
17223 case OPT_MATCH:
17224 if (argc != 4 &&
17225 (argc != 5 ||
17226 Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL,
@@ -17281,11 +17500,11 @@
17281
17282 case OPT_REPLACE:{
17283 Jim_Obj *objPtr;
17284
17285 if (argc != 5 && argc != 6) {
17286 Jim_WrongNumArgs(interp, 2, argv, "string first last ?newstring?");
17287 return JIM_ERR;
17288 }
17289 objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL);
17290 if (objPtr == NULL) {
17291 return JIM_ERR;
@@ -17739,13 +17958,13 @@
17739
17740 listObjPtr = Jim_NewListObj(interp, NULL, 0);
17741
17742 htiter = Jim_GetHashTableIterator(&interp->references);
17743 while ((he = Jim_NextHashEntry(htiter)) != NULL) {
17744 char buf[JIM_REFERENCE_SPACE];
17745 Jim_Reference *refPtr = he->u.val;
17746 const jim_wide *refId = he->key;
17747
17748 JimFormatReference(buf, refPtr, *refId);
17749 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
17750 }
17751 Jim_FreeHashTableIterator(htiter);
@@ -17988,11 +18207,10 @@
17988 static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
17989 {
17990 int cmd;
17991 Jim_Obj *objPtr;
17992 int mode = 0;
17993 int nons = 0;
17994
17995 static const char * const commands[] = {
17996 "body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals",
17997 "vars", "version", "patchlevel", "complete", "args", "hostname",
17998 "script", "source", "stacktrace", "nameofexecutable", "returncodes",
@@ -18003,20 +18221,25 @@
18003 INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS,
18004 INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE,
18005 INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS
18006 };
18007
18008 if (argc < 2) {
18009 Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
18010 return JIM_ERR;
18011 }
18012 if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18013
18014 argc--;
18015 argv++;
18016 nons = 1;
18017 }
 
 
 
 
 
 
18018 if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
18019 != JIM_OK) {
18020 return JIM_ERR;
18021 }
18022
18023
--- autosetup/jimsh0.c
+++ autosetup/jimsh0.c
@@ -37,10 +37,11 @@
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_SYS_TIME_H
44 #define HAVE_DIRENT_H
45 #define HAVE_UNISTD_H
46 #endif
47 #ifndef JIM_WIN32COMPAT_H
@@ -532,10 +533,11 @@
533 structure. */
534 int local;
535 Jim_Obj *liveList;
536 Jim_Obj *freeList;
537 Jim_Obj *currentScriptObj;
538 Jim_Obj *nullScriptObj;
539 Jim_Obj *emptyObj;
540 Jim_Obj *trueObj;
541 Jim_Obj *falseObj;
542 unsigned long referenceNextId;
543 struct Jim_HashTable references;
@@ -1078,13 +1080,108 @@
1080 "\n"
1081 "\n"
1082 "\n"
1083 "\n"
1084 "\n"
1085 "\n"
1086 "\n"
1087 "package require readdir\n"
1088 "\n"
1089 "\n"
1090 "proc glob.globdir {dir pattern} {\n"
1091 " set result {}\n"
1092 " set files [readdir $dir]\n"
1093 " lappend files . ..\n"
1094 "\n"
1095 " foreach name $files {\n"
1096 " if {[string match $pattern $name]} {\n"
1097 "\n"
1098 " if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n"
1099 " continue\n"
1100 " }\n"
1101 " lappend result $name\n"
1102 " }\n"
1103 " }\n"
1104 "\n"
1105 " return $result\n"
1106 "}\n"
1107 "\n"
1108 "\n"
1109 "\n"
1110 "\n"
1111 "proc glob.explode {pattern} {\n"
1112 " set oldexp {}\n"
1113 " set newexp {\"\"}\n"
1114 "\n"
1115 " while 1 {\n"
1116 " set oldexp $newexp\n"
1117 " set newexp {}\n"
1118 " set ob [string first \\{ $pattern]\n"
1119 " set cb [string first \\} $pattern]\n"
1120 "\n"
1121 " if {$ob < $cb && $ob != -1} {\n"
1122 " set mid [string range $pattern 0 $ob-1]\n"
1123 " set subexp [lassign [glob.explode [string range $pattern $ob+1 end]] pattern]\n"
1124 " if {$pattern eq \"\"} {\n"
1125 " error \"unmatched open brace in glob pattern\"\n"
1126 " }\n"
1127 " set pattern [string range $pattern 1 end]\n"
1128 "\n"
1129 " foreach subs $subexp {\n"
1130 " foreach sub [split $subs ,] {\n"
1131 " foreach old $oldexp {\n"
1132 " lappend newexp $old$mid$sub\n"
1133 " }\n"
1134 " }\n"
1135 " }\n"
1136 " } elseif {$cb != -1} {\n"
1137 " set suf [string range $pattern 0 $cb-1]\n"
1138 " set rest [string range $pattern $cb end]\n"
1139 " break\n"
1140 " } else {\n"
1141 " set suf $pattern\n"
1142 " set rest \"\"\n"
1143 " break\n"
1144 " }\n"
1145 " }\n"
1146 "\n"
1147 " foreach old $oldexp {\n"
1148 " lappend newexp $old$suf\n"
1149 " }\n"
1150 " linsert $newexp 0 $rest\n"
1151 "}\n"
1152 "\n"
1153 "\n"
1154 "\n"
1155 "proc glob.glob {base pattern} {\n"
1156 " set dir [file dirname $pattern]\n"
1157 " if {$pattern eq $dir || $pattern eq \"\"} {\n"
1158 " return [list [file join $base $dir] $pattern]\n"
1159 " } elseif {$pattern eq [file tail $pattern]} {\n"
1160 " set dir \"\"\n"
1161 " }\n"
1162 "\n"
1163 "\n"
1164 " set dirlist [glob.glob $base $dir]\n"
1165 " set pattern [file tail $pattern]\n"
1166 "\n"
1167 "\n"
1168 " set result {}\n"
1169 " foreach {realdir dir} $dirlist {\n"
1170 " if {![file isdir $realdir]} {\n"
1171 " continue\n"
1172 " }\n"
1173 " if {[string index $dir end] ne \"/\" && $dir ne \"\"} {\n"
1174 " append dir /\n"
1175 " }\n"
1176 " foreach name [glob.globdir $realdir $pattern] {\n"
1177 " lappend result [file join $realdir $name] $dir$name\n"
1178 " }\n"
1179 " }\n"
1180 " return $result\n"
1181 "}\n"
1182 "\n"
1183 "\n"
1184 "\n"
1185 "\n"
1186 "\n"
1187 "\n"
@@ -1093,114 +1190,75 @@
1190 "\n"
1191 "\n"
1192 "\n"
1193 "\n"
1194 "proc glob {args} {\n"
1195 " set nocomplain 0\n"
1196 " set base \"\"\n"
1197 "\n"
1198 " set n 0\n"
1199 " foreach arg $args {\n"
1200 " if {[info exists param]} {\n"
1201 " set $param $arg\n"
1202 " unset param\n"
1203 " incr n\n"
1204 " continue\n"
1205 " }\n"
1206 " switch -glob -- $arg {\n"
1207 " -d* {\n"
1208 " set switch $arg\n"
1209 " set param base\n"
1210 " }\n"
1211 " -n* {\n"
1212 " set nocomplain 1\n"
1213 " }\n"
1214 " -t* {\n"
1215 "\n"
1216 " }\n"
1217 "\n"
1218 " -* {\n"
1219 " return -code error \"bad option \\\"$switch\\\": must be -directory, -nocomplain, -tails, or --\"\n"
1220 " }\n"
1221 " -- {\n"
1222 " incr n\n"
1223 " break\n"
1224 " }\n"
1225 " * {\n"
1226 " break\n"
1227 " }\n"
1228 " }\n"
1229 " incr n\n"
1230 " }\n"
1231 " if {[info exists param]} {\n"
1232 " return -code error \"missing argument to \\\"$switch\\\"\"\n"
1233 " }\n"
1234 " if {[llength $args] <= $n} {\n"
1235 " return -code error \"wrong # args: should be \\\"glob ?options? pattern ?pattern ...?\\\"\"\n"
1236 " }\n"
1237 "\n"
1238 " set args [lrange $args $n end]\n"
1239 "\n"
1240 " set result {}\n"
1241 " foreach pattern $args {\n"
1242 " set pattern [string map {\n"
1243 " \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n"
1244 " } $pattern]\n"
1245 " set patexps [lassign [glob.explode $pattern] rest]\n"
1246 " if {$rest ne \"\"} {\n"
1247 " return -code error \"unmatched close brace in glob pattern\"\n"
1248 " }\n"
1249 " foreach patexp $patexps {\n"
1250 " set patexp [string map {\n"
1251 " \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n"
1252 " } $patexp]\n"
1253 " foreach {realname name} [glob.glob $base $patexp] {\n"
1254 " lappend result $name\n"
1255 " }\n"
1256 " }\n"
1257 " }\n"
1258 "\n"
1259 " if {!$nocomplain && [llength $result] == 0} {\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1260 " return -code error \"no files matched glob patterns\"\n"
1261 " }\n"
1262 "\n"
1263 " return $result\n"
1264 "}\n"
@@ -1628,10 +1686,11 @@
1686 " file delete $path\n"
1687 "}\n"
1688 );
1689 }
1690
1691
1692
1693 #include <stdio.h>
1694 #include <string.h>
1695 #include <errno.h>
1696 #include <fcntl.h>
@@ -1651,10 +1710,17 @@
1710 #endif
1711
1712
1713 #define AIO_CMD_LEN 32
1714 #define AIO_BUF_LEN 256
1715
1716 #ifndef HAVE_FTELLO
1717 #define ftello ftell
1718 #endif
1719 #ifndef HAVE_FSEEKO
1720 #define fseeko fseek
1721 #endif
1722
1723 #define AIO_KEEPOPEN 1
1724
1725 #if defined(JIM_IPV6)
1726 #define IPV6 1
@@ -1935,10 +2001,22 @@
2001 }
2002 JimAioSetError(interp, af->filename);
2003 return JIM_ERR;
2004 }
2005
2006 static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2007 {
2008 #ifdef HAVE_ISATTY
2009 AioFile *af = Jim_CmdPrivData(interp);
2010 Jim_SetResultInt(interp, isatty(fileno(af->fp)));
2011 #else
2012 Jim_SetResultInt(interp, 0);
2013 #endif
2014
2015 return JIM_OK;
2016 }
2017
2018
2019 static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2020 {
2021 AioFile *af = Jim_CmdPrivData(interp);
2022
@@ -1965,11 +2043,11 @@
2043
2044 static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2045 {
2046 AioFile *af = Jim_CmdPrivData(interp);
2047 int orig = SEEK_SET;
2048 jim_wide offset;
2049
2050 if (argc == 2) {
2051 if (Jim_CompareStringImmediate(interp, argv[1], "start"))
2052 orig = SEEK_SET;
2053 else if (Jim_CompareStringImmediate(interp, argv[1], "current"))
@@ -1978,14 +2056,14 @@
2056 orig = SEEK_END;
2057 else {
2058 return -1;
2059 }
2060 }
2061 if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) {
2062 return JIM_ERR;
2063 }
2064 if (fseeko(af->fp, offset, orig) == -1) {
2065 JimAioSetError(interp, af->filename);
2066 return JIM_ERR;
2067 }
2068 return JIM_OK;
2069 }
@@ -1992,11 +2070,11 @@
2070
2071 static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2072 {
2073 AioFile *af = Jim_CmdPrivData(interp);
2074
2075 Jim_SetResultInt(interp, ftello(af->fp));
2076 return JIM_OK;
2077 }
2078
2079 static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2080 {
@@ -2167,10 +2245,17 @@
2245 "?-nonewline? str",
2246 aio_cmd_puts,
2247 1,
2248 2,
2249
2250 },
2251 { "isatty",
2252 NULL,
2253 aio_cmd_isatty,
2254 0,
2255 0,
2256
2257 },
2258 { "flush",
2259 NULL,
2260 aio_cmd_flush,
2261 0,
@@ -3048,11 +3133,13 @@
3133 static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3134 {
3135 const char *path = Jim_String(argv[0]);
3136 const char *p = strrchr(path, '/');
3137
3138 if (!p && path[0] == '.' && path[1] == '.' && path[2] == '\0') {
3139 Jim_SetResultString(interp, "..", -1);
3140 } else if (!p) {
3141 Jim_SetResultString(interp, ".", -1);
3142 }
3143 else if (p == path) {
3144 Jim_SetResultString(interp, "/", -1);
3145 }
@@ -3116,16 +3203,17 @@
3203 const char *path = Jim_String(argv[0]);
3204 char *newname = Jim_Alloc(MAXPATHLEN + 1);
3205
3206 if (realpath(path, newname)) {
3207 Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1));
3208 return JIM_OK;
3209 }
3210 else {
3211 Jim_Free(newname);
3212 Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno));
3213 return JIM_ERR;
3214 }
 
3215 #else
3216 Jim_SetResultString(interp, "Not implemented", -1);
3217 return JIM_ERR;
3218 #endif
3219 }
@@ -4934,11 +5022,11 @@
5022 return env;
5023 }
5024
5025 static void JimRestoreEnv(char **env)
5026 {
5027 JimFreeEnv(env, Jim_GetEnviron());
5028 }
5029
5030 static Jim_Obj *
5031 JimWinBuildCommandLine(Jim_Interp *interp, char **argv)
5032 {
@@ -5869,16 +5957,103 @@
5957 endptr++;
5958 }
5959 }
5960 return JIM_OK;
5961 }
5962
5963 static int JimNumberBase(const char *str, int *base, int *sign)
5964 {
5965 int i = 0;
5966
5967 *base = 10;
5968
5969 while (isspace(UCHAR(str[i]))) {
5970 i++;
5971 }
5972
5973 if (str[i] == '-') {
5974 *sign = -1;
5975 i++;
5976 }
5977 else {
5978 if (str[i] == '+') {
5979 i++;
5980 }
5981 *sign = 1;
5982 }
5983
5984 if (str[i] != '0') {
5985
5986 return 0;
5987 }
5988
5989
5990 switch (str[i + 1]) {
5991 case 'x': case 'X': *base = 16; break;
5992 case 'o': case 'O': *base = 8; break;
5993 case 'b': case 'B': *base = 2; break;
5994 default: return 0;
5995 }
5996 i += 2;
5997
5998 if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) {
5999
6000 return i;
6001 }
6002
6003 return 10;
6004 }
6005
6006 static long jim_strtol(const char *str, char **endptr)
6007 {
6008 int sign;
6009 int base;
6010 int i = JimNumberBase(str, &base, &sign);
6011
6012 if (base != 10) {
6013 long value = strtol(str + i, endptr, base);
6014 if (endptr == NULL || *endptr != str + i) {
6015 return value * sign;
6016 }
6017 }
6018
6019
6020 return strtol(str, endptr, 10);
6021 }
6022
6023
6024 static jim_wide jim_strtoull(const char *str, char **endptr)
6025 {
6026 #ifdef HAVE_LONG_LONG
6027 int sign;
6028 int base;
6029 int i = JimNumberBase(str, &base, &sign);
6030
6031 if (base != 10) {
6032 jim_wide value = strtoull(str + i, endptr, base);
6033 if (endptr == NULL || *endptr != str + i) {
6034 return value * sign;
6035 }
6036 }
6037
6038
6039 return strtoull(str, endptr, 10);
6040 #else
6041 return (unsigned long)jim_strtol(str, endptr);
6042 #endif
6043 }
6044
6045 int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
6046 {
6047 char *endptr;
6048
6049 if (base) {
6050 *widePtr = strtoull(str, &endptr, base);
6051 }
6052 else {
6053 *widePtr = jim_strtoull(str, &endptr);
6054 }
6055
6056 return JimCheckConversion(str, endptr);
6057 }
6058
6059 int Jim_DoubleToString(char *buf, double doubleValue)
@@ -7390,27 +7565,10 @@
7565 Jim_Free(objPtr->bytes);
7566 }
7567 objPtr->bytes = NULL;
7568 }
7569
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7570
7571 Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr)
7572 {
7573 Jim_Obj *dupPtr;
7574
@@ -7417,12 +7575,22 @@
7575 dupPtr = Jim_NewObj(interp);
7576 if (objPtr->bytes == NULL) {
7577
7578 dupPtr->bytes = NULL;
7579 }
7580 else if (objPtr->length == 0) {
7581
7582 dupPtr->bytes = JimEmptyStringRep;
7583 dupPtr->length = 0;
7584 dupPtr->typePtr = NULL;
7585 return dupPtr;
7586 }
7587 else {
7588 dupPtr->bytes = Jim_Alloc(objPtr->length + 1);
7589 dupPtr->length = objPtr->length;
7590
7591 memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1);
7592 }
7593
7594
7595 dupPtr->typePtr = objPtr->typePtr;
7596 if (objPtr->typePtr != NULL) {
@@ -7596,13 +7764,12 @@
7764
7765 Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len)
7766 {
7767 Jim_Obj *objPtr = Jim_NewObj(interp);
7768
7769 objPtr->bytes = s;
7770 objPtr->length = len == -1 ? strlen(s) : len;
 
7771 objPtr->typePtr = NULL;
7772 return objPtr;
7773 }
7774
7775 static void StringAppendString(Jim_Obj *objPtr, const char *str, int len)
@@ -7818,11 +7985,11 @@
7985
7986 if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) {
7987 return NULL;
7988 }
7989
7990 if (last < first) {
7991 return strObjPtr;
7992 }
7993
7994 str = Jim_String(strObjPtr);
7995
@@ -8169,19 +8336,19 @@
8336 Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj);
8337 }
8338
8339 void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
8340 {
8341 dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue;
8342 Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj);
8343 }
8344
8345 static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr,
8346 Jim_Obj *fileNameObj, int lineNumber)
8347 {
8348 JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object"));
8349 JimPanic((objPtr->typePtr == &sourceObjType, "JimSetSourceInfo called with non-source object"));
8350 Jim_IncrRefCount(fileNameObj);
8351 objPtr->internalRep.sourceValue.fileNameObj = fileNameObj;
8352 objPtr->internalRep.sourceValue.lineNumber = lineNumber;
8353 objPtr->typePtr = &sourceObjType;
8354 }
@@ -8557,13 +8724,16 @@
8724 return JIM_OK;
8725 }
8726
8727 ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr)
8728 {
8729 if (objPtr == interp->emptyObj) {
8730
8731 objPtr = interp->nullScriptObj;
8732 }
8733
8734 if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) {
8735 SetScriptFromAny(interp, objPtr, NULL);
8736 }
8737 return (ScriptObj *) Jim_GetIntRepPtr(objPtr);
8738 }
8739
@@ -10045,16 +10215,18 @@
10215 i->result = i->emptyObj;
10216 i->stackTrace = Jim_NewListObj(i, NULL, 0);
10217 i->unknown = Jim_NewStringObj(i, "unknown", -1);
10218 i->errorProc = i->emptyObj;
10219 i->currentScriptObj = Jim_NewEmptyStringObj(i);
10220 i->nullScriptObj = Jim_NewEmptyStringObj(i);
10221 Jim_IncrRefCount(i->emptyObj);
10222 Jim_IncrRefCount(i->errorFileNameObj);
10223 Jim_IncrRefCount(i->result);
10224 Jim_IncrRefCount(i->stackTrace);
10225 Jim_IncrRefCount(i->unknown);
10226 Jim_IncrRefCount(i->currentScriptObj);
10227 Jim_IncrRefCount(i->nullScriptObj);
10228 Jim_IncrRefCount(i->errorProc);
10229 Jim_IncrRefCount(i->trueObj);
10230 Jim_IncrRefCount(i->falseObj);
10231
10232
@@ -10084,10 +10256,11 @@
10256 Jim_DecrRefCount(i, i->stackTrace);
10257 Jim_DecrRefCount(i, i->errorProc);
10258 Jim_DecrRefCount(i, i->unknown);
10259 Jim_DecrRefCount(i, i->errorFileNameObj);
10260 Jim_DecrRefCount(i, i->currentScriptObj);
10261 Jim_DecrRefCount(i, i->nullScriptObj);
10262 Jim_FreeHashTable(&i->commands);
10263 #ifdef JIM_REFERENCES
10264 Jim_FreeHashTable(&i->references);
10265 #endif
10266 Jim_FreeHashTable(&i->packages);
@@ -10159,11 +10332,11 @@
10332 if (levelObjPtr) {
10333 str = Jim_String(levelObjPtr);
10334 if (str[0] == '#') {
10335 char *endptr;
10336
10337 level = jim_strtol(str + 1, &endptr);
10338 if (str[1] == '\0' || endptr[0] != '\0') {
10339 level = -1;
10340 }
10341 }
10342 else {
@@ -10822,13 +10995,11 @@
10995
10996 if (objPtr->typePtr == &listObjType) {
10997 return JIM_OK;
10998 }
10999
11000 if (Jim_IsDict(objPtr) && !Jim_IsShared(objPtr)) {
 
 
11001 Jim_Obj **listObjPtrPtr;
11002 int len;
11003 int i;
11004
11005 Jim_DictPairs(interp, objPtr, &listObjPtrPtr, &len);
@@ -10843,11 +11014,10 @@
11014 objPtr->internalRep.listValue.maxLen = len;
11015 objPtr->internalRep.listValue.ele = listObjPtrPtr;
11016
11017 return JIM_OK;
11018 }
 
11019
11020
11021 if (objPtr->typePtr == &sourceObjType) {
11022 fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
11023 linenr = objPtr->internalRep.sourceValue.lineNumber;
@@ -10866,20 +11036,22 @@
11036 objPtr->internalRep.listValue.len = 0;
11037 objPtr->internalRep.listValue.maxLen = 0;
11038 objPtr->internalRep.listValue.ele = NULL;
11039
11040
11041 if (strLen) {
11042 JimParserInit(&parser, str, strLen, linenr);
11043 while (!parser.eof) {
11044 Jim_Obj *elementPtr;
11045
11046 JimParseList(&parser);
11047 if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC)
11048 continue;
11049 elementPtr = JimParserGetTokenObj(interp, &parser);
11050 JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline);
11051 ListAppendElement(objPtr, elementPtr);
11052 }
11053 }
11054 Jim_DecrRefCount(interp, fileNameObj);
11055 return JIM_OK;
11056 }
11057
@@ -11682,11 +11854,11 @@
11854 end = 1;
11855 str += 3;
11856 idx = 0;
11857 }
11858 else {
11859 idx = jim_strtol(str, &endptr);
11860
11861 if (endptr == str) {
11862 goto badindex;
11863 }
11864 str = endptr;
@@ -11694,11 +11866,11 @@
11866
11867
11868 if (*str == '+' || *str == '-') {
11869 int sign = (*str == '+' ? 1 : -1);
11870
11871 idx += sign * jim_strtol(++str, &endptr);
11872 if (str == endptr || *endptr) {
11873 goto badindex;
11874 }
11875 str = endptr;
11876 }
@@ -12769,32 +12941,57 @@
12941 }
12942
12943 static int JimParseExprNumber(struct JimParserCtx *pc)
12944 {
12945 int allowdot = 1;
12946 int base = 10;
12947
12948
12949 pc->tt = JIM_TT_EXPR_INT;
12950 pc->tstart = pc->p;
12951 pc->tline = pc->linenr;
12952
12953
12954 if (pc->p[0] == '0') {
12955 switch (pc->p[1]) {
12956 case 'x':
12957 case 'X':
12958 base = 16;
12959 allowdot = 0;
12960 pc->p += 2;
12961 pc->len -= 2;
12962 break;
12963 case 'o':
12964 case 'O':
12965 base = 8;
12966 allowdot = 0;
12967 pc->p += 2;
12968 pc->len -= 2;
12969 break;
12970 case 'b':
12971 case 'B':
12972 base = 2;
12973 allowdot = 0;
12974 pc->p += 2;
12975 pc->len -= 2;
12976 break;
12977 }
12978 }
12979
12980 while (isdigit(UCHAR(*pc->p))
12981 || (base == 16 && isxdigit(UCHAR(*pc->p)))
12982 || (base == 8 && *pc->p >= '0' && *pc->p <= '7')
12983 || (base == 2 && (*pc->p == '0' || *pc->p == '1'))
12984 || (allowdot && *pc->p == '.')
 
12985 ) {
 
 
 
 
12986 if (*pc->p == '.') {
12987 allowdot = 0;
12988 pc->tt = JIM_TT_EXPR_DOUBLE;
12989 }
12990 pc->p++;
12991 pc->len--;
12992 if (base == 10 && (*pc->p == 'e' || *pc->p == 'E') && (pc->p[1] == '-' || pc->p[1] == '+'
12993 || isdigit(UCHAR(pc->p[1])))) {
12994 pc->p += 2;
12995 pc->len -= 2;
12996 pc->tt = JIM_TT_EXPR_DOUBLE;
12997 }
@@ -13183,29 +13380,39 @@
13380 case JIM_TT_ESC:
13381 case JIM_TT_VAR:
13382 case JIM_TT_DICTSUGAR:
13383 case JIM_TT_EXPRSUGAR:
13384 case JIM_TT_CMD:
 
13385 token->type = t->type;
13386 strexpr:
13387 token->objPtr = Jim_NewStringObj(interp, t->token, t->len);
13388 if (t->type == JIM_TT_CMD) {
13389
13390 JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line);
13391 }
13392 expr->len++;
13393 break;
13394
13395 case JIM_TT_EXPR_INT:
 
 
 
 
 
13396 case JIM_TT_EXPR_DOUBLE:
13397 {
13398 char *endptr;
13399 if (t->type == JIM_TT_EXPR_INT) {
13400 token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr));
13401 }
13402 else {
13403 token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr));
13404 }
13405 if (endptr != t->token + t->len) {
13406
13407 Jim_FreeNewObj(interp, token->objPtr);
13408 token->type = JIM_TT_STR;
13409 goto strexpr;
13410 }
13411 token->type = t->type;
13412 expr->len++;
13413 }
13414 break;
13415
13416 case JIM_TT_SUBEXPR_START:
13417 Jim_StackPush(&stack, t);
13418 prevtt = JIM_TT_NONE;
@@ -13984,13 +14191,15 @@
14191
14192 int base = descr->type == 'o' ? 8
14193 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10;
14194
14195
14196 if (base == 0) {
14197 w = jim_strtoull(tok, &endp);
14198 }
14199 else {
14200 w = strtoull(tok, &endp, base);
14201 }
14202
14203 if (endp != tok) {
14204
14205 *valObjPtr = Jim_NewIntObj(interp, w);
@@ -14817,10 +15026,15 @@
15026 (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) {
15027 JimSetProcWrongArgs(interp, argv[0], cmd);
15028 return JIM_ERR;
15029 }
15030
15031 if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) {
15032
15033 return JIM_OK;
15034 }
15035
15036
15037 if (interp->framePtr->level == interp->maxCallFrameDepth) {
15038 Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
15039 return JIM_ERR;
15040 }
@@ -15079,78 +15293,49 @@
15293 Jim_DecrRefCount(interp, scriptObjPtr);
15294
15295 return retcode;
15296 }
15297
15298 static void JimParseSubst(struct JimParserCtx *pc, int flags)
15299 {
15300 pc->tstart = pc->p;
15301 pc->tline = pc->linenr;
15302
15303 if (pc->len == 0) {
15304 pc->tend = pc->p;
15305 pc->tt = JIM_TT_EOL;
15306 pc->eof = 1;
15307 return;
15308 }
15309 if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) {
15310 JimParseCmd(pc);
15311 return;
15312 }
15313 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15314 if (JimParseVar(pc) == JIM_OK) {
15315 return;
15316 }
15317
15318 pc->tstart = pc->p;
15319 flags |= JIM_SUBST_NOVAR;
15320 }
15321 while (pc->len) {
15322 if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) {
15323 break;
15324 }
15325 if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) {
15326 break;
15327 }
15328 if (*pc->p == '\\' && pc->len > 1) {
15329 pc->p++;
15330 pc->len--;
15331 }
15332 pc->p++;
15333 pc->len--;
15334 }
15335 pc->tend = pc->p - 1;
15336 pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15337 }
15338
15339
15340 static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags)
15341 {
@@ -17173,10 +17358,13 @@
17358 OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE
17359 };
17360 static const char * const nocase_options[] = {
17361 "-nocase", NULL
17362 };
17363 static const char * const nocase_length_options[] = {
17364 "-nocase", "-length", NULL
17365 };
17366
17367 if (argc < 2) {
17368 Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?");
17369 return JIM_ERR;
17370 }
@@ -17200,27 +17388,58 @@
17388 Jim_SetResultInt(interp, len);
17389 return JIM_OK;
17390
17391 case OPT_COMPARE:
17392 case OPT_EQUAL:
17393 {
17394
17395 long opt_length = -1;
17396 int n = argc - 4;
17397 int i = 2;
17398 while (n > 0) {
17399 int subopt;
17400 if (Jim_GetEnum(interp, argv[i++], nocase_length_options, &subopt, NULL,
17401 JIM_ENUM_ABBREV) != JIM_OK) {
17402 badcompareargs:
17403 Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2");
17404 return JIM_ERR;
17405 }
17406 if (subopt == 0) {
17407
17408 opt_case = 0;
17409 n--;
17410 }
17411 else {
17412
17413 if (n < 2) {
17414 goto badcompareargs;
17415 }
17416 if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) {
17417 return JIM_ERR;
17418 }
17419 n -= 2;
17420 }
17421 }
17422 if (n) {
17423 goto badcompareargs;
17424 }
17425 argv += argc - 2;
17426 if (opt_length < 0 && option != OPT_COMPARE && opt_case) {
17427
17428 Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1]));
17429 }
17430 else {
17431 if (opt_length >= 0) {
17432 n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case);
17433 }
17434 else {
17435 n = Jim_StringCompareObj(interp, argv[0], argv[1], !opt_case);
17436 }
17437 Jim_SetResultInt(interp, option == OPT_COMPARE ? n : n == 0);
17438 }
17439 return JIM_OK;
17440 }
17441
17442 case OPT_MATCH:
17443 if (argc != 4 &&
17444 (argc != 5 ||
17445 Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL,
@@ -17281,11 +17500,11 @@
17500
17501 case OPT_REPLACE:{
17502 Jim_Obj *objPtr;
17503
17504 if (argc != 5 && argc != 6) {
17505 Jim_WrongNumArgs(interp, 2, argv, "string first last ?string?");
17506 return JIM_ERR;
17507 }
17508 objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL);
17509 if (objPtr == NULL) {
17510 return JIM_ERR;
@@ -17739,13 +17958,13 @@
17958
17959 listObjPtr = Jim_NewListObj(interp, NULL, 0);
17960
17961 htiter = Jim_GetHashTableIterator(&interp->references);
17962 while ((he = Jim_NextHashEntry(htiter)) != NULL) {
17963 char buf[JIM_REFERENCE_SPACE + 1];
17964 Jim_Reference *refPtr = he->u.val;
17965 const unsigned long *refId = he->key;
17966
17967 JimFormatReference(buf, refPtr, *refId);
17968 Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1));
17969 }
17970 Jim_FreeHashTableIterator(htiter);
@@ -17988,11 +18207,10 @@
18207 static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
18208 {
18209 int cmd;
18210 Jim_Obj *objPtr;
18211 int mode = 0;
 
18212
18213 static const char * const commands[] = {
18214 "body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals",
18215 "vars", "version", "patchlevel", "complete", "args", "hostname",
18216 "script", "source", "stacktrace", "nameofexecutable", "returncodes",
@@ -18003,20 +18221,25 @@
18221 INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS,
18222 INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE,
18223 INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS
18224 };
18225
18226 #ifdef jim_ext_namespace
18227 int nons = 0;
18228
 
18229 if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
18230
18231 argc--;
18232 argv++;
18233 nons = 1;
18234 }
18235 #endif
18236
18237 if (argc < 2) {
18238 Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
18239 return JIM_ERR;
18240 }
18241 if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
18242 != JIM_OK) {
18243 return JIM_ERR;
18244 }
18245
18246
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -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 by the corresponding
109
+# Each pattern of the form @define@ is replaced the the corresponding
110110
# define, if it exists, or left unchanged if not.
111111
#
112112
# The special value @srcdir@ is subsituted with the relative
113113
# path to the source directory from the directory where the output
114114
# file is created. Use @top_srcdir@ for the absolute path.
@@ -215,11 +215,12 @@
215215
define host [config_sub $host]
216216
set cross $host-
217217
}
218218
define cross [get-env CROSS $cross]
219219
220
-set prefix [opt-val prefix /usr/local]
220
+# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
221
+set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
221222
222223
# These are for compatibility with autoconf
223224
define target [get-define host]
224225
define prefix $prefix
225226
define builddir $autosetup(builddir)
@@ -252,11 +253,11 @@
252253
253254
define SHELL [get-env SHELL [find-an-executable sh bash ksh]]
254255
255256
# Windows vs. non-Windows
256257
switch -glob -- [get-define host] {
257
- *-*-ming* - *-*-cygwin {
258
+ *-*-ming* - *-*-cygwin - *-*-msys {
258259
define-feature windows
259260
define EXEEXT .exe
260261
}
261262
default {
262263
define EXEEXT ""
263264
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -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 by the corresponding
110 # define, if it exists, or left unchanged if not.
111 #
112 # The special value @srcdir@ is subsituted with the relative
113 # path to the source directory from the directory where the output
114 # file is created. Use @top_srcdir@ for the absolute path.
@@ -215,11 +215,12 @@
215 define host [config_sub $host]
216 set cross $host-
217 }
218 define cross [get-env CROSS $cross]
219
220 set prefix [opt-val prefix /usr/local]
 
221
222 # These are for compatibility with autoconf
223 define target [get-define host]
224 define prefix $prefix
225 define builddir $autosetup(builddir)
@@ -252,11 +253,11 @@
252
253 define SHELL [get-env SHELL [find-an-executable sh bash ksh]]
254
255 # Windows vs. non-Windows
256 switch -glob -- [get-define host] {
257 *-*-ming* - *-*-cygwin {
258 define-feature windows
259 define EXEEXT .exe
260 }
261 default {
262 define EXEEXT ""
263
--- autosetup/system.tcl
+++ autosetup/system.tcl
@@ -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 subsituted with the relative
113 # path to the source directory from the directory where the output
114 # file is created. Use @top_srcdir@ for the absolute path.
@@ -215,11 +215,12 @@
215 define host [config_sub $host]
216 set cross $host-
217 }
218 define cross [get-env CROSS $cross]
219
220 # Do "define defaultprefix myvalue" to set the default prefix *before* the first "use"
221 set prefix [opt-val prefix [get-define defaultprefix /usr/local]]
222
223 # These are for compatibility with autoconf
224 define target [get-define host]
225 define prefix $prefix
226 define builddir $autosetup(builddir)
@@ -252,11 +253,11 @@
253
254 define SHELL [get-env SHELL [find-an-executable sh bash ksh]]
255
256 # Windows vs. non-Windows
257 switch -glob -- [get-define host] {
258 *-*-ming* - *-*-cygwin - *-*-msys {
259 define-feature windows
260 define EXEEXT .exe
261 }
262 default {
263 define EXEEXT ""
264

Keyboard Shortcuts

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