diff options
author | Steve Bennett <steveb@workware.net.au> | 2017-04-22 20:30:59 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2017-04-22 20:31:22 +1000 |
commit | 31a9f433f06b8cc426d281436a628a5fdd3bf755 (patch) | |
tree | 42ebfbbcc964f60a8432b3b42f2880db44926287 | |
parent | a9c149f459c9711ce5e36efa7f4eca1fe57622d9 (diff) | |
download | jimtcl-31a9f433f06b8cc426d281436a628a5fdd3bf755.zip jimtcl-31a9f433f06b8cc426d281436a628a5fdd3bf755.tar.gz jimtcl-31a9f433f06b8cc426d281436a628a5fdd3bf755.tar.bz2 |
build: Update autosetup to v0.6.6-8-g062d650
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | auto.def | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | autosetup/LICENSE | 0 | ||||
-rw-r--r-- | autosetup/README.autosetup | 12 | ||||
-rwxr-xr-x | autosetup/autosetup | 690 | ||||
-rwxr-xr-x | autosetup/autosetup-config.guess (renamed from autosetup/config.guess) | 0 | ||||
-rwxr-xr-x | autosetup/autosetup-config.sub (renamed from autosetup/config.sub) | 0 | ||||
-rwxr-xr-x | autosetup/autosetup-find-tclsh (renamed from autosetup/find-tclsh) | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | autosetup/autosetup-test-tclsh (renamed from autosetup/test-tclsh) | 0 | ||||
-rw-r--r-- | autosetup/cc-db.tcl | 4 | ||||
-rw-r--r-- | autosetup/cc-lib.tcl | 150 | ||||
-rw-r--r-- | autosetup/cc.tcl | 78 | ||||
-rwxr-xr-x[-rw-r--r--] | autosetup/jimsh0.c | 3921 | ||||
-rw-r--r-- | autosetup/pkg-config.tcl | 35 | ||||
-rw-r--r-- | autosetup/system.tcl | 87 | ||||
-rw-r--r-- | autosetup/tmake.tcl | 6 | ||||
-rwxr-xr-x | configure | 2 |
16 files changed, 2670 insertions, 2323 deletions
@@ -4,7 +4,7 @@ define JIM_VERSION 77 # Note: modules which support options *must* be included before 'options' -use cc cc-shared cc-db cc-lib pkg-config +use cc cc-shared cc-db cc-lib pkg-config util use local options { diff --git a/autosetup/LICENSE b/autosetup/LICENSE index 4fe636c..4fe636c 100644..100755 --- a/autosetup/LICENSE +++ b/autosetup/LICENSE diff --git a/autosetup/README.autosetup b/autosetup/README.autosetup index 54ddb4b..590842d 100644 --- a/autosetup/README.autosetup +++ b/autosetup/README.autosetup @@ -1 +1,11 @@ -This is autosetup v0.6.6. See http://msteveb.github.com/autosetup/ +README.autosetup created by autosetup v0.6.7 + +This is the autosetup directory for a local install of autosetup. +It contains autosetup, support files and loadable modules. + +*.tcl files in this directory are optional modules which +can be loaded with the 'use' directive. + +*.auto files in this directory are auto-loaded. + +For more information, see http://msteveb.github.com/autosetup/ diff --git a/autosetup/autosetup b/autosetup/autosetup index 5b90323..2fba5c8 100755 --- a/autosetup/autosetup +++ b/autosetup/autosetup @@ -3,12 +3,12 @@ # All rights reserved # vim:se syntax=tcl: # \ -dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@" +dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@" -set autosetup(version) 0.6.6 +set autosetup(version) 0.6.7 # Can be set to 1 to debug early-init problems -set autosetup(debug) 0 +set autosetup(debug) [expr {"--debug" in $argv}] ################################################################## # @@ -89,11 +89,13 @@ proc main {argv} { #"=Core Options:" options-add { help:=local => "display help and options. Optionally specify a module name, such as --help=system" + licence license => "display the autosetup license" version => "display the version of autosetup" ref:=text manual:=text reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" debug => "display debugging output as autosetup runs" - install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)" + sysinstall: => "install standalone autosetup to the given directory (e.g.: /usr/local)" + install:=. => "install autosetup to the current or given directory" force init:=help => "create initial auto.def, etc. Use --init=help for known types" # Undocumented options option-checking=1 @@ -110,7 +112,7 @@ proc main {argv} { # autosetup --conf=alternate-auto.def if {[opt-val conf] ne ""} { - set autosetup(autodef) [opt-val conf] + set autosetup(autodef) [lindex [opt-val conf] end] } # Debugging output (set this early) @@ -126,38 +128,47 @@ proc main {argv} { } # Now any auto-load modules - foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { - automf_load source $file - } + autosetup_load_auto_modules if {[opt-val help] ne ""} { incr autosetup(showhelp) use help - autosetup_help [opt-val help] + autosetup_help [lindex [opt-val help] end] + } + + if {[opt-bool licence license]} { + use help + autosetup_show_license + exit 0 } if {[opt-val {manual ref reference}] ne ""} { use help - autosetup_reference [opt-val {manual ref reference}] + autosetup_reference [lindex [opt-val {manual ref reference}] end] } # Allow combining --install and --init set earlyexit 0 if {[opt-val install] ne ""} { use install - autosetup_install [opt-val install] + autosetup_install [lindex [opt-val install] end] incr earlyexit } if {[opt-val init] ne ""} { use init - autosetup_init [opt-val init] + autosetup_init [lindex [opt-val init] end] incr earlyexit } if {$earlyexit} { exit 0 } + if {[opt-val sysinstall] ne ""} { + use install + autosetup_install [lindex [opt-val sysinstall] end] 1 + exit 0 + } if {![file exists $autosetup(autodef)]} { # Check for invalid option first @@ -212,10 +223,10 @@ proc main {argv} { # or disabled by the user, return 1 or 0 accordingly. # # If the option was specified more than once, the last value wins. -# e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0 +# e.g. With '--enable-foo --disable-foo', '[opt-bool foo]' will return 0 # # If no value was specified by the user, returns the default value for the -# first option. If -nodefault is given, this behaviour changes and +# first option. If '-nodefault' is given, this behaviour changes and # -1 is returned instead. # proc opt-bool {args} { @@ -239,16 +250,16 @@ proc opt-bool {args} { return [dict get $::autosetup(optdefault) [lindex $args 0]] } -# @opt-val option-list ?default=""? +# @opt-val optionlist ?default=""? # -# Returns a list containing all the values given for the non-boolean options in 'option-list'. +# Returns a list containing all the values given for the non-boolean options in '$optionlist'. # There will be one entry in the list for each option given by the user, including if the # same option was used multiple times. # If only a single value is required, use something like: # ## lindex [opt-val $names] end # -# If no options were set, $default is returned (exactly, not as a list). +# If no options were set, '$default' is returned (exactly, not as a list). # proc opt-val {names {default ""}} { option-check-names {*}$names @@ -465,31 +476,32 @@ proc options-show {} { } } -# @options options-spec +# @options optionspec # # Specifies configuration-time options which may be selected by the user -# and checked with opt-val and opt-bool. The format of options-spec follows. +# and checked with 'opt-val' and 'opt-bool'. '$optionspec' contains a series +# of options specifications separated by newlines, as follows: # # A boolean option is of the form: # ## name[=0|1] => "Description of this boolean option" # -# The default is name=0, meaning that the option is disabled by default. -# If name=1 is used to make the option enabled by default, the description should reflect +# The default is 'name=0', meaning that the option is disabled by default. +# If 'name=1' is used to make the option enabled by default, the description should reflect # that with text like "Disable support for ...". # # An argument option (one which takes a parameter) is of the form: # ## name:[=]value => "Description of this option" # -# If the name:value form is used, the value must be provided with the option (as --name=myvalue). -# If the name:=value form is used, the value is optional and the given value is used as the default +# If the 'name:value' form is used, the value must be provided with the option (as '--name=myvalue'). +# If the 'name:=value' form is used, the value is optional and the given value is used as the default # if it is not provided. # -# Undocumented options are also supported by omitting the "=> description. -# These options are not displayed with --help and can be useful for internal options or as aliases. +# Undocumented options are also supported by omitting the '=> description'. +# These options are not displayed with '--help' and can be useful for internal options or as aliases. # -# For example, --disable-lfs is an alias for --disable=largefile: +# For example, '--disable-lfs' is an alias for '--disable=largefile': # ## lfs=1 largefile=1 => "Disable large file support" # @@ -513,21 +525,20 @@ proc options {optlist} { } proc config_guess {} { - if {[file-isexec $::autosetup(dir)/config.guess]} { - exec-with-stderr sh $::autosetup(dir)/config.guess - if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} { + if {[file-isexec $::autosetup(dir)/autosetup-config.guess]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.guess} alias]} { user-error $alias } return $alias } else { - configlog "No config.guess, so using uname" + configlog "No autosetup-config.guess, so using uname" string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r] } } proc config_sub {alias} { - if {[file-isexec $::autosetup(dir)/config.sub]} { - if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} { + if {[file-isexec $::autosetup(dir)/autosetup-config.sub]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.sub $alias} alias]} { user-error $alias } } @@ -538,7 +549,7 @@ proc config_sub {alias} { # # Defines the named variable to the given value. # These (name, value) pairs represent the results of the configuration check -# and are available to be checked, modified and substituted. +# and are available to be subsequently checked, modified and substituted. # proc define {name {value 1}} { set ::define($name) $value @@ -547,7 +558,7 @@ proc define {name {value 1}} { # @undefine name # -# Undefine the named variable +# Undefine the named variable. # proc undefine {name} { unset -nocomplain ::define($name) @@ -556,8 +567,8 @@ proc undefine {name} { # @define-append name value ... # -# Appends the given value(s) to the given 'defined' variable. -# If the variable is not defined or empty, it is set to $value. +# Appends the given value(s) to the given "defined" variable. +# If the variable is not defined or empty, it is set to '$value'. # Otherwise the value is appended, separated by a space. # Any extra values are similarly appended. # If any value is already contained in the variable (as a substring) it is omitted. @@ -578,7 +589,7 @@ proc define-append {name args} { # @get-define name ?default=0? # -# Returns the current value of the 'defined' variable, or $default +# Returns the current value of the "defined" variable, or '$default' # if not set. # proc get-define {name {default 0}} { @@ -600,7 +611,7 @@ proc is-defined {name} { # @all-defines # -# Returns a dictionary (name value list) of all defined variables. +# Returns a dictionary (name, value list) of all defined variables. # # This is suitable for use with 'dict', 'array set' or 'foreach' # and allows for arbitrary processing of the defined variables. @@ -612,9 +623,9 @@ proc all-defines {} { # @get-env name default # -# If $name was specified on the command line, return it. -# If $name was set in the environment, return it. -# Otherwise return $default. +# If '$name' was specified on the command line, return it. +# Otherwise if '$name' was set in the environment, return it. +# Otherwise return '$default'. # proc get-env {name default} { if {[dict exists $::autosetup(cmdline) $name]} { @@ -625,7 +636,7 @@ proc get-env {name default} { # @env-is-set name # -# Returns 1 if the $name was specified on the command line or in the environment. +# Returns 1 if '$name' was specified on the command line or in the environment. # Note that an empty environment variable is not considered to be set. # proc env-is-set {name} { @@ -641,7 +652,7 @@ proc env-is-set {name} { # @readfile filename ?default=""? # # Return the contents of the file, without the trailing newline. -# If the file doesn't exist or can't be read, returns $default. +# If the file doesn't exist or can't be read, returns '$default'. # proc readfile {filename {default_value ""}} { set result $default_value @@ -655,7 +666,7 @@ proc readfile {filename {default_value ""}} { # @writefile filename value # -# Creates the given file containing $value. +# Creates the given file containing '$value'. # Does not add an extra newline. # proc writefile {filename value} { @@ -679,40 +690,10 @@ proc quote-argv {argv} { join $args } -# @suffix suf list -# -# Takes a list and returns a new list with $suf appended -# to each element -# -## suffix .c {a b c} => {a.c b.c c.c} -# -proc suffix {suf list} { - set result {} - foreach p $list { - lappend result $p$suf - } - return $result -} - -# @prefix pre list -# -# Takes a list and returns a new list with $pre prepended -# to each element -# -## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} -# -proc prefix {pre list} { - set result {} - foreach p $list { - lappend result $pre$p - } - return $result -} - # @find-executable name # # Searches the path for an executable with the given name. -# Note that the name may include some parameters, e.g. "cc -mbig-endian", +# Note that the name may include some parameters, e.g. 'cc -mbig-endian', # in which case the parameters are ignored. # Returns 1 if found, or 0 if not. # @@ -766,7 +747,7 @@ proc find-an-executable {args} { # @configlog msg # -# Writes the given message to the configuration log, config.log +# Writes the given message to the configuration log, 'config.log'. # proc configlog {msg} { if {![info exists ::autosetup(logfh)]} { @@ -802,8 +783,8 @@ proc msg-result {msg} { # @msg-quiet command ... # -# msg-quiet evaluates it's arguments as a command with output -# from msg-checking and msg-result suppressed. +# 'msg-quiet' evaluates it's arguments as a command with output +# from 'msg-checking' and 'msg-result' suppressed. # # This is useful if a check needs to run a subcheck which isn't # of interest to the user. @@ -843,7 +824,7 @@ proc dputs {msg} { # # Indicate incorrect usage to the user, including if required components # or features are not found. -# autosetup exits with a non-zero return code. +# 'autosetup' exits with a non-zero return code. # proc user-error {msg} { show-notices @@ -890,6 +871,18 @@ proc maybe-show-timestamp {} { } } +# @autosetup-require-version required +# +# Checks the current version of 'autosetup' against '$required'. +# A fatal error is generated if the current version is less than that required. +# +proc autosetup-require-version {required} { + use util + if {[compare-versions $::autosetup(version) $required] < 0} { + user-error "autosetup version $required is required, but this is $::autosetup(version)" + } +} + proc autosetup_version {} { return "autosetup v$::autosetup(version)" } @@ -988,19 +981,31 @@ proc autosetup_add_dep {filename} { # when it is loaded. # proc use {args} { + global autosetup libmodule modsource + + set dirs [list $autosetup(libdir)] + if {[info exists autosetup(srcdir)]} { + lappend dirs $autosetup(srcdir)/autosetup + } foreach m $args { - if {[info exists ::libmodule($m)]} { + if {[info exists libmodule($m)]} { continue } - set ::libmodule($m) 1 - if {[info exists ::modsource($m)]} { - automf_load eval $::modsource($m) + set libmodule($m) 1 + if {[info exists modsource(${m}.tcl)]} { + automf_load eval $modsource(${m}.tcl) } else { - set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl] + set locs [list ${m}.tcl ${m}/init.tcl] set found 0 - foreach source $sources { - if {[file exists $source]} { - incr found + foreach dir $dirs { + foreach loc $locs { + set source $dir/$loc + if {[file exists $source]} { + incr found + break + } + } + if {$found} { break } } @@ -1017,6 +1022,18 @@ proc use {args} { } } +proc autosetup_load_auto_modules {} { + global autosetup modsource + # First load any embedded auto modules + foreach mod [array names modsource *.auto] { + automf_load eval $modsource($mod) + } + # Now any external auto modules + foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { + automf_load source $file + } +} + # Load module source in the global scope by executing the given command proc automf_load {args} { if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { @@ -1029,14 +1046,17 @@ set autosetup(exe) $::argv0 set autosetup(istcl) 1 set autosetup(start) [clock millis] set autosetup(installed) 0 +set autosetup(sysinstall) 0 set autosetup(msg-checking) 0 set autosetup(msg-quiet) 0 +set autosetup(inittypes) {} # Embedded modules are inserted below here set autosetup(installed) 1 -# ----- module asciidoc-formatting ----- +set autosetup(sysinstall) 0 +# ----- @module asciidoc-formatting.tcl ----- -set modsource(asciidoc-formatting) { +set modsource(asciidoc-formatting.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1104,9 +1124,9 @@ proc defn {first args} { } } -# ----- module formatting ----- +# ----- @module formatting.tcl ----- -set modsource(formatting) { +set modsource(formatting.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1161,9 +1181,9 @@ proc parse_code_block {text} { } } -# ----- module getopt ----- +# ----- @module getopt.tcl ----- -set modsource(getopt) { +set modsource(getopt.tcl) { # Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1220,9 +1240,9 @@ proc getopt {argvname} { } } -# ----- module help ----- +# ----- @module help.tcl ----- -set modsource(help) { +set modsource(help.tcl) { # Copyright (c) 2010 WorkWare Systems http://workware.net.au/ # All rights reserved @@ -1254,6 +1274,24 @@ proc autosetup_help {what} { exit 0 } +proc autosetup_show_license {} { + global modsource autosetup + use_pager + + if {[info exists modsource(LICENSE)]} { + puts $modsource(LICENSE) + return + } + foreach dir [list $autosetup(libdir) $autosetup(srcdir)] { + set path [file join $dir LICENSE] + if {[file exists $path]} { + puts [readfile $path] + return + } + } + puts "LICENSE not found" +} + # If not already paged and stdout is a tty, pipe the output through the pager # This is done by reinvoking autosetup with --nopager added proc use_pager {} { @@ -1306,6 +1344,12 @@ proc autosetup_reference {{type text}} { proc autosetup_output_block {type lines} { if {[llength $lines]} { switch $type { + section { + section $lines + } + subsection { + subsection $lines + } code { codelines $lines } @@ -1327,16 +1371,30 @@ proc automf_command_reference {} { lappend files $::autosetup(prog) lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]] - section "Core Commands" - set type p - set lines {} - set cmd {} + # We want to process all non-module files before module files + # and then modules in alphabetical order. + # So examine all files and extract docs into doc($modulename) and doc(_core_) + # + # Each entry is a list of {type data} where $type is one of: section, subsection, code, list, p + # and $data is a string for section, subsection or a list of text lines for other types. + + # XXX: Should commands be in alphabetical order too? Currently they are in file order. + + set doc(_core_) {} + lappend doc(_core_) [list section "Core Commands"] foreach file $files { + set modulename [file rootname [file tail $file]] + set current _core_ set f [open $file] while {![eof $f]} { set line [gets $f] + # Find embedded module names + if {[regexp {^#.*@module ([^ ]*)} $line -> modulename]} { + continue + } + # Find lines starting with "# @*" and continuing through the remaining comment lines if {![regexp {^# @(.*)} $line -> cmd]} { continue @@ -1344,9 +1402,10 @@ proc automf_command_reference {} { # Synopsis or command? if {$cmd eq "synopsis:"} { - section "Module: [file rootname [file tail $file]]" + set current $modulename + lappend doc($current) [list section "Module: $modulename"] } else { - subsection $cmd + lappend doc($current) [list subsection $cmd] } set lines {} @@ -1371,7 +1430,7 @@ proc automf_command_reference {} { if {$t ne $type || $cmd eq ""} { # Finish the current block - autosetup_output_block $type $lines + lappend doc($current) [list $type $lines] set lines {} set type $t } @@ -1380,16 +1439,25 @@ proc automf_command_reference {} { } } - autosetup_output_block $type $lines + lappend doc($current) [list $type $lines] } close $f } + + # Now format and output the results + + # _core_ will sort first + foreach module [lsort [array names doc]] { + foreach item $doc($module) { + autosetup_output_block {*}$item + } + } } } -# ----- module init ----- +# ----- @module init.tcl ----- -set modsource(init) { +set modsource(init.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1446,22 +1514,55 @@ proc autosetup_check_create {filename contents} { } } -# ----- module install ----- +# ----- @module install.tcl ----- -set modsource(install) { +set modsource(install.tcl) { # Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which can install autosetup -proc autosetup_install {dir} { - if {[catch { +# autosetup(installed)=1 means that autosetup is not running from source +# autosetup(sysinstall)=1 means that autosetup is running from a sysinstall verion +# shared=1 means that we are trying to do a sysinstall. This is only possible from the development source. + +proc autosetup_install {dir {shared 0}} { + if {$shared && $::autosetup(installed)} { + user-error "Can only --sysinstall from development sources" + } + + if {$::autosetup(sysinstall)} { + # This is the sysinstall version, so install just uses references cd $dir + + puts "[autosetup_version] creating configure to use system-installed autosetup" + autosetup_create_configure 1 + puts "Creating autosetup/README.autosetup" file mkdir autosetup + autosetup_install_readme autosetup/README.autosetup 1 + return + } + + if {[catch { + if {$shared} { + set target $dir/bin/autosetup + set installedas $target + } else { + if {$dir eq "."} { + set installedas autosetup + } else { + set installedas $dir/autosetup + } + cd $dir + file mkdir autosetup + set target autosetup/autosetup + } + set targetdir [file dirname $target] + file mkdir $targetdir - set f [open autosetup/autosetup w] + set f [open $target w] - set publicmodules [glob $::autosetup(libdir)/*.auto] + set publicmodules {} # First the main script, but only up until "CUT HERE" set in [open $::autosetup(dir)/autosetup] @@ -1473,48 +1574,89 @@ proc autosetup_install {dir} { # Insert the static modules here # i.e. those which don't contain @synopsis: + # All modules are inserted if $shared is set puts $f "set autosetup(installed) 1" - foreach file [lsort [glob $::autosetup(libdir)/*.tcl]] { + puts $f "set autosetup(sysinstall) $shared" + foreach file [lsort [glob $::autosetup(libdir)/*.{tcl,auto}]] { + set modname [file tail $file] + set ext [file ext $modname] set buf [readfile $file] - if {[string match "*\n# @synopsis:*" $buf]} { - lappend publicmodules $file - continue + if {!$shared} { + if {$ext eq ".auto" || [string match "*\n# @synopsis:*" $buf]} { + lappend publicmodules $file + continue + } } - set modname [file rootname [file tail $file]] - puts $f "# ----- module $modname -----" + dputs "install: importing lib/[file tail $file]" + puts $f "# ----- @module $modname -----" puts $f "\nset modsource($modname) \{" puts $f $buf puts $f "\}\n" } + if {$shared} { + foreach {srcname destname} [list $::autosetup(libdir)/README.autosetup-lib README.autosetup \ + $::autosetup(srcdir)/LICENSE LICENSE] { + dputs "install: importing $srcname as $destname" + puts $f "\nset modsource($destname) \\\n[list [readfile $srcname]\n]\n" + } + } } close $in close $f - exec chmod 755 autosetup/autosetup + exec chmod 755 $target + + set installfiles {autosetup-config.guess autosetup-config.sub autosetup-test-tclsh} + set removefiles {} - # Install public modules - foreach file $publicmodules { - autosetup_install_file $file autosetup + if {!$shared} { + autosetup_install_readme $targetdir/README.autosetup 0 + + # Install public modules + foreach file $publicmodules { + set tail [file tail $file] + autosetup_install_file $file $targetdir/$tail + } + lappend installfiles jimsh0.c autosetup-find-tclsh LICENSE + lappend removefiles config.guess config.sub test-tclsh find-tclsh + } else { + lappend installfiles {sys-find-tclsh autosetup-find-tclsh} } # Install support files - foreach file {config.guess config.sub jimsh0.c find-tclsh test-tclsh LICENSE} { - autosetup_install_file $::autosetup(dir)/$file autosetup + foreach fileinfo $installfiles { + if {[llength $fileinfo] == 2} { + lassign $fileinfo source dest + } else { + lassign $fileinfo source + set dest $source + } + autosetup_install_file $::autosetup(dir)/$source $targetdir/$dest + exec chmod 755 $targetdir/$dest } - exec chmod 755 autosetup/config.sub autosetup/config.guess autosetup/find-tclsh - - writefile autosetup/README.autosetup \ - "This is [autosetup_version]. See http://msteveb.github.com/autosetup/\n" + # Remove obsolete files + foreach file $removefiles { + if {[file exists $targetdir/$file]} { + file delete $targetdir/$file + } + } } error]} { user-error "Failed to install autosetup: $error" } - puts "Installed [autosetup_version] to autosetup/" + if {$shared} { + set type "system" + } else { + set type "local" + } + puts "Installed $type [autosetup_version] to $installedas" - # Now create 'configure' if necessary - autosetup_create_configure + if {!$shared} { + # Now create 'configure' if necessary + autosetup_create_configure 0 + } } -proc autosetup_create_configure {} { +proc autosetup_create_configure {shared} { if {[file exists configure]} { if {!$::autosetup(force)} { # Could this be an autosetup configure? @@ -1529,36 +1671,68 @@ proc autosetup_create_configure {} { } else { puts "I don't see configure, so I will create it." } - writefile configure \ + if {$shared} { + writefile configure \ +{#!/bin/sh +# Note that WRAPPER is set here purely to detect an autosetup-created script +WRAPPER="-"; "autosetup" "$@" +} + } else { + writefile configure \ {#!/bin/sh dir="`dirname "$0"`/autosetup" -WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@" +WRAPPER="$0"; export WRAPPER; exec "`$dir/autosetup-find-tclsh`" "$dir/autosetup" "$@" } + } catch {exec chmod 755 configure} } # Append the contents of $file to filehandle $f proc autosetup_install_append {f file} { + dputs "install: include $file" set in [open $file] puts $f [read $in] close $in } -proc autosetup_install_file {file dir} { - if {![file exists $file]} { - error "Missing installation file '$file'" +proc autosetup_install_file {source target} { + dputs "install: $source => $target" + if {![file exists $source]} { + error "Missing installation file '$source'" } - writefile [file join $dir [file tail $file]] [readfile $file]\n + writefile $target [readfile $source]\n +} + +proc autosetup_install_readme {target sysinstall} { + set readme "README.autosetup created by [autosetup_version]\n\n" + if {$sysinstall} { + append readme \ +{This is the autosetup directory for a system install of autosetup. +Loadable modules can be added here. +} + } else { + append readme \ +{This is the autosetup directory for a local install of autosetup. +It contains autosetup, support files and loadable modules. +} } -if {$::autosetup(installed)} { - user-error "autosetup can only be installed from development source, not from installed copy" + append readme { +*.tcl files in this directory are optional modules which +can be loaded with the 'use' directive. + +*.auto files in this directory are auto-loaded. + +For more information, see http://msteveb.github.com/autosetup/ +} + dputs "install: autosetup/README.autosetup" + writefile $target $readme } } -# ----- module markdown-formatting ----- +# ----- @module markdown-formatting.tcl ----- -set modsource(markdown-formatting) { +set modsource(markdown-formatting.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1629,9 +1803,9 @@ proc defn {first args} { } } -# ----- module misc ----- +# ----- @module misc.tcl ----- -set modsource(misc) { +set modsource(misc.tcl) { # Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1807,9 +1981,9 @@ proc error-dump {msg opts fulltrace} { } } -# ----- module text-formatting ----- +# ----- @module text-formatting.tcl ----- -set modsource(text-formatting) { +set modsource(text-formatting.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1818,91 +1992,193 @@ set modsource(text-formatting) { use formatting proc wordwrap {text length {firstprefix ""} {nextprefix ""}} { - set len 0 - set space $firstprefix - foreach word [split $text] { - set word [string trim $word] - if {$word == ""} { - continue - } - if {$len && [string length $space$word] + $len >= $length} { - puts "" - set len 0 - set space $nextprefix - } - incr len [string length $space$word] - - # Use man-page conventions for highlighting 'quoted' and *quoted* - # single words. - # Use x^Hx for *bold* and _^Hx for 'underline'. - # - # less and more will both understand this. - # Pipe through 'col -b' to remove them. - if {[regexp {^'(.*)'([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { - regsub -all . $bareword "_\b&" word - append word $dot - } elseif {[regexp {^[*](.*)[*]([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { - regsub -all . $bareword "&\b&" word - append word $dot - } - puts -nonewline $space$word - set space " " - } - if {$len} { - puts "" - } + set len 0 + set space $firstprefix + + foreach word [split $text] { + set word [string trim $word] + if {$word eq ""} { + continue + } + if {[info exists partial]} { + append partial " " $word + if {[string first $quote $word] < 0} { + # Haven't found end of quoted word + continue + } + # Finished quoted word + set word $partial + unset partial + unset quote + } else { + set quote [string index $word 0] + if {$quote in {' *}} { + if {[string first $quote $word 1] < 0} { + # Haven't found end of quoted word + # Not a whole word. + set first [string index $word 0] + # Start of quoted word + set partial $word + continue + } + } + } + + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + + # Use man-page conventions for highlighting 'quoted' and *quoted* + # single words. + # Use x^Hx for *bold* and _^Hx for 'underline'. + # + # less and more will both understand this. + # Pipe through 'col -b' to remove them. + if {[regexp {^'(.*)'(.*)} $word -> quoted after]} { + set quoted [string map {~ " "} $quoted] + regsub -all . $quoted "&\b&" quoted + set word $quoted$after + } elseif {[regexp {^[*](.*)[*](.*)} $word -> quoted after]} { + set quoted [string map {~ " "} $quoted] + regsub -all . $quoted "_\b&" quoted + set word $quoted$after + } + puts -nonewline $space$word + set space " " + } + if {[info exists partial]} { + # Missing end of quote + puts -nonewline $space$partial + } + if {$len} { + puts "" + } } proc title {text} { - underline [string trim $text] = - nl + underline [string trim $text] = + nl } proc p {text} { - wordwrap $text 80 - nl + wordwrap $text 80 + nl } proc codelines {lines} { - foreach line $lines { - puts " $line" - } - nl + foreach line $lines { + puts " $line" + } + nl } proc nl {} { - puts "" + puts "" } proc underline {text char} { - regexp "^(\[ \t\]*)(.*)" $text -> indent words - puts $text - puts $indent[string repeat $char [string length $words]] + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] } proc section {text} { - underline "[string trim $text]" - - nl + underline "[string trim $text]" - + nl } proc subsection {text} { - underline "$text" ~ - nl + underline "$text" ~ + nl } proc bullet {text} { - wordwrap $text 76 " * " " " + wordwrap $text 76 " * " " " } proc indent {text} { - wordwrap $text 76 " " " " + wordwrap $text 76 " " " " } proc defn {first args} { - if {$first ne ""} { - underline " $first" ~ - } - foreach p $args { - if {$p ne ""} { - indent $p - } - } + if {$first ne ""} { + underline " $first" ~ + } + foreach p $args { + if {$p ne ""} { + indent $p + } + } +} +} + +# ----- @module util.tcl ----- + +set modsource(util.tcl) { +# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which contains miscellaneous utility functions + +# @compare-versions version1 version2 +# +# Versions are of the form 'a.b.c' (may be any number of numeric components) +# +# Compares the two versions and returns: +## -1 if v1 < v2 +## 0 if v1 == v2 +## 1 if v1 > v2 +# +# If one version has fewer components than the other, 0 is substituted to the right. e.g. +## 0.2 < 0.3 +## 0.2.5 > 0.2 +## 1.1 == 1.1.0 +# +proc compare-versions {v1 v2} { + foreach c1 [split $v1 .] c2 [split $v2 .] { + if {$c1 eq ""} { + set c1 0 + } + if {$c2 eq ""} { + set c2 0 + } + if {$c1 < $c2} { + return -1 + } + if {$c1 > $c2} { + return 1 + } + } + return 0 +} + +# @suffix suf list +# +# Takes a list and returns a new list with '$suf' appended +# to each element +# +## suffix .c {a b c} => {a.c b.c c.c} +# +proc suffix {suf list} { + set result {} + foreach p $list { + lappend result $p$suf + } + return $result +} + +# @prefix pre list +# +# Takes a list and returns a new list with '$pre' prepended +# to each element +# +## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} +# +proc prefix {pre list} { + set result {} + foreach p $list { + lappend result $pre$p + } + return $result } } -# ----- module wiki-formatting ----- +# ----- @module wiki-formatting.tcl ----- -set modsource(wiki-formatting) { +set modsource(wiki-formatting.tcl) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved @@ -1977,7 +2253,7 @@ if {$autosetup(debug)} { } if {[catch {main $argv} msg opts] == 1} { show-notices - autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] + autosetup-full-error [error-dump $msg $opts $autosetup(debug)] if {!$autosetup(debug)} { puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" } diff --git a/autosetup/config.guess b/autosetup/autosetup-config.guess index 6c32c86..6c32c86 100755 --- a/autosetup/config.guess +++ b/autosetup/autosetup-config.guess diff --git a/autosetup/config.sub b/autosetup/autosetup-config.sub index 7ffe373..7ffe373 100755 --- a/autosetup/config.sub +++ b/autosetup/autosetup-config.sub diff --git a/autosetup/find-tclsh b/autosetup/autosetup-find-tclsh index be7cf3d..12d76af 100755 --- a/autosetup/find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -2,15 +2,15 @@ # Looks for a suitable tclsh or jimsh in the PATH # If not found, builds a bootstrap jimsh from source d=`dirname "$0"` -{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0 +{ "$d/jimsh0" "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0 PATH="$PATH:$d"; export PATH for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do - { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0 + { $tclsh "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue - "$d/jimsh0" "$d/test-tclsh" && exit 0 + "$d/jimsh0" "$d/autosetup-test-tclsh" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." echo false diff --git a/autosetup/test-tclsh b/autosetup/autosetup-test-tclsh index 75126d2..75126d2 100644..100755 --- a/autosetup/test-tclsh +++ b/autosetup/autosetup-test-tclsh diff --git a/autosetup/cc-db.tcl b/autosetup/cc-db.tcl index c67fc6e..5dadbaf 100644 --- a/autosetup/cc-db.tcl +++ b/autosetup/cc-db.tcl @@ -3,8 +3,8 @@ # @synopsis: # -# The 'cc-db' module provides a knowledge based of system idiosyncrasies -# In general, this module can always be included +# The 'cc-db' module provides a knowledge-base of system idiosyncrasies. +# In general, this module can always be included. use cc diff --git a/autosetup/cc-lib.tcl b/autosetup/cc-lib.tcl index 1ef7c63..c4b45bc 100644 --- a/autosetup/cc-lib.tcl +++ b/autosetup/cc-lib.tcl @@ -11,7 +11,7 @@ module-options {} # @cc-check-lfs # -# The equivalent of the AC_SYS_LARGEFILE macro +# The equivalent of the 'AC_SYS_LARGEFILE' macro. # # defines 'HAVE_LFS' if LFS is available, # and defines '_FILE_OFFSET_BITS=64' if necessary @@ -37,7 +37,7 @@ proc cc-check-lfs {} { # @cc-check-endian # -# The equivalent of the AC_C_BIGENDIAN macro +# The equivalent of the 'AC_C_BIGENDIAN' macro. # # defines 'HAVE_BIG_ENDIAN' if endian is known to be big, # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. @@ -82,34 +82,34 @@ proc cc-check-endian {} { # names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and # appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'. proc cc-check-flags {args} { - set result 1 - array set opts [cc-get-settings] - switch -exact -- $opts(-lang) { - c++ { - set lang C++ - set prefix CXXFLAG - } - c { - set lang C - set prefix CFLAG - } - default { - autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" - } - } - foreach flag $args { - msg-checking "Checking whether the $lang compiler accepts $flag..." - if {[cctest -cflags $flag]} { - msg-result yes - define-feature $prefix$flag - cc-with [list -cflags [list $flag]] - define-append ${prefix}S $flag - } else { - msg-result no - set result 0 - } - } - return $result + set result 1 + array set opts [cc-get-settings] + switch -exact -- $opts(-lang) { + c++ { + set lang C++ + set prefix CXXFLAG + } + c { + set lang C + set prefix CFLAG + } + default { + autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" + } + } + foreach flag $args { + msg-checking "Checking whether the $lang compiler accepts $flag..." + if {[cctest -cflags $flag]} { + msg-result yes + define-feature $prefix$flag + cc-with [list -cflags [list $flag]] + define-append ${prefix}S $flag + } else { + msg-result no + set result 0 + } + } + return $result } # @cc-check-standards ver ?...? @@ -118,26 +118,24 @@ proc cc-check-flags {args} { # options, and appends the first working one to '-cflags' and 'CFLAGS' or # 'CXXFLAGS'. proc cc-check-standards {args} { - array set opts [cc-get-settings] - foreach std $args { - if {[cc-check-flags -std=$std]} { - return $std - } - } - return "" + array set opts [cc-get-settings] + foreach std $args { + if {[cc-check-flags -std=$std]} { + return $std + } + } + return "" } # Checks whether $keyword is usable as alignof proc cctest_alignof {keyword} { - msg-checking "Checking for $keyword..." - if {[cctest -code [subst -nobackslashes { - printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x')); - }]]} then { - msg-result ok - define-feature $keyword - } else { - msg-result "not found" - } + msg-checking "Checking for $keyword..." + if {[cctest -code "int x = ${keyword}(char), y = ${keyword}('x');"]} then { + msg-result ok + define-feature $keyword + } else { + msg-result "not found" + } } # @cc-check-c11 @@ -145,47 +143,47 @@ proc cctest_alignof {keyword} { # Checks for several C11/C++11 extensions and their alternatives. Currently # checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'. proc cc-check-c11 {} { - msg-checking "Checking for _Static_assert..." - if {[cctest -code { - _Static_assert(1, "static assertions are available"); - }]} then { - msg-result ok - define-feature _Static_assert - } else { - msg-result "not found" - } + msg-checking "Checking for _Static_assert..." + if {[cctest -code { + _Static_assert(1, "static assertions are available"); + }]} then { + msg-result ok + define-feature _Static_assert + } else { + msg-result "not found" + } - cctest_alignof _Alignof - cctest_alignof __alignof__ - cctest_alignof __alignof + cctest_alignof _Alignof + cctest_alignof __alignof__ + cctest_alignof __alignof } # @cc-check-alloca # -# The equivalent of the AC_FUNC_ALLOCA macro +# The equivalent of the 'AC_FUNC_ALLOCA' macro. # -# Checks for the existence of alloca -# defines HAVE_ALLOCA and returns 1 if it exists +# Checks for the existence of 'alloca' +# defines 'HAVE_ALLOCA' and returns 1 if it exists. proc cc-check-alloca {} { - cc-check-some-feature alloca { - cctest -includes alloca.h -code { alloca (2 * sizeof (int)); } - } + cc-check-some-feature alloca { + cctest -includes alloca.h -code { alloca (2 * sizeof (int)); } + } } # @cc-signal-return-type # -# The equivalent of the AC_TYPE_SIGNAL macro +# The equivalent of the 'AC_TYPE_SIGNAL' macro. # -# defines RETSIGTYPE to int or void +# defines 'RETSIGTYPE' to 'int' or 'void'. proc cc-signal-return-type {} { - msg-checking "Checking return type of signal handlers..." - cc-with {-includes {sys/types.h signal.h}} { - if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} { - set type int - } else { - set type void - } - define RETSIGTYPE $type - msg-result $type - } + msg-checking "Checking return type of signal handlers..." + cc-with {-includes {sys/types.h signal.h}} { + if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} { + set type int + } else { + set type void + } + define RETSIGTYPE $type + msg-result $type + } } diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl index c6702a2..5f066b5 100644 --- a/autosetup/cc.tcl +++ b/autosetup/cc.tcl @@ -4,8 +4,8 @@ # @synopsis: # # The 'cc' module supports checking various 'features' of the C or C++ -# compiler/linker environment. Common commands are cc-check-includes, -# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template. +# compiler/linker environment. Common commands are 'cc-check-includes', +# 'cc-check-types', 'cc-check-functions', 'cc-with', 'make-config-header' and 'make-template'. # # The following environment variables are used if set: # @@ -70,8 +70,8 @@ proc cctest_decl {name} { # @cc-check-sizeof type ... # # Checks the size of the given types (between 1 and 32, inclusive). -# Defines a variable with the size determined, or "unknown" otherwise. -# e.g. for type 'long long', defines SIZEOF_LONG_LONG. +# Defines a variable with the size determined, or 'unknown' otherwise. +# e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'. # Returns the size of the last type. # proc cc-check-sizeof {args} { @@ -111,7 +111,7 @@ proc cc-check-some-feature {list script} { # @cc-check-includes includes ... # -# Checks that the given include files can be used +# Checks that the given include files can be used. proc cc-check-includes {args} { cc-check-some-feature $args { set with {} @@ -136,8 +136,8 @@ proc cc-check-includes {args} { # @cc-include-needs include required ... # -# Ensures that when checking for 'include', a check is first -# made for each 'required' file, and if found, it is #included +# Ensures that when checking for '$include', a check is first +# made for each '$required' file, and if found, it is included with '#include'. proc cc-include-needs {file args} { foreach depfile $args { dict set ::autosetup(cc-include-deps) $file $depfile 1 @@ -155,7 +155,7 @@ proc cc-check-types {args} { # @cc-check-defines define ... # -# Checks that the given preprocessor symbol is defined +# Checks that the given preprocessor symbol is defined. proc cc-check-defines {args} { cc-check-some-feature $args { cctest_define $each @@ -165,8 +165,8 @@ proc cc-check-defines {args} { # @cc-check-decls name ... # # Checks that each given name is either a preprocessor symbol or rvalue -# such as an enum. Note that the define used is HAVE_DECL_xxx -# rather than HAVE_xxx +# such as an enum. Note that the define used is 'HAVE_DECL_xxx' +# rather than 'HAVE_xxx'. proc cc-check-decls {args} { set ret 1 foreach name $args { @@ -185,7 +185,7 @@ proc cc-check-decls {args} { # @cc-check-functions function ... # -# Checks that the given functions exist (can be linked) +# Checks that the given functions exist (can be linked). proc cc-check-functions {args} { cc-check-some-feature $args { cctest_function $each @@ -195,7 +195,7 @@ proc cc-check-functions {args} { # @cc-check-members type.member ... # # Checks that the given type/structure members exist. -# A structure member is of the form "struct stat.st_mtime" +# A structure member is of the form 'struct stat.st_mtime'. proc cc-check-members {args} { cc-check-some-feature $args { cctest_member $each @@ -209,13 +209,13 @@ proc cc-check-members {args} { # First checks for no library required, then checks each of the libraries # in turn. # -# If the function is found, the feature is defined and lib_$function is defined -# to -l$lib where the function was found, or "" if no library required. -# In addition, -l$lib is prepended to the LIBS define. +# If the function is found, the feature is defined and 'lib_$function' is defined +# to '-l$lib' where the function was found, or "" if no library required. +# In addition, '-l$lib' is prepended to the 'LIBS' define. # # If additional libraries may be needed for linking, they should be specified -# as $extralibs as "-lotherlib1 -lotherlib2". -# These libraries are not automatically added to LIBS. +# with '$extralibs' as '-lotherlib1 -lotherlib2'. +# These libraries are not automatically added to 'LIBS'. # # Returns 1 if found or 0 if not. # @@ -255,12 +255,12 @@ proc cc-check-function-in-lib {function libs {otherlibs {}}} { # Checks for existence of the given compiler tools, taking # into account any cross compilation prefix. # -# For example, when checking for "ar", first AR is checked on the command -# line and then in the environment. If not found, "${host}-ar" or -# simply "ar" is assumed depending upon whether cross compiling. -# The path is searched for this executable, and if found AR is defined +# For example, when checking for 'ar', first 'AR' is checked on the command +# line and then in the environment. If not found, '${host}-ar' or +# simply 'ar' is assumed depending upon whether cross compiling. +# The path is searched for this executable, and if found 'AR' is defined # to the executable name. -# Note that even when cross compiling, the simple "ar" is used as a fallback, +# Note that even when cross compiling, the simple 'ar' is used as a fallback, # but a warning is generated. This is necessary for some toolchains. # # It is an error if the executable is not found. @@ -286,10 +286,10 @@ proc cc-check-tools {args} { # # Checks for existence of the given executables on the path. # -# For example, when checking for "grep", the path is searched for -# the executable, 'grep', and if found GREP is defined as "grep". +# For example, when checking for 'grep', the path is searched for +# the executable, 'grep', and if found 'GREP' is defined as 'grep'. # -# If the executable is not found, the variable is defined as false. +# If the executable is not found, the variable is defined as 'false'. # Returns 1 if all programs were found, or 0 otherwise. # proc cc-check-progs {args} { @@ -375,12 +375,12 @@ proc cc-update-settings {args} { # @cc-with settings ?{ script }? # -# Sets the given 'cctest' settings and then runs the tests in 'script'. -# Note that settings such as -lang replace the current setting, while -# those such as -includes are appended to the existing setting. +# Sets the given 'cctest' settings and then runs the tests in '$script'. +# Note that settings such as '-lang' replace the current setting, while +# those such as '-includes' are appended to the existing setting. # # If no script is given, the settings become the default for the remainder -# of the auto.def file. +# of the 'auto.def' file. # ## cc-with {-lang c++} { ## # This will check with the C++ compiler @@ -392,7 +392,7 @@ proc cc-update-settings {args} { ## # back to just the C++ compiler ## } # -# The -libs setting is special in that newer values are added *before* earlier ones. +# The '-libs' setting is special in that newer values are added *before* earlier ones. # ## cc-with {-libs {-lc -lm}} { ## cc-with {-libs -ldl} { @@ -418,7 +418,7 @@ proc cc-with {settings args} { # @cctest ?settings? # -# Low level C compiler checker. Compiles and or links a small C program +# Low level C/C++ compiler checker. Compiles and or links a small C program # according to the arguments and returns 1 if OK, or 0 if not. # # Supported settings are: @@ -434,7 +434,7 @@ proc cc-with {settings args} { ## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file] ## -nooutput 1 Treat any compiler output (e.g. a warning) as an error # -# Unless -source or -sourcefile is specified, the C program looks like: +# Unless '-source' or '-sourcefile' is specified, the C program looks like: # ## #include <firstinclude> /* same for remaining includes in the list */ ## @@ -556,7 +556,7 @@ proc cctest {args} { # @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*? # -# Deprecated - see make-config-header +# Deprecated - see 'make-config-header' proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} { user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead" make-config-header $file -auto $autopatterns -bare $barepatterns @@ -565,19 +565,19 @@ proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_ # @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ... # # Examines all defined variables which match the given patterns -# and writes an include file, $file, which defines each of these. +# and writes an include file, '$file', which defines each of these. # Variables which match '-auto' are output as follows: -# - defines which have the value "0" are ignored. +# - defines which have the value '0' are ignored. # - defines which have integer values are defined as the integer value. -# - any other value is defined as a string, e.g. "value" +# - any other value is defined as a string, e.g. '"value"' # Variables which match '-bare' are defined as-is. -# Variables which match '-str' are defined as a string, e.g. "value" +# Variables which match '-str' are defined as a string, e.g. '"value"' # Variables which match '-none' are omitted. # -# Note that order is important. The first pattern which matches is selected +# Note that order is important. The first pattern that matches is selected. # Default behaviour is: # -# -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * +## -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * # # If the file would be unchanged, it is not written. proc make-config-header {file args} { diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index 463c6c3..fc2133f 100644..100755 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -1,7 +1,5 @@ /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ -#define _GNU_SOURCE #define JIM_TCL_COMPAT -#define JIM_REFERENCES #define JIM_ANSIC #define JIM_REGEXP #define HAVE_NO_AUTOCONF @@ -33,10 +31,24 @@ #define HAVE_SYS_TIME_H #define HAVE_DIRENT_H #define HAVE_UNISTD_H +#define HAVE_UMASK +#include <sys/stat.h> +#ifndef S_IRWXG +#define S_IRWXG 0 +#endif +#ifndef S_IRWXO +#define S_IRWXO 0 +#endif #else #define TCL_PLATFORM_OS "unknown" #define TCL_PLATFORM_PLATFORM "unix" #define TCL_PLATFORM_PATH_SEPARATOR ":" +#ifdef _MINIX +#define vfork fork +#define _POSIX_SOURCE +#else +#define _GNU_SOURCE +#endif #define HAVE_VFORK #define HAVE_WAITPID #define HAVE_ISATTY @@ -45,8 +57,9 @@ #define HAVE_SYS_TIME_H #define HAVE_DIRENT_H #define HAVE_UNISTD_H +#define HAVE_UMASK #endif -#define JIM_VERSION 76 +#define JIM_VERSION 77 #ifndef JIM_WIN32COMPAT_H #define JIM_WIN32COMPAT_H @@ -90,7 +103,6 @@ char *dlerror(void); #define JIM_WIDE_MODIFIER "I64d" #define strcasecmp _stricmp #define strtoull _strtoui64 -#define snprintf _snprintf #include <io.h> @@ -107,10 +119,10 @@ struct dirent { }; typedef struct DIR { - long handle; + long handle; struct _finddata_t info; - struct dirent result; - char *name; + struct dirent result; + char *name; } DIR; DIR *opendir(const char *name); @@ -124,7 +136,7 @@ struct dirent *readdir(DIR *dir); #endif -#endif +#endif #ifdef __cplusplus } @@ -148,7 +160,8 @@ int utf8_fromunicode(char *p, unsigned uc); #include <ctype.h> -#define utf8_strlen(S, B) ((B) < 0 ? strlen(S) : (B)) +#define utf8_strlen(S, B) ((B) < 0 ? (int)strlen(S) : (B)) +#define utf8_strwidth(S, B) utf8_strlen((S), (B)) #define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1) #define utf8_getchars(CP, C) (*(CP) = (C), 1) #define utf8_upper(C) toupper(C) @@ -157,6 +170,7 @@ int utf8_fromunicode(char *p, unsigned uc); #define utf8_index(C, I) (I) #define utf8_charlen(C) 1 #define utf8_prev_len(S, L) 1 +#define utf8_width(C) 1 #else @@ -177,9 +191,9 @@ extern "C" { #include <time.h> #include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> #ifndef HAVE_NO_AUTOCONF @@ -226,27 +240,27 @@ extern "C" { #define JIM_EVAL 7 -#define JIM_MAX_CALLFRAME_DEPTH 1000 -#define JIM_MAX_EVAL_DEPTH 2000 +#define JIM_MAX_CALLFRAME_DEPTH 1000 +#define JIM_MAX_EVAL_DEPTH 2000 #define JIM_PRIV_FLAG_SHIFT 20 -#define JIM_NONE 0 -#define JIM_ERRMSG 1 -#define JIM_ENUM_ABBREV 2 -#define JIM_UNSHARED 4 -#define JIM_MUSTEXIST 8 +#define JIM_NONE 0 +#define JIM_ERRMSG 1 +#define JIM_ENUM_ABBREV 2 +#define JIM_UNSHARED 4 +#define JIM_MUSTEXIST 8 -#define JIM_SUBST_NOVAR 1 -#define JIM_SUBST_NOCMD 2 -#define JIM_SUBST_NOESC 4 -#define JIM_SUBST_FLAG 128 +#define JIM_SUBST_NOVAR 1 +#define JIM_SUBST_NOCMD 2 +#define JIM_SUBST_NOESC 4 +#define JIM_SUBST_FLAG 128 -#define JIM_CASESENS 0 -#define JIM_NOCASE 1 +#define JIM_CASESENS 0 +#define JIM_NOCASE 1 #define JIM_PATH_LEN 1024 @@ -341,66 +355,66 @@ typedef struct Jim_HashTableIterator { typedef struct Jim_Obj { - char *bytes; - const struct Jim_ObjType *typePtr; - int refCount; - int length; - + char *bytes; + const struct Jim_ObjType *typePtr; + int refCount; + int length; + union { - + jim_wide wideValue; - + int intValue; - + double doubleValue; - + void *ptr; - + struct { void *ptr1; void *ptr2; } twoPtrValue; - + struct { struct Jim_Var *varPtr; - unsigned long callFrameId; - int global; + unsigned long callFrameId; + int global; } varValue; - + struct { struct Jim_Obj *nsObj; struct Jim_Cmd *cmdPtr; - unsigned long procEpoch; + unsigned long procEpoch; } cmdValue; - + struct { - struct Jim_Obj **ele; - int len; - int maxLen; + struct Jim_Obj **ele; + int len; + int maxLen; } listValue; - + struct { int maxLength; - int charLength; + int charLength; } strValue; - + struct { unsigned long id; struct Jim_Reference *refPtr; } refValue; - + struct { struct Jim_Obj *fileNameObj; int lineNumber; } sourceValue; - + struct { struct Jim_Obj *varNameObjPtr; struct Jim_Obj *indexObjPtr; } dictSubstValue; - + struct { - void *compre; + void *compre; unsigned flags; } regexpValue; struct { @@ -408,8 +422,8 @@ typedef struct Jim_Obj { int argc; } scriptLineValue; } internalRep; - struct Jim_Obj *prevObjPtr; - struct Jim_Obj *nextObjPtr; + struct Jim_Obj *prevObjPtr; + struct Jim_Obj *nextObjPtr; } Jim_Obj; @@ -444,7 +458,7 @@ typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp, typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr); typedef struct Jim_ObjType { - const char *name; + const char *name; Jim_FreeInternalRepProc *freeIntRepProc; Jim_DupInternalRepProc *dupIntRepProc; Jim_UpdateStringProc *updateStringProc; @@ -452,28 +466,28 @@ typedef struct Jim_ObjType { } Jim_ObjType; -#define JIM_TYPE_NONE 0 -#define JIM_TYPE_REFERENCES 1 +#define JIM_TYPE_NONE 0 +#define JIM_TYPE_REFERENCES 1 typedef struct Jim_CallFrame { - unsigned long id; - int level; - struct Jim_HashTable vars; - struct Jim_HashTable *staticVars; - struct Jim_CallFrame *parent; - Jim_Obj *const *argv; - int argc; - Jim_Obj *procArgsObjPtr; - Jim_Obj *procBodyObjPtr; - struct Jim_CallFrame *next; - Jim_Obj *nsObj; - Jim_Obj *fileNameObj; + unsigned long id; + int level; + struct Jim_HashTable vars; + struct Jim_HashTable *staticVars; + struct Jim_CallFrame *parent; + Jim_Obj *const *argv; + int argc; + Jim_Obj *procArgsObjPtr; + Jim_Obj *procBodyObjPtr; + struct Jim_CallFrame *next; + Jim_Obj *nsObj; + Jim_Obj *fileNameObj; int line; - Jim_Stack *localCommands; - struct Jim_Obj *tailcallObj; - struct Jim_Cmd *tailcallCmd; + Jim_Stack *localCommands; + struct Jim_Obj *tailcallObj; + struct Jim_Cmd *tailcallCmd; } Jim_CallFrame; typedef struct Jim_Var { @@ -489,31 +503,31 @@ typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData); typedef struct Jim_Cmd { - int inUse; - int isproc; - struct Jim_Cmd *prevCmd; + int inUse; + int isproc; + struct Jim_Cmd *prevCmd; union { struct { - - Jim_CmdProc *cmdProc; - Jim_DelCmdProc *delProc; - void *privData; + + Jim_CmdProc *cmdProc; + Jim_DelCmdProc *delProc; + void *privData; } native; struct { - + Jim_Obj *argListObjPtr; Jim_Obj *bodyObjPtr; - Jim_HashTable *staticVars; - int argListLen; - int reqArity; - int optArity; - int argsPos; - int upcall; + Jim_HashTable *staticVars; + int argListLen; + int reqArity; + int optArity; + int argsPos; + int upcall; struct Jim_ProcArg { - Jim_Obj *nameObjPtr; - Jim_Obj *defaultObjPtr; + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; } *arglist; - Jim_Obj *nsObj; + Jim_Obj *nsObj; } proc; } u; } Jim_Cmd; @@ -525,23 +539,23 @@ typedef struct Jim_PrngState { } Jim_PrngState; typedef struct Jim_Interp { - Jim_Obj *result; - int errorLine; - Jim_Obj *errorFileNameObj; - int addStackTrace; - int maxCallFrameDepth; - int maxEvalDepth; - int evalDepth; - int returnCode; - int returnLevel; - int exitCode; - long id; - int signal_level; - jim_wide sigmask; - int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); - Jim_CallFrame *framePtr; - Jim_CallFrame *topFramePtr; - struct Jim_HashTable commands; + Jim_Obj *result; + int errorLine; + Jim_Obj *errorFileNameObj; + int addStackTrace; + int maxCallFrameDepth; + int maxEvalDepth; + int evalDepth; + int returnCode; + int returnLevel; + int exitCode; + long id; + int signal_level; + jim_wide sigmask; + int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); + Jim_CallFrame *framePtr; + Jim_CallFrame *topFramePtr; + struct Jim_HashTable commands; unsigned long procEpoch; /* Incremented every time the result of procedures names lookup caching may no longer be valid. */ @@ -549,36 +563,36 @@ typedef struct Jim_Interp { callframe is created. This id is used for the 'ID' field contained in the Jim_CallFrame structure. */ - int local; - Jim_Obj *liveList; - Jim_Obj *freeList; - Jim_Obj *currentScriptObj; - Jim_Obj *nullScriptObj; - Jim_Obj *emptyObj; - Jim_Obj *trueObj; - Jim_Obj *falseObj; - unsigned long referenceNextId; - struct Jim_HashTable references; + int local; + Jim_Obj *liveList; + Jim_Obj *freeList; + Jim_Obj *currentScriptObj; + Jim_Obj *nullScriptObj; + Jim_Obj *emptyObj; + Jim_Obj *trueObj; + Jim_Obj *falseObj; + unsigned long referenceNextId; + struct Jim_HashTable references; unsigned long lastCollectId; /* reference max Id of the last GC execution. It's set to -1 while the collection is running as sentinel to avoid to recursive calls via the [collect] command inside finalizers. */ - time_t lastCollectTime; - Jim_Obj *stackTrace; - Jim_Obj *errorProc; - Jim_Obj *unknown; - int unknown_called; - int errorFlag; + time_t lastCollectTime; + Jim_Obj *stackTrace; + Jim_Obj *errorProc; + Jim_Obj *unknown; + int unknown_called; + int errorFlag; void *cmdPrivData; /* Used to pass the private data pointer to a command. It is set to what the user specified via Jim_CreateCommand(). */ - struct Jim_CallFrame *freeFramesList; - struct Jim_HashTable assocData; - Jim_PrngState *prngState; - struct Jim_HashTable packages; - Jim_Stack *loadHandles; + struct Jim_CallFrame *freeFramesList; + struct Jim_HashTable assocData; + Jim_PrngState *prngState; + struct Jim_HashTable packages; + Jim_Stack *loadHandles; } Jim_Interp; #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++ @@ -625,7 +639,7 @@ JIM_EXPORT char *Jim_StrDupLen(const char *s, int l); JIM_EXPORT char **Jim_GetEnviron(void); JIM_EXPORT void Jim_SetEnviron(char **env); -JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *template); +JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template); JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); @@ -818,10 +832,14 @@ JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len); JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr); -JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj); -JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr); + +#define JIM_DICTMATCH_KEYS 0x0001 +#define JIM_DICTMATCH_VALUES 0x002 + +JIM_EXPORT int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types); JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr); JIM_EXPORT int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv); JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, @@ -834,6 +852,10 @@ JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr); +JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, + int *booleanPtr); + + JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr, jim_wide *widePtr); JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr, @@ -854,6 +876,8 @@ JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg); JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr, const char * const *tablePtr, int *indexPtr, const char *name, int flags); +JIM_EXPORT int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, + const char *const *tablePtr); JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr); @@ -906,7 +930,7 @@ JIM_EXPORT int Jim_IsList(Jim_Obj *objPtr); } #endif -#endif +#endif #ifndef JIM_SUBCMD_H #define JIM_SUBCMD_H @@ -917,20 +941,20 @@ extern "C" { #endif -#define JIM_MODFLAG_HIDDEN 0x0001 -#define JIM_MODFLAG_FULLARGV 0x0002 +#define JIM_MODFLAG_HIDDEN 0x0001 +#define JIM_MODFLAG_FULLARGV 0x0002 typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv); typedef struct { - const char *cmd; - const char *args; - jim_subcmd_function *function; - short minargs; - short maxargs; - unsigned short flags; + const char *cmd; + const char *args; + jim_subcmd_function *function; + short minargs; + short maxargs; + unsigned short flags; } jim_subcmd_type; const jim_subcmd_type * @@ -962,32 +986,32 @@ typedef struct { typedef struct regexp { - - int re_nsub; - - - int cflags; - int err; - int regstart; - int reganch; - int regmust; - int regmlen; - int *program; - - - const char *regparse; - int p; - int proglen; - - - int eflags; - const char *start; - const char *reginput; - const char *regbol; - - - regmatch_t *pmatch; - int nmatch; + + int re_nsub; + + + int cflags; + int err; + int regstart; + int reganch; + int regmust; + int regmlen; + int *program; + + + const char *regparse; + int p; + int proglen; + + + int eflags; + const char *start; + const char *reginput; + const char *regbol; + + + regmatch_t *pmatch; + int nmatch; } regexp; typedef regexp regex_t; @@ -999,9 +1023,9 @@ typedef regexp regex_t; #define REG_NOTBOL 16 enum { - REG_NOERROR, - REG_NOMATCH, - REG_BADPAT, + REG_NOERROR, + REG_NOMATCH, + REG_BADPAT, REG_ERR_NULL_ARGUMENT, REG_ERR_UNKNOWN, REG_ERR_TOO_BIG, @@ -1102,6 +1126,39 @@ int Jim_initjimshInit(Jim_Interp *interp) " set jim::argv0 [string map {\\\\ /} $jim::argv0]\n" "}\n" "\n" +"\n" +"set tcl::autocomplete_commands {info tcl::prefix socket namespace array clock file package string dict signal history}\n" +"\n" +"\n" +"\n" +"proc tcl::autocomplete {prefix} {\n" +" if {[set space [string first \" \" $prefix]] != -1} {\n" +" set cmd [string range $prefix 0 $space-1]\n" +" if {$cmd in $::tcl::autocomplete_commands || [info channel $cmd] ne \"\"} {\n" +" set arg [string range $prefix $space+1 end]\n" +"\n" +" return [lmap p [$cmd -commands] {\n" +" if {![string match \"${arg}*\" $p]} continue\n" +" function \"$cmd $p\"\n" +" }]\n" +" }\n" +" }\n" +"\n" +" if {[string match \"source *\" $prefix]} {\n" +" set path [string range $prefix 7 end]\n" +" return [lmap p [glob -nocomplain \"${path}*\"] {\n" +" function \"source $p\"\n" +" }]\n" +" }\n" +"\n" +" return [lmap p [lsort [info commands $prefix*]] {\n" +" if {[string match \"* *\" $p]} {\n" +" continue\n" +" }\n" +" function $p\n" +" }]\n" +"}\n" +"\n" "_jimsh_init\n" ); } @@ -1405,27 +1462,6 @@ int Jim_stdlibInit(Jim_Interp *interp) "}\n" "\n" "\n" -"proc {dict with} {&dictVar {args key} script} {\n" -" set keys {}\n" -" foreach {n v} [dict get $dictVar {*}$key] {\n" -" upvar $n var_$n\n" -" set var_$n $v\n" -" lappend keys $n\n" -" }\n" -" catch {uplevel 1 $script} msg opts\n" -" if {[info exists dictVar] && ([llength $key] == 0 || [dict exists $dictVar {*}$key])} {\n" -" foreach n $keys {\n" -" if {[info exists var_$n]} {\n" -" dict set dictVar {*}$key $n [set var_$n]\n" -" } else {\n" -" dict unset dictVar {*}$key $n\n" -" }\n" -" }\n" -" }\n" -" return {*}$opts $msg\n" -"}\n" -"\n" -"\n" "proc {dict update} {&varName args script} {\n" " set keys {}\n" " foreach {n v} $args {\n" @@ -1447,19 +1483,6 @@ int Jim_stdlibInit(Jim_Interp *interp) " return {*}$opts $msg\n" "}\n" "\n" -"\n" -"\n" -"proc {dict merge} {dict args} {\n" -" foreach d $args {\n" -"\n" -" dict size $d\n" -" foreach {k v} $d {\n" -" dict set dict $k $v\n" -" }\n" -" }\n" -" return $dict\n" -"}\n" -"\n" "proc {dict replace} {dictionary {args {key value}}} {\n" " if {[llength ${key value}] % 2} {\n" " tailcall {dict replace}\n" @@ -1506,11 +1529,6 @@ int Jim_stdlibInit(Jim_Interp *interp) "}\n" "\n" "\n" -"proc {dict values} {dictionary {pattern *}} {\n" -" dict keys [lreverse $dictionary] $pattern\n" -"}\n" -"\n" -"\n" "proc {dict for} {vars dictionary script} {\n" " if {[llength $vars] != 2} {\n" " return -code error \"must have exactly two variable names\"\n" @@ -1593,7 +1611,6 @@ int Jim_tclcompatInit(Jim_Interp *interp) "\n" "\n" "\n" -"\n" "proc parray {arrayname {pattern *} {puts puts}} {\n" " upvar $arrayname a\n" "\n" @@ -1703,11 +1720,6 @@ int Jim_tclcompatInit(Jim_Interp *interp) "\n" "\n" "\n" -"\n" -"\n" -"\n" -"\n" -"\n" "proc try {args} {\n" " set catchopts {}\n" " while {[string match -* [lindex $args 0]]} {\n" @@ -1782,6 +1794,9 @@ int Jim_tclcompatInit(Jim_Interp *interp) } +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include <stdio.h> #include <string.h> #include <errno.h> @@ -1809,9 +1824,12 @@ int Jim_tclcompatInit(Jim_Interp *interp) #include <openssl/err.h> #endif +#ifdef HAVE_TERMIOS_H +#endif + -#define AIO_CMD_LEN 32 -#define AIO_BUF_LEN 256 +#define AIO_CMD_LEN 32 +#define AIO_BUF_LEN 256 #ifndef HAVE_FTELLO #define ftello ftell @@ -1850,7 +1868,7 @@ typedef struct AioFile FILE *fp; Jim_Obj *filename; int type; - int openFlags; + int openFlags; int fd; Jim_Obj *rEvent; Jim_Obj *wEvent; @@ -1881,7 +1899,7 @@ static int stdio_error(const AioFile *af) return JIM_OK; } clearerr(af->fp); - + if (feof(af->fp) || errno == EAGAIN || errno == EINTR) { return JIM_OK; } @@ -1891,7 +1909,7 @@ static int stdio_error(const AioFile *af) } #endif #ifdef ECONNABORTED - if (errno != ECONNABORTED) { + if (errno == ECONNABORTED) { return JIM_OK; } #endif @@ -1947,8 +1965,8 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData) Jim_DecrRefCount(interp, af->filename); #ifdef jim_ext_eventloop - - Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION); + + Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION); #endif #if defined(JIM_SSL) @@ -1956,7 +1974,6 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData) SSL_free(af->ssl); } #endif - if (!(af->openFlags & AIO_KEEPOPEN)) { fclose(af->fp); } @@ -1970,7 +1987,7 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) char buf[AIO_BUF_LEN]; Jim_Obj *objPtr; int nonewline = 0; - jim_wide neededLen = -1; + jim_wide neededLen = -1; if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { nonewline = 1; @@ -2009,7 +2026,7 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (retval != readlen) break; } - + if (JimCheckStreamError(interp, af)) { Jim_FreeNewObj(interp, objPtr); return JIM_ERR; @@ -2031,7 +2048,7 @@ AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command) { Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); - + if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { return (AioFile *) cmdPtr->u.native.privData; } @@ -2112,7 +2129,7 @@ static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) len = strlen(buf); if (len && (buf[len - 1] == '\n')) { - + len--; } @@ -2122,7 +2139,7 @@ static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (JimCheckStreamError(interp, af)) { - + Jim_FreeNewObj(interp, objPtr); return JIM_ERR; } @@ -2136,7 +2153,7 @@ static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) len = Jim_Length(objPtr); if (len == 0 && feof(af->fp)) { - + len = -1; } Jim_SetResultInt(interp, len); @@ -2366,7 +2383,7 @@ static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Ob int argc, Jim_Obj * const *argv) { if (argc == 0) { - + if (*scriptHandlerObj) { Jim_SetResult(interp, *scriptHandlerObj); } @@ -2374,21 +2391,21 @@ static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Ob } if (*scriptHandlerObj) { - - Jim_DeleteFileHandler(interp, af->fp, mask); + + Jim_DeleteFileHandler(interp, af->fd, mask); } - + if (Jim_Length(argv[0]) == 0) { - + return JIM_OK; } - + Jim_IncrRefCount(argv[0]); *scriptHandlerObj = argv[0]; - Jim_CreateFileHandler(interp, af->fp, mask, + Jim_CreateFileHandler(interp, af->fd, mask, JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer); return JIM_OK; @@ -2417,55 +2434,57 @@ static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *arg #endif + + static const jim_subcmd_type aio_command_table[] = { { "read", "?-nonewline? ?len?", aio_cmd_read, 0, 2, - + }, { "copyto", "handle ?size?", aio_cmd_copy, 1, 2, - + }, { "gets", "?var?", aio_cmd_gets, 0, 1, - + }, { "puts", "?-nonewline? str", aio_cmd_puts, 1, 2, - + }, { "isatty", NULL, aio_cmd_isatty, 0, 0, - + }, { "flush", NULL, aio_cmd_flush, 0, 0, - + }, { "eof", NULL, aio_cmd_eof, 0, 0, - + }, { "close", "?r(ead)|w(rite)?", @@ -2473,28 +2492,28 @@ static const jim_subcmd_type aio_command_table[] = { 0, 1, JIM_MODFLAG_FULLARGV, - + }, { "seek", "offset ?start|current|end", aio_cmd_seek, 1, 2, - + }, { "tell", NULL, aio_cmd_tell, 0, 0, - + }, { "filename", NULL, aio_cmd_filename, 0, 0, - + }, #ifdef O_NDELAY { "ndelay", @@ -2502,7 +2521,7 @@ static const jim_subcmd_type aio_command_table[] = { aio_cmd_ndelay, 0, 1, - + }, #endif #ifdef HAVE_FSYNC @@ -2511,7 +2530,7 @@ static const jim_subcmd_type aio_command_table[] = { aio_cmd_sync, 0, 0, - + }, #endif { "buffering", @@ -2519,7 +2538,7 @@ static const jim_subcmd_type aio_command_table[] = { aio_cmd_buffering, 1, 1, - + }, #ifdef jim_ext_eventloop { "readable", @@ -2527,21 +2546,21 @@ static const jim_subcmd_type aio_command_table[] = { aio_cmd_readable, 0, 1, - + }, { "writable", "?writable-script?", aio_cmd_writable, 0, 1, - + }, { "onexception", "?exception-script?", aio_cmd_onexception, 0, 1, - + }, #endif { NULL } @@ -2568,7 +2587,7 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc, { const char *filename = Jim_String(argv[1]); - + if (*filename == '|') { Jim_Obj *evalObj[3]; @@ -2625,7 +2644,7 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *fi } } - + af = Jim_Alloc(sizeof(*af)); memset(af, 0, sizeof(*af)); af->fp = fh; @@ -2663,7 +2682,7 @@ static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, } } - + close(p[0]); close(p[1]); JimAioSetError(interp, NULL); @@ -2672,14 +2691,14 @@ static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, #endif -int Jim_MakeTempFile(Jim_Interp *interp, const char *template) +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template) { #ifdef HAVE_MKSTEMP int fd; mode_t mask; Jim_Obj *filenameObj; - if (template == NULL) { + if (filename_template == NULL) { const char *tmpdir = getenv("TMPDIR"); if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) { tmpdir = "/tmp/"; @@ -2691,17 +2710,11 @@ int Jim_MakeTempFile(Jim_Interp *interp, const char *template) Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1); } else { - filenameObj = Jim_NewStringObj(interp, template, -1); + filenameObj = Jim_NewStringObj(interp, filename_template, -1); } -#if defined(S_IRWXG) && defined(S_IRWXO) - mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); -#else - - mask = umask(S_IXUSR); -#endif - + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); fd = mkstemp(filenameObj->bytes); umask(mask); if (fd < 0) { @@ -2733,7 +2746,7 @@ int Jim_aioInit(Jim_Interp *interp) Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); #endif - + JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r"); JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w"); JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w"); @@ -2833,16 +2846,16 @@ static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned f const char *pattern; int ret; - + if (objPtr->typePtr == ®expObjType && objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) { - + return objPtr->internalRep.regexpValue.compre; } - - + + pattern = Jim_String(objPtr); compre = Jim_Alloc(sizeof(regex_t)); @@ -3003,7 +3016,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) num_matches++; if (opt_all && !opt_inline) { - + goto try_next_match; } @@ -3043,7 +3056,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_ListAppendElement(interp, resultListObj, resultObj); } else { - + result = Jim_SetVariable(interp, argv[i], resultObj); if (result != JIM_OK) { @@ -3170,7 +3183,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) replace_str = Jim_GetString(argv[i + 2], &replace_len); varname = argv[i + 3]; - + resultObj = Jim_NewStringObj(interp, "", 0); if (offset) { @@ -3185,7 +3198,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } } - + Jim_AppendString(interp, resultObj, source_str, offset); @@ -3244,19 +3257,19 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) p += pmatch[0].rm_eo; n -= pmatch[0].rm_eo; - + if (!opt_all || n == 0) { break; } - + if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') { break; } - + if (pattern[0] == '\0' && n) { - + Jim_AppendString(interp, resultObj, p, 1); p++; n--; @@ -3267,7 +3280,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_AppendString(interp, resultObj, p, -1); - + if (argc - i == 4) { result = Jim_SetVariable(interp, varname, resultObj); @@ -3373,7 +3386,7 @@ static void AppendStatElement(Jim_Interp *interp, Jim_Obj *listObj, const char * static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb) { - + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); AppendStatElement(interp, listObj, "dev", sb->st_dev); @@ -3389,23 +3402,25 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1)); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1)); - + if (varName) { - Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE); + Jim_Obj *objPtr; + objPtr = Jim_GetVariable(interp, varName, JIM_NONE); + if (objPtr) { - if (Jim_DictSize(interp, objPtr) < 0) { - + Jim_Obj *objv[2]; + + objv[0] = objPtr; + objv[1] = listObj; + + objPtr = Jim_DictMerge(interp, 2, objv); + if (objPtr == NULL) { + Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); Jim_FreeNewObj(interp, listObj); return JIM_ERR; } - if (Jim_IsShared(objPtr)) - objPtr = Jim_DuplicateObj(interp, objPtr); - - - Jim_ListAppendList(interp, objPtr, listObj); - Jim_DictSize(interp, objPtr); Jim_InvalidateStringRep(objPtr); Jim_FreeNewObj(interp, listObj); @@ -3414,7 +3429,7 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat Jim_SetVariable(interp, varName, listObj); } - + Jim_SetResult(interp, listObj); return JIM_OK; @@ -3434,7 +3449,7 @@ static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_SetResultString(interp, "/", -1); } else if (ISWINDOWS && p[-1] == ':') { - + Jim_SetResultString(interp, path, p - path + 1); } else { @@ -3514,17 +3529,17 @@ static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) *newname = 0; - + for (i = 0; i < argc; i++) { int len; const char *part = Jim_GetString(argv[i], &len); if (*part == '/') { - + last = newname; } else if (ISWINDOWS && strchr(part, ':')) { - + last = newname; } else if (part[0] == '.') { @@ -3533,12 +3548,12 @@ static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) len -= 2; } else if (part[1] == 0 && last != newname) { - + continue; } } - + if (last != newname && last[-1] != '/') { *last++ = '/'; } @@ -3553,9 +3568,9 @@ static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) last += len; } - + if (last > newname + 1 && last[-1] == '/') { - + if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { *--last = 0; } @@ -3564,7 +3579,7 @@ static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) *last = 0; - + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); @@ -3593,7 +3608,7 @@ static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *arg #ifdef X_OK return file_access(interp, argv[0], X_OK); #else - + Jim_SetResultBool(interp, 1); return JIM_OK; #endif @@ -3618,7 +3633,7 @@ static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (unlink(path) == -1 && errno != ENOENT) { if (rmdir(path) == -1) { - + if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path, strerror(errno)); @@ -3641,11 +3656,11 @@ static int mkdir_all(char *path) { int ok = 1; - + goto first; while (ok--) { - + { char *slash = strrchr(path, '/'); @@ -3662,20 +3677,20 @@ static int mkdir_all(char *path) return 0; } if (errno == ENOENT) { - + continue; } - + if (errno == EEXIST) { struct stat sb; if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { return 0; } - + errno = EEXIST; } - + break; } return -1; @@ -3964,119 +3979,119 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_atime, 1, 1, - + }, { "mtime", "name ?time?", file_cmd_mtime, 1, 2, - + }, { "copy", "?-force? source dest", file_cmd_copy, 2, 3, - + }, { "dirname", "name", file_cmd_dirname, 1, 1, - + }, { "rootname", "name", file_cmd_rootname, 1, 1, - + }, { "extension", "name", file_cmd_extension, 1, 1, - + }, { "tail", "name", file_cmd_tail, 1, 1, - + }, { "normalize", "name", file_cmd_normalize, 1, 1, - + }, { "join", "name ?name ...?", file_cmd_join, 1, -1, - + }, { "readable", "name", file_cmd_readable, 1, 1, - + }, { "writable", "name", file_cmd_writable, 1, 1, - + }, { "executable", "name", file_cmd_executable, 1, 1, - + }, { "exists", "name", file_cmd_exists, 1, 1, - + }, { "delete", "?-force|--? name ...", file_cmd_delete, 1, -1, - + }, { "mkdir", "dir ...", file_cmd_mkdir, 1, -1, - + }, { "tempfile", "?template?", file_cmd_tempfile, 0, 1, - + }, { "rename", "?-force? source dest", file_cmd_rename, 2, 3, - + }, #if defined(HAVE_LINK) && defined(HAVE_SYMLINK) { "link", @@ -4084,7 +4099,7 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_link, 2, 3, - + }, #endif #if defined(HAVE_READLINK) @@ -4093,7 +4108,7 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_readlink, 1, 1, - + }, #endif { "size", @@ -4101,28 +4116,28 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_size, 1, 1, - + }, { "stat", "name ?var?", file_cmd_stat, 1, 2, - + }, { "lstat", "name ?var?", file_cmd_lstat, 1, 2, - + }, { "type", "name", file_cmd_type, 1, 1, - + }, #ifdef HAVE_GETEUID { "owned", @@ -4130,7 +4145,7 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_owned, 1, 1, - + }, #endif { "isdirectory", @@ -4138,14 +4153,14 @@ static const jim_subcmd_type file_command_table[] = { file_cmd_isdirectory, 1, 1, - + }, { "isfile", "name", file_cmd_isfile, 1, 1, - + }, { NULL @@ -4181,7 +4196,7 @@ static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } else if (ISWINDOWS) { - + char *p = cwd; while ((p = strchr(p, '\\')) != NULL) { *p++ = '/'; @@ -4205,6 +4220,9 @@ int Jim_fileInit(Jim_Interp *interp) return JIM_OK; } +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include <string.h> #include <ctype.h> @@ -4216,7 +4234,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int i, j; int rc; - + for (i = 1; i < argc; i++) { int len; const char *arg = Jim_GetString(argv[i], &len); @@ -4225,7 +4243,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_AppendString(interp, cmdlineObj, " ", 1); } if (strpbrk(arg, "\\\" ") == NULL) { - + Jim_AppendString(interp, cmdlineObj, arg, len); continue; } @@ -4270,7 +4288,7 @@ int Jim_execInit(Jim_Interp *interp) #include <signal.h> #if defined(__MINGW32__) - + #ifndef STRICT #define STRICT #endif @@ -4296,7 +4314,7 @@ int Jim_execInit(Jim_Interp *interp) static fdtype JimOpenForRead(const char *filename); static FILE *JimFdOpenForRead(fdtype fd); static int JimPipe(fdtype pipefd[2]); - static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, + static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, fdtype inputId, fdtype outputId, fdtype errorId); static int JimErrno(void); #else @@ -4325,6 +4343,7 @@ int Jim_execInit(Jim_Interp *interp) #endif static const char *JimStrError(void); +static char **JimOriginalEnviron(void); static char **JimSaveEnv(char **env); static void JimRestoreEnv(char **env); static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, @@ -4392,14 +4411,14 @@ static char **JimBuildEnv(Jim_Interp *interp) Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE); if (!objPtr) { - return Jim_GetEnviron(); + return JimOriginalEnviron(); } - + num = Jim_ListLength(interp, objPtr); if (num % 2) { - + num--; } size = Jim_Length(objPtr) + 2; @@ -4495,15 +4514,15 @@ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, J struct WaitInfo { - pidtype pid; - int status; - int flags; + pidtype pid; + int status; + int flags; }; struct WaitInfoTable { - struct WaitInfo *info; - int size; - int used; + struct WaitInfo *info; + int size; + int used; }; @@ -4530,8 +4549,8 @@ static struct WaitInfoTable *JimAllocWaitInfoTable(void) static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - fdtype outputId; - fdtype errorId; + fdtype outputId; + fdtype errorId; pidtype *pidPtr; int numPids, result; int child_siginfo = 1; @@ -4547,7 +4566,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (numPids < 0) { return JIM_ERR; } - + listObj = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < numPids; i++) { Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); @@ -4569,7 +4588,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) errStrObj = Jim_NewStringObj(interp, "", 0); - + if (outputId != JIM_BAD_FD) { if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) { result = JIM_ERR; @@ -4577,7 +4596,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } } - + childErrObj = Jim_NewStringObj(interp, "", 0); Jim_IncrRefCount(childErrObj); @@ -4594,21 +4613,21 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) result = JIM_ERR; } else if (ret > 0) { - + child_siginfo = 0; } } if (child_siginfo) { - + Jim_AppendObj(interp, errStrObj, childErrObj); } Jim_DecrRefCount(interp, childErrObj); - + Jim_RemoveTrailingNewline(errStrObj); - + Jim_SetResult(interp, errStrObj); return result; @@ -4631,7 +4650,7 @@ static void JimReapDetachedPids(struct WaitInfoTable *table) int status; pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG); if (pid == waitPtr->pid) { - + table->used--; continue; } @@ -4647,13 +4666,13 @@ static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int * { int i; - + for (i = 0; i < table->used; i++) { if (pid == table->info[i].pid) { - + JimWaitPid(pid, statusPtr, 0); - + if (i != table->used - 1) { table->info[i] = table->info[table->used - 1]; } @@ -4662,7 +4681,7 @@ static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int * } } - + return JIM_BAD_PID; } @@ -4672,7 +4691,7 @@ static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr struct WaitInfoTable *table = Jim_CmdPrivData(interp); for (j = 0; j < numPids; j++) { - + int i; for (i = 0; i < table->used; i++) { if (pidPtr[j] == table->info[i].pid) { @@ -4709,12 +4728,12 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** const char *input = NULL; /* Describes input for pipeline, depending * on "inputFile". NULL means take input * from stdin/pipe. */ - int input_len = 0; + int input_len = 0; -#define FILE_NAME 0 -#define FILE_APPEND 1 -#define FILE_HANDLE 2 -#define FILE_TEXT 3 +#define FILE_NAME 0 +#define FILE_APPEND 1 +#define FILE_HANDLE 2 +#define FILE_TEXT 3 int inputFile = FILE_NAME; /* 1 means input is name of input file. * 2 means input is filehandle name. @@ -4739,7 +4758,7 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** fdtype outputId = JIM_BAD_FD; fdtype errorId = JIM_BAD_FD; fdtype lastOutputId = JIM_BAD_FD; - fdtype pipeIds[2]; + fdtype pipeIds[2]; int firstArg, lastArg; /* Indexes of first and last arguments in * current command. */ int lastBar; @@ -4748,7 +4767,7 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** char **save_environ; struct WaitInfoTable *table = Jim_CmdPrivData(interp); - + char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1)); int arg_count = 0; @@ -4798,7 +4817,7 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** output++; } if (*output == '&') { - + output++; dup_error = 1; } @@ -4839,7 +4858,7 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** lastBar = i; cmdCount++; } - + arg_array[arg_count++] = (char *)arg; continue; } @@ -4857,7 +4876,7 @@ badargs: return -1; } - + save_environ = JimSaveEnv(JimBuildEnv(interp)); if (input != NULL) { @@ -4868,7 +4887,7 @@ badargs: } } else if (inputFile == FILE_HANDLE) { - + FILE *fh = JimGetAioFilehandle(interp, input); if (fh == NULL) { @@ -4920,16 +4939,16 @@ badargs: *outPipePtr = pipeIds[0]; pipeIds[0] = pipeIds[1] = JIM_BAD_FD; } - + if (error != NULL) { if (errorFile == FILE_HANDLE) { if (strcmp(error, "1") == 0) { - + if (lastOutputId != JIM_BAD_FD) { errorId = JimDupFd(lastOutputId); } else { - + error = "stdout"; } } @@ -4975,7 +4994,7 @@ badargs: break; } } - + arg_array[lastArg] = NULL; if (lastArg == arg_count) { outputId = lastOutputId; @@ -4988,15 +5007,15 @@ badargs: outputId = pipeIds[1]; } - + if (pipe_dup_err) { errorId = outputId; } - + #ifdef __MINGW32__ - pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId); + pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ, inputId, outputId, errorId); if (pid == JIM_BAD_PID) { Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]); goto error; @@ -5008,7 +5027,7 @@ badargs: goto error; } if (pid == 0) { - + if (inputId != -1) dup2(inputId, 0); if (outputId != -1) dup2(outputId, 1); @@ -5018,18 +5037,25 @@ badargs: close(i); } - + (void)signal(SIGPIPE, SIG_DFL); execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron()); - + fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]); +#ifdef JIM_MAINTAINER + { + + static char *const false_argv[2] = {"false", NULL}; + execvp(false_argv[0],false_argv); + } +#endif _exit(127); } #endif - + if (table->used == table->size) { table->size += WAIT_TABLE_GROW_BY; @@ -5042,7 +5068,7 @@ badargs: pidPtr[numPids] = pid; - + errorId = origErrorId; @@ -5051,6 +5077,7 @@ badargs: } if (outputId != JIM_BAD_FD) { JimCloseFd(outputId); + outputId = JIM_BAD_FD; } inputId = pipeIds[0]; pipeIds[0] = pipeIds[1] = JIM_BAD_FD; @@ -5113,7 +5140,7 @@ static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, int result = JIM_OK; int i; - + for (i = 0; i < numPids; i++) { int waitStatus = 0; if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) { @@ -5286,13 +5313,17 @@ static fdtype JimFileno(FILE *fh) static fdtype JimOpenForRead(const char *filename) { return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - JimStdSecAttrs(), OPEN_EXISTING, 0, NULL); + JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } static fdtype JimOpenForWrite(const char *filename, int append) { - return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL); + fdtype fd = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); + if (append && fd != JIM_BAD_FD) { + SetFilePointer(fd, 0, NULL, FILE_END); + } + return fd; } static FILE *JimFdOpenForWrite(fdtype fd) @@ -5304,7 +5335,7 @@ static pidtype JimWaitPid(pidtype pid, int *status, int nohang) { DWORD ret = WaitForSingleObject(pid, nohang ? 0 : INFINITE); if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) { - + return JIM_BAD_PID; } GetExitCodeProcess(pid, &ret); @@ -5331,7 +5362,7 @@ static HANDLE JimCreateTemp(Jim_Interp *interp, const char *contents, int len) } if (contents != NULL) { - + FILE *fh = JimFdOpenForWrite(JimDupFd(handle)); if (fh == NULL) { goto error; @@ -5384,6 +5415,11 @@ static void JimRestoreEnv(char **env) JimFreeEnv(env, Jim_GetEnviron()); } +static char **JimOriginalEnviron(void) +{ + return NULL; +} + static Jim_Obj * JimWinBuildCommandLine(Jim_Interp *interp, char **argv) { @@ -5457,7 +5493,7 @@ JimWinBuildCommandLine(Jim_Interp *interp, char **argv) } static pidtype -JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, fdtype outputId, fdtype errorId) +JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, fdtype inputId, fdtype outputId, fdtype errorId) { STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; @@ -5465,6 +5501,7 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, f char execPath[MAX_PATH]; pidtype pid = JIM_BAD_PID; Jim_Obj *cmdLineObj; + char *winenv; if (JimWinFindExecutable(argv[0], execPath) < 0) { return JIM_BAD_PID; @@ -5517,8 +5554,19 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, f goto end; } + if (env == NULL) { + + winenv = NULL; + } + else if (env[0] == NULL) { + winenv = (char *)"\0"; + } + else { + winenv = env[0]; + } + if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, - 0, env, NULL, &startInfo, &procInfo)) { + 0, winenv, NULL, &startInfo, &procInfo)) { goto end; } @@ -5571,6 +5619,11 @@ static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) return fd; } +static char **JimOriginalEnviron(void) +{ + return Jim_GetEnviron(); +} + static char **JimSaveEnv(char **env) { char **saveenv = Jim_GetEnviron(); @@ -5603,7 +5656,7 @@ static void JimRestoreEnv(char **env) static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - + char buf[100]; time_t t; long seconds; @@ -5644,7 +5697,7 @@ static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return -1; } - + localtime_r(&now, &tm); pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm); @@ -5653,7 +5706,7 @@ static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - + Jim_SetResultInt(interp, mktime(&tm)); return JIM_OK; @@ -5695,35 +5748,35 @@ static const jim_subcmd_type clock_command_table[] = { clock_cmd_seconds, 0, 0, - + }, { "clicks", NULL, clock_cmd_micros, 0, 0, - + }, { "microseconds", NULL, clock_cmd_micros, 0, 0, - + }, { "milliseconds", NULL, clock_cmd_millis, 0, 0, - + }, { "format", "seconds ?-format format?", clock_cmd_format, 1, 3, - + }, #ifdef HAVE_STRPTIME { "scan", @@ -5731,7 +5784,7 @@ static const jim_subcmd_type clock_command_table[] = { clock_cmd_scan, 3, 3, - + }, #endif { NULL } @@ -5755,8 +5808,9 @@ int Jim_clockInit(Jim_Interp *interp) static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - - Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0); + + Jim_Obj *dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); + Jim_SetResultInt(interp, dictObj && Jim_DictSize(interp, dictObj) != -1); return JIM_OK; } @@ -5771,17 +5825,16 @@ static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) patternObj = (argc == 1) ? NULL : argv[1]; - + if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) { if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) { - + Jim_SetResult(interp, objPtr); return JIM_OK; } } - - return Jim_DictValues(interp, objPtr, patternObj); + return Jim_DictMatchTypes(interp, objPtr, patternObj, JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS | JIM_DICTMATCH_VALUES); } static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -5792,7 +5845,7 @@ static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } - return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]); + return Jim_DictMatchTypes(interp, objPtr, argc == 1 ? NULL : argv[1], JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS); } static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -5804,7 +5857,7 @@ static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Obj **dictValuesObj; if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { - + Jim_UnsetVariable(interp, argv[0], JIM_NONE); return JIM_OK; } @@ -5812,15 +5865,17 @@ static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); if (objPtr == NULL) { - + return JIM_OK; } if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) { - return JIM_ERR; + + Jim_SetResultString(interp, "", -1); + return JIM_OK; } - + resultObj = Jim_NewDictObj(interp, NULL, 0); for (i = 0; i < len; i += 2) { @@ -5839,12 +5894,14 @@ static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Obj *objPtr; int len = 0; - + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); if (objPtr) { len = Jim_DictSize(interp, objPtr); if (len < 0) { - return JIM_ERR; + + Jim_SetResultInt(interp, 0); + return JIM_OK; } } @@ -5878,7 +5935,7 @@ static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); if (!dictObj) { - + return Jim_SetVariable(interp, argv[0], listObj); } else if (Jim_DictSize(interp, dictObj) < 0) { @@ -5907,49 +5964,49 @@ static const jim_subcmd_type array_command_table[] = { array_cmd_exists, 1, 1, - + }, { "get", "arrayName ?pattern?", array_cmd_get, 1, 2, - + }, { "names", "arrayName ?pattern?", array_cmd_names, 1, 2, - + }, { "set", "arrayName list", array_cmd_set, 2, 2, - + }, { "size", "arrayName", array_cmd_size, 1, 1, - + }, { "stat", "arrayName", array_cmd_stat, 1, 1, - + }, { "unset", "arrayName ?pattern?", array_cmd_unset, 1, 2, - + }, { NULL } @@ -5989,7 +6046,10 @@ Jim_stdlibInit(interp); Jim_tclcompatInit(interp); return JIM_OK; } -#define JIM_OPTIMIZATION +#define JIM_OPTIMIZATION +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include <stdio.h> #include <stdlib.h> @@ -6058,6 +6118,12 @@ static void JimPanicDump(int fail_condition, const char *fmt, ...); #define JimPanic(X) #endif +#ifdef JIM_OPTIMIZATION +#define JIM_IF_OPTIM(X) X +#else +#define JIM_IF_OPTIM(X) +#endif + static char JimEmptyStringRep[] = ""; @@ -6114,30 +6180,30 @@ static const char *JimCharsetMatch(const char *pattern, int c, int flags) pattern++; } - + if (*pattern == ']') { goto first; } } while (*pattern && *pattern != ']') { - + if (pattern[0] == '\\') { first: pattern += utf8_tounicode_case(pattern, &pchar, nocase); } else { - + int start; int end; pattern += utf8_tounicode_case(pattern, &start, nocase); if (pattern[0] == '-' && pattern[1]) { - + pattern += utf8_tounicode(pattern, &pchar); pattern += utf8_tounicode_case(pattern, &end, nocase); - + if ((c >= start && c <= end) || (c >= end && c <= start)) { match = 1; } @@ -6171,15 +6237,15 @@ static int JimGlobMatch(const char *pattern, const char *string, int nocase) } pattern++; if (!pattern[0]) { - return 1; + return 1; } while (*string) { - + if (JimGlobMatch(pattern, string, nocase)) - return 1; + return 1; string += utf8_tounicode(string, &c); } - return 0; + return 0; case '?': string += utf8_tounicode(string, &c); @@ -6192,7 +6258,7 @@ static int JimGlobMatch(const char *pattern, const char *string, int nocase) return 0; } if (!*pattern) { - + continue; } break; @@ -6201,7 +6267,7 @@ static int JimGlobMatch(const char *pattern, const char *string, int nocase) if (pattern[1]) { pattern++; } - + default: string += utf8_tounicode_case(string, &c, nocase); utf8_tounicode_case(pattern, &pchar, nocase); @@ -6251,7 +6317,7 @@ static int JimStringCompareLen(const char *s1, const char *s2, int maxchars, int if (!maxchars) { return 0; } - + if (*s1) { return 1; } @@ -6292,7 +6358,7 @@ static int JimStringLast(const char *s1, int l1, const char *s2, int l2) if (!l1 || !l2 || l1 > l2) return -1; - + for (p = s2 + l2 - 1; p != s2 - 1; p--) { if (*p == *s1 && memcmp(s1, p, l1) == 0) { return p - s2; @@ -6351,11 +6417,11 @@ static int JimNumberBase(const char *str, int *base, int *sign) } if (str[i] != '0') { - + return 0; } - + switch (str[i + 1]) { case 'x': case 'X': *base = 16; break; case 'o': case 'O': *base = 8; break; @@ -6363,12 +6429,12 @@ static int JimNumberBase(const char *str, int *base, int *sign) default: return 0; } i += 2; - + if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) { - + return i; } - + *base = 10; return 0; } @@ -6386,7 +6452,7 @@ static long jim_strtol(const char *str, char **endptr) } } - + return strtol(str, endptr, 10); } @@ -6405,7 +6471,7 @@ static jim_wide jim_strtoull(const char *str, char **endptr) } } - + return strtoull(str, endptr, 10); #else return (unsigned long)jim_strtol(str, endptr); @@ -6430,7 +6496,7 @@ int Jim_StringToDouble(const char *str, double *doublePtr) { char *endptr; - + errno = 0; *doublePtr = strtod(str, &endptr); @@ -6440,12 +6506,26 @@ int Jim_StringToDouble(const char *str, double *doublePtr) static jim_wide JimPowWide(jim_wide b, jim_wide e) { - jim_wide i, res = 1; + jim_wide res = 1; - if ((b == 0 && e != 0) || (e < 0)) - return 0; - for (i = 0; i < e; i++) { - res *= b; + + if (b == 1) { + + return 1; + } + if (e < 0) { + if (b != -1) { + return 0; + } + e = -e; + } + while (e) + { + if (e & 1) { + res *= b; + } + e >>= 1; + b *= b; } return res; } @@ -6511,7 +6591,7 @@ char *Jim_StrDupLen(const char *s, int l) char *copy = Jim_Alloc(l + 1); memcpy(copy, s, l + 1); - copy[l] = 0; + copy[l] = 0; return copy; } @@ -6600,7 +6680,7 @@ void Jim_ResizeHashTable(Jim_HashTable *ht) void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) { - Jim_HashTable n; + Jim_HashTable n; unsigned int realsize = JimHashTableNextPower(size), i; if (size <= ht->used) @@ -6610,10 +6690,10 @@ void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) n.size = realsize; n.sizemask = realsize - 1; n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *)); - + n.uniq = ht->uniq; - + memset(n.table, 0, realsize * sizeof(Jim_HashEntry *)); n.used = ht->used; @@ -6623,25 +6703,25 @@ void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) if (ht->table[i] == NULL) continue; - + he = ht->table[i]; while (he) { unsigned int h; nextHe = he->next; - + h = Jim_HashKey(ht, he->key) & n.sizemask; he->next = n.table[h]; n.table[h] = he; ht->used--; - + he = nextHe; } } assert(ht->used == 0); Jim_Free(ht->table); - + *ht = n; } @@ -6654,7 +6734,7 @@ int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val) if (entry == NULL) return JIM_ERR; - + Jim_SetHashKey(ht, entry, key); Jim_SetHashVal(ht, entry, val); return JIM_OK; @@ -6680,7 +6760,7 @@ int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val) existed = 1; } else { - + Jim_SetHashKey(ht, entry, key); Jim_SetHashVal(ht, entry, val); existed = 0; @@ -6703,7 +6783,7 @@ int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key) prevHe = NULL; while (he) { if (Jim_CompareHashKeys(ht, key, he->key)) { - + if (prevHe) prevHe->next = he->next; else @@ -6717,7 +6797,7 @@ int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key) prevHe = he; he = he->next; } - return JIM_ERR; + return JIM_ERR; } @@ -6725,7 +6805,7 @@ int Jim_FreeHashTable(Jim_HashTable *ht) { unsigned int i; - + for (i = 0; ht->used > 0; i++) { Jim_HashEntry *he, *nextHe; @@ -6740,11 +6820,11 @@ int Jim_FreeHashTable(Jim_HashTable *ht) he = nextHe; } } - + Jim_Free(ht->table); - + JimResetHashTable(ht); - return JIM_OK; + return JIM_OK; } Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key) @@ -6821,12 +6901,12 @@ static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int unsigned int h; Jim_HashEntry *he; - + JimExpandHashTableIfNeeded(ht); - + h = Jim_HashKey(ht, key) & ht->sizemask; - + he = ht->table[h]; while (he) { if (Jim_CompareHashKeys(ht, key, he->key)) @@ -6834,7 +6914,7 @@ static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int he = he->next; } - + he = Jim_Alloc(sizeof(*he)); he->next = ht->table[h]; ht->table[h] = he; @@ -6867,12 +6947,12 @@ static void JimStringCopyHTKeyDestructor(void *privdata, void *key) } static const Jim_HashTableType JimPackageHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - NULL + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + NULL }; typedef struct AssocDataValue @@ -6891,12 +6971,12 @@ static void JimAssocDataHashTableValueDestructor(void *privdata, void *data) } static const Jim_HashTableType JimAssocDataHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimAssocDataHashTableValueDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimAssocDataHashTableValueDestructor }; void Jim_InitStack(Jim_Stack *stack) @@ -6953,19 +7033,19 @@ void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr)) -#define JIM_TT_NONE 0 -#define JIM_TT_STR 1 -#define JIM_TT_ESC 2 -#define JIM_TT_VAR 3 -#define JIM_TT_DICTSUGAR 4 -#define JIM_TT_CMD 5 +#define JIM_TT_NONE 0 +#define JIM_TT_STR 1 +#define JIM_TT_ESC 2 +#define JIM_TT_VAR 3 +#define JIM_TT_DICTSUGAR 4 +#define JIM_TT_CMD 5 -#define JIM_TT_SEP 6 -#define JIM_TT_EOL 7 -#define JIM_TT_EOF 8 +#define JIM_TT_SEP 6 +#define JIM_TT_EOL 7 +#define JIM_TT_EOF 8 -#define JIM_TT_LINE 9 -#define JIM_TT_WORD 10 +#define JIM_TT_LINE 9 +#define JIM_TT_WORD 10 #define JIM_TT_SUBEXPR_START 11 @@ -6973,32 +7053,37 @@ void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr)) #define JIM_TT_SUBEXPR_COMMA 13 #define JIM_TT_EXPR_INT 14 #define JIM_TT_EXPR_DOUBLE 15 +#define JIM_TT_EXPR_BOOLEAN 16 -#define JIM_TT_EXPRSUGAR 16 +#define JIM_TT_EXPRSUGAR 17 #define JIM_TT_EXPR_OP 20 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) +#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA) + +#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP) + struct JimParseMissing { - int ch; - int line; + int ch; + int line; }; struct JimParserCtx { - const char *p; - int len; - int linenr; + const char *p; + int len; + int linenr; const char *tstart; - const char *tend; - int tline; - int tt; - int eof; - int inquote; - int comment; - struct JimParseMissing missing; + const char *tend; + int tline; + int tt; + int eof; + int inquote; + int comment; + struct JimParseMissing missing; }; static int JimParseScript(struct JimParserCtx *pc); @@ -7032,7 +7117,7 @@ static void JimParserInit(struct JimParserCtx *pc, const char *prg, int len, int static int JimParseScript(struct JimParserCtx *pc) { - while (1) { + while (1) { if (!pc->len) { pc->tstart = pc->p; pc->tend = pc->p - 1; @@ -7068,7 +7153,7 @@ static int JimParseScript(struct JimParserCtx *pc) case '$': pc->comment = 0; if (JimParseVar(pc) == JIM_ERR) { - + pc->tstart = pc->tend = pc->p++; pc->len--; pc->tt = JIM_TT_ESC; @@ -7129,7 +7214,7 @@ static void JimParseSubBrace(struct JimParserCtx *pc) { int level = 1; - + pc->p++; pc->len--; while (pc->len) { @@ -7173,7 +7258,7 @@ static int JimParseSubQuote(struct JimParserCtx *pc) int tt = JIM_TT_STR; int line = pc->tline; - + pc->p++; pc->len--; while (pc->len) { @@ -7222,7 +7307,7 @@ static void JimParseSubCmd(struct JimParserCtx *pc) int startofword = 1; int line = pc->tline; - + pc->p++; pc->len--; while (pc->len) { @@ -7302,13 +7387,13 @@ static int JimParseQuote(struct JimParserCtx *pc) static int JimParseVar(struct JimParserCtx *pc) { - + pc->p++; pc->len--; #ifdef EXPRSUGAR_BRACKET if (*pc->p == '[') { - + JimParseCmd(pc); pc->tt = JIM_TT_EXPRSUGAR; return JIM_OK; @@ -7338,7 +7423,7 @@ static int JimParseVar(struct JimParserCtx *pc) } else { while (1) { - + if (pc->p[0] == ':' && pc->p[1] == ':') { while (*pc->p == ':') { pc->p++; @@ -7353,7 +7438,7 @@ static int JimParseVar(struct JimParserCtx *pc) } break; } - + if (*pc->p == '(') { int count = 1; const char *paren = NULL; @@ -7380,7 +7465,7 @@ static int JimParseVar(struct JimParserCtx *pc) pc->len--; } else if (paren) { - + paren++; pc->len += (pc->p - paren); pc->p = paren; @@ -7405,7 +7490,7 @@ static int JimParseStr(struct JimParserCtx *pc) { if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL || pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) { - + if (*pc->p == '{') { return JimParseBrace(pc); } @@ -7413,7 +7498,7 @@ static int JimParseStr(struct JimParserCtx *pc) pc->inquote = 1; pc->p++; pc->len--; - + pc->missing.line = pc->tline; } } @@ -7443,21 +7528,21 @@ static int JimParseStr(struct JimParserCtx *pc) pc->len--; } else if (pc->len == 1) { - + pc->missing.ch = '\\'; } break; case '(': - + if (pc->len > 1 && pc->p[1] != '$') { break; } - + case ')': - + if (*pc->p == '(' || pc->tt == JIM_TT_VAR) { if (pc->p == pc->tstart) { - + pc->p++; pc->len--; } @@ -7501,7 +7586,7 @@ static int JimParseStr(struct JimParserCtx *pc) pc->p++; pc->len--; } - return JIM_OK; + return JIM_OK; } static int JimParseComment(struct JimParserCtx *pc) @@ -7612,20 +7697,20 @@ static int JimEscape(char *dest, const char *s, int slen) } val = (val << 4) | c; } - + if (s[i] == '{') { if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') { - + i--; k = 0; } else { - + k++; } } if (k) { - + if (s[i] == 'x') { *p++ = val; } @@ -7635,7 +7720,7 @@ static int JimEscape(char *dest, const char *s, int slen) i += k; break; } - + *p++ = s[i]; } break; @@ -7648,7 +7733,7 @@ static int JimEscape(char *dest, const char *s, int slen) i++; break; case '\n': - + *p++ = ' '; do { i++; @@ -7662,7 +7747,7 @@ static int JimEscape(char *dest, const char *s, int slen) case '5': case '6': case '7': - + { int val = 0; int c = odigitval(s[i + 1]); @@ -7719,12 +7804,12 @@ static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc len = (end - start) + 1; token = Jim_Alloc(len + 1); if (pc->tt != JIM_TT_ESC) { - + memcpy(token, start, len); token[len] = '\0'; } else { - + len = JimEscape(token, start, len); } } @@ -7792,7 +7877,7 @@ static int JimParseListQuote(struct JimParserCtx *pc) case '\\': pc->tt = JIM_TT_ESC; if (--pc->len == 0) { - + pc->tend = pc->p; return JIM_OK; } @@ -7828,7 +7913,7 @@ static int JimParseListStr(struct JimParserCtx *pc) } if (*pc->p == '\\') { if (--pc->len == 0) { - + pc->tend = pc->p; return JIM_OK; } @@ -7848,20 +7933,20 @@ Jim_Obj *Jim_NewObj(Jim_Interp *interp) { Jim_Obj *objPtr; - + if (interp->freeList != NULL) { - + objPtr = interp->freeList; interp->freeList = objPtr->nextObjPtr; } else { - + objPtr = Jim_Alloc(sizeof(*objPtr)); } objPtr->refCount = 0; - + objPtr->prevObjPtr = NULL; objPtr->nextObjPtr = interp->liveList; if (interp->liveList) @@ -7873,18 +7958,18 @@ Jim_Obj *Jim_NewObj(Jim_Interp *interp) void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) { - + JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr, objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "<none>")); - + Jim_FreeIntRep(interp, objPtr); - + if (objPtr->bytes != NULL) { if (objPtr->bytes != JimEmptyStringRep) Jim_Free(objPtr->bytes); } - + if (objPtr->prevObjPtr) objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr; if (objPtr->nextObjPtr) @@ -7894,7 +7979,7 @@ void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) #ifdef JIM_DISABLE_OBJECT_POOL Jim_Free(objPtr); #else - + objPtr->prevObjPtr = NULL; objPtr->nextObjPtr = interp->freeList; if (interp->freeList) @@ -7921,11 +8006,11 @@ Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) dupPtr = Jim_NewObj(interp); if (objPtr->bytes == NULL) { - + dupPtr->bytes = NULL; } else if (objPtr->length == 0) { - + dupPtr->bytes = JimEmptyStringRep; dupPtr->length = 0; dupPtr->typePtr = NULL; @@ -7934,18 +8019,18 @@ Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) else { dupPtr->bytes = Jim_Alloc(objPtr->length + 1); dupPtr->length = objPtr->length; - + memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1); } - + dupPtr->typePtr = objPtr->typePtr; if (objPtr->typePtr != NULL) { if (objPtr->typePtr->dupIntRepProc == NULL) { dupPtr->internalRep = objPtr->internalRep; } else { - + objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr); } } @@ -7955,7 +8040,7 @@ Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) { if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); } @@ -7968,7 +8053,7 @@ const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) int Jim_Length(Jim_Obj *objPtr) { if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); } @@ -7979,7 +8064,7 @@ int Jim_Length(Jim_Obj *objPtr) const char *Jim_String(Jim_Obj *objPtr) { if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value.")); JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); @@ -8039,18 +8124,18 @@ static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *d static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr->typePtr != &stringObjType) { - + if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); } - + Jim_FreeIntRep(interp, objPtr); - + objPtr->typePtr = &stringObjType; objPtr->internalRep.strValue.maxLength = objPtr->length; - + objPtr->internalRep.strValue.charLength = -1; } return JIM_OK; @@ -8075,10 +8160,10 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) { Jim_Obj *objPtr = Jim_NewObj(interp); - + if (len == -1) len = strlen(s); - + if (len == 0) { objPtr->bytes = JimEmptyStringRep; } @@ -8089,7 +8174,7 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) } objPtr->length = len; - + objPtr->typePtr = NULL; return objPtr; } @@ -8098,12 +8183,12 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen) { #ifdef JIM_UTF8 - + int bytelen = utf8_index(s, charlen); Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen); - + objPtr->typePtr = &stringObjType; objPtr->internalRep.strValue.maxLength = bytelen; objPtr->internalRep.strValue.charLength = charlen; @@ -8134,7 +8219,7 @@ static void StringAppendString(Jim_Obj *objPtr, const char *str, int len) if (objPtr->internalRep.strValue.maxLength < needlen || objPtr->internalRep.strValue.maxLength == 0) { needlen *= 2; - + if (needlen < 7) { needlen = 7; } @@ -8150,7 +8235,7 @@ static void StringAppendString(Jim_Obj *objPtr, const char *str, int len) objPtr->bytes[objPtr->length + len] = '\0'; if (objPtr->internalRep.strValue.charLength >= 0) { - + objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len); } objPtr->length += len; @@ -8212,7 +8297,7 @@ int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *seco const char *s2 = Jim_GetString(secondObjPtr, &l2); if (nocase) { - + return JimStringCompareLen(s1, s2, -1, nocase); } return JimStringCompare(s1, l1, s2, l2); @@ -8314,7 +8399,7 @@ Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp, return strObjPtr; } if (len == bytelen) { - + return Jim_NewStringObj(interp, str + first, rangeLen); } return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen); @@ -8343,15 +8428,15 @@ Jim_Obj *JimStringReplaceObj(Jim_Interp *interp, str = Jim_String(strObjPtr); - + objPtr = Jim_NewStringObjUtf8(interp, str, first); - + if (newStrObj) { Jim_AppendObj(interp, objPtr, newStrObj); } - + Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1); return objPtr; @@ -8454,7 +8539,7 @@ static const char *JimFindTrimLeft(const char *str, int len, const char *trimcha int n = utf8_tounicode(str, &c); if (utf8_memchr(trimchars, trimlen, c) == NULL) { - + break; } str += n; @@ -8525,11 +8610,11 @@ static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_O nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen); if (nontrim == NULL) { - + return Jim_NewEmptyStringObj(interp); } if (nontrim == strObjPtr->bytes + len) { - + return strObjPtr; } @@ -8537,7 +8622,7 @@ static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_O strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes)); } else { - + strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0; strObjPtr->length = (nontrim - strObjPtr->bytes); } @@ -8547,15 +8632,15 @@ static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_O static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) { - + Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr); - + strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr); - + if (objPtr != strObjPtr && objPtr->refCount == 0) { - + Jim_FreeNewObj(interp, objPtr); } @@ -8577,13 +8662,13 @@ static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass static const char * const strclassnames[] = { "integer", "alpha", "alnum", "ascii", "digit", "double", "lower", "upper", "space", "xdigit", - "control", "print", "graph", "punct", + "control", "print", "graph", "punct", "boolean", NULL }; enum { STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT, - STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN, }; int strclass; int len; @@ -8616,6 +8701,13 @@ static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass return JIM_OK; } + case STR_IS_BOOLEAN: + { + int b; + Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK); + return JIM_OK; + } + case STR_IS_ALPHA: isclassfunc = isalpha; break; case STR_IS_ALNUM: isclassfunc = isalnum; break; case STR_IS_ASCII: isclassfunc = jim_isascii; break; @@ -8633,7 +8725,7 @@ static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass } for (i = 0; i < len; i++) { - if (!isclassfunc(str[i])) { + if (!isclassfunc(UCHAR(str[i]))) { Jim_SetResultBool(interp, 0); return JIM_OK; } @@ -8667,7 +8759,7 @@ int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char * Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &comparedStringObjType; } - objPtr->internalRep.ptr = (char *)str; + objPtr->internalRep.ptr = (char *)str; return 1; } } @@ -8760,16 +8852,16 @@ typedef struct ScriptToken typedef struct ScriptObj { - ScriptToken *token; - Jim_Obj *fileNameObj; - int len; - int substFlags; + ScriptToken *token; + Jim_Obj *fileNameObj; + int len; + int substFlags; int inUse; /* Used to share a ScriptObj. Currently only used by Jim_EvalObj() as protection against shimmering of the currently evaluated object. */ - int firstline; - int linenr; - int missing; + int firstline; + int linenr; + int missing; } ScriptObj; static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); @@ -8801,19 +8893,19 @@ void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) typedef struct { - const char *token; - int len; - int type; - int line; + const char *token; + int len; + int type; + int line; } ParseToken; typedef struct { - - ParseToken *list; - int size; - int count; - ParseToken static_list[20]; + + ParseToken *list; + int size; + int count; + ParseToken static_list[20]; } ParseTokenList; static void ScriptTokenListInit(ParseTokenList *tokenlist) @@ -8836,14 +8928,14 @@ static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len ParseToken *t; if (tokenlist->count == tokenlist->size) { - + tokenlist->size *= 2; if (tokenlist->list != tokenlist->static_list) { tokenlist->list = Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list)); } else { - + tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list)); memcpy(tokenlist->list, tokenlist->static_list, tokenlist->count * sizeof(*tokenlist->list)); @@ -8861,16 +8953,16 @@ static int JimCountWordTokens(ParseToken *t) int expand = 1; int count = 0; - + if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) { if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) { - + expand = -1; t++; } } - + while (!TOKEN_IS_SEP(t->type)) { t++; count++; @@ -8884,7 +8976,7 @@ static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t) Jim_Obj *objPtr; if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) { - + int len = t->len; char *str = Jim_Alloc(len + 1); len = JimEscape(str, t->token, len); @@ -8901,9 +8993,9 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, { int i; struct ScriptToken *token; - + int lineargs = 0; - + ScriptToken *linefirst; int count; int linenr; @@ -8916,7 +9008,7 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, } #endif - + count = tokenlist->count; for (i = 0; i < tokenlist->count; i++) { if (tokenlist->list[i].type == JIM_TT_EOL) { @@ -8927,14 +9019,14 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, token = script->token = Jim_Alloc(sizeof(ScriptToken) * count); - + linefirst = token++; for (i = 0; i < tokenlist->count; ) { - + int wordtokens; - + while (tokenlist->list[i].type == JIM_TT_SEP) { i++; } @@ -8942,13 +9034,13 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, wordtokens = JimCountWordTokens(tokenlist->list + i); if (wordtokens == 0) { - + if (lineargs) { linefirst->type = JIM_TT_LINE; linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr); Jim_IncrRefCount(linefirst->objPtr); - + lineargs = 0; linefirst = token++; } @@ -8956,13 +9048,13 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, continue; } else if (wordtokens != 1) { - + token->type = JIM_TT_WORD; token->objPtr = Jim_NewIntObj(interp, wordtokens); Jim_IncrRefCount(token->objPtr); token++; if (wordtokens < 0) { - + i++; wordtokens = -wordtokens - 1; lineargs--; @@ -8970,12 +9062,12 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, } if (lineargs == 0) { - + linenr = tokenlist->list[i].line; } lineargs++; - + while (wordtokens--) { const ParseToken *t = &tokenlist->list[i++]; @@ -9051,7 +9143,7 @@ static void SubstObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, for (i = 0; i < tokenlist->count; i++) { const ParseToken *t = &tokenlist->list[i]; - + token->type = t->type; token->objPtr = JimMakeScriptObj(interp, t); Jim_IncrRefCount(token->objPtr); @@ -9070,12 +9162,12 @@ static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) ParseTokenList tokenlist; int line = 1; - + if (objPtr->typePtr == &sourceObjType) { line = objPtr->internalRep.sourceValue.lineNumber; } - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, scriptText, scriptTextLen, line); @@ -9085,10 +9177,10 @@ static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) parser.tline); } - + ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); - + script = Jim_Alloc(sizeof(*script)); memset(script, 0, sizeof(*script)); script->inUse = 1; @@ -9104,10 +9196,10 @@ static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) ScriptObjAddTokens(interp, script, &tokenlist); - + ScriptTokenListFree(&tokenlist); - + Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, script); objPtr->typePtr = &scriptObjType; @@ -9118,7 +9210,7 @@ static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script); static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr == interp->emptyObj) { - + objPtr = interp->nullScriptObj; } @@ -9157,13 +9249,13 @@ static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) } } else { - + if (cmdPtr->u.native.delProc) { cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData); } } if (cmdPtr->prevCmd) { - + JimDecrCmdRefCount(interp, cmdPtr->prevCmd); } Jim_Free(cmdPtr); @@ -9178,12 +9270,12 @@ static void JimVariablesHTValDestructor(void *interp, void *val) } static const Jim_HashTableType JimVariablesHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimVariablesHTValDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimVariablesHTValDestructor }; static void JimCommandsHT_ValDestructor(void *interp, void *val) @@ -9192,12 +9284,12 @@ static void JimCommandsHT_ValDestructor(void *interp, void *val) } static const Jim_HashTableType JimCommandsHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimCommandsHT_ValDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimCommandsHT_ValDestructor }; @@ -9207,13 +9299,13 @@ static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj) { const char *name = Jim_String(nsObj); if (name[0] == ':' && name[1] == ':') { - + while (*++name == ':') { } nsObj = Jim_NewStringObj(interp, name, -1); } else if (Jim_Length(interp->framePtr->nsObj)) { - + nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, nsObj, "::", name, NULL); } @@ -9241,12 +9333,12 @@ static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj Jim_Obj *objPtr = interp->emptyObj; if (name[0] == ':' && name[1] == ':') { - + while (*++name == ':') { } } else if (Jim_Length(interp->framePtr->nsObj)) { - + objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, objPtr, "::", name, NULL); name = Jim_String(objPtr); @@ -9259,7 +9351,7 @@ static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ)) #else - + #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME)) #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY) @@ -9278,13 +9370,13 @@ static int JimCreateCommand(Jim_Interp *interp, const char *name, Jim_Cmd *cmd) } if (he && interp->local) { - + cmd->prevCmd = Jim_GetHashEntryVal(he); Jim_SetHashVal(&interp->commands, he, cmd); } else { if (he) { - + Jim_DeleteHashEntry(&interp->commands, name); } @@ -9299,7 +9391,7 @@ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, { Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); - + memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; cmdPtr->u.native.delProc = delProc; @@ -9328,7 +9420,7 @@ static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Ob int subLen; objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i); - + subLen = Jim_ListLength(interp, objPtr); if (subLen == 1 || subLen == 2) { nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0); @@ -9374,7 +9466,7 @@ static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const ch { #ifdef jim_ext_namespace if (cmdPtr->isproc) { - + const char *pt = strrchr(cmdname, ':'); if (pt && pt != cmdname && pt[-1] == ':') { Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); @@ -9382,7 +9474,7 @@ static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const ch Jim_IncrRefCount(cmdPtr->u.proc.nsObj); if (Jim_FindHashEntry(&interp->commands, pt + 1)) { - + Jim_InterpIncrProcEpoch(interp); } } @@ -9399,7 +9491,7 @@ static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr argListLen = Jim_ListLength(interp, argListObjPtr); - + cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen); memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; @@ -9414,20 +9506,20 @@ static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr Jim_IncrRefCount(bodyObjPtr); Jim_IncrRefCount(cmdPtr->u.proc.nsObj); - + if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) { goto err; } - - + + for (i = 0; i < argListLen; i++) { Jim_Obj *argPtr; Jim_Obj *nameObjPtr; Jim_Obj *defaultObjPtr; int len; - + argPtr = Jim_ListGetIndex(interp, argListObjPtr, i); len = Jim_ListLength(interp, argPtr); if (len == 0) { @@ -9442,12 +9534,12 @@ err: } if (len == 2) { - + nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0); defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1); } else { - + nameObjPtr = argPtr; defaultObjPtr = NULL; } @@ -9512,7 +9604,7 @@ int Jim_RenameCommand(Jim_Interp *interp, const char *oldName, const char *newNa fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj); fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj); - + he = Jim_FindHashEntry(&interp->commands, fqold); if (he == NULL) { Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName); @@ -9521,16 +9613,16 @@ int Jim_RenameCommand(Jim_Interp *interp, const char *oldName, const char *newNa Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName); } else { - + cmdPtr = Jim_GetHashEntryVal(he); JimIncrCmdRefCount(cmdPtr); JimUpdateProcNamespace(interp, cmdPtr, fqnew); Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr); - + Jim_DeleteHashEntry(&interp->commands, fqold); - + Jim_InterpIncrProcEpoch(interp); ret = JIM_OK; @@ -9573,9 +9665,9 @@ Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj) #endif ) { - - + + const char *name = Jim_String(objPtr); Jim_HashEntry *he; @@ -9585,7 +9677,7 @@ Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) } #ifdef jim_ext_namespace else if (Jim_Length(interp->framePtr->nsObj)) { - + Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, nameObj, "::", name, NULL); he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj)); @@ -9596,7 +9688,7 @@ Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) } #endif - + he = Jim_FindHashEntry(&interp->commands, name); if (he == NULL) { if (flags & JIM_ERRMSG) { @@ -9609,7 +9701,7 @@ found: #endif cmd = Jim_GetHashEntryVal(he); - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &commandObjType; objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch; @@ -9628,7 +9720,7 @@ found: -#define JIM_DICT_SUGAR 100 +#define JIM_DICT_SUGAR 100 static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); @@ -9642,7 +9734,7 @@ static const Jim_ObjType variableObjType = { static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr) { - + if (nameObjPtr->typePtr != &variableObjType) { int len; const char *str = Jim_GetString(nameObjPtr, &len); @@ -9662,14 +9754,14 @@ static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) int global; int len; - + if (objPtr->typePtr == &variableObjType) { framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr; if (objPtr->internalRep.varValue.callFrameId == framePtr->id) { - + return JIM_OK; } - + } else if (objPtr->typePtr == &dictSubstObjType) { return JIM_DICT_SUGAR; @@ -9681,7 +9773,7 @@ static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) varName = Jim_GetString(objPtr, &len); - + if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) { return JIM_DICT_SUGAR; } @@ -9697,11 +9789,11 @@ static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) framePtr = interp->framePtr; } - + he = Jim_FindHashEntry(&framePtr->vars, varName); if (he == NULL) { if (!global && framePtr->staticVars) { - + he = Jim_FindHashEntry(framePtr->staticVars, varName); } if (he == NULL) { @@ -9709,7 +9801,7 @@ static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) } } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &variableObjType; objPtr->internalRep.varValue.callFrameId = framePtr->id; @@ -9728,7 +9820,7 @@ static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_O Jim_CallFrame *framePtr; int global; - + Jim_Var *var = Jim_Alloc(sizeof(*var)); var->objPtr = valObjPtr; @@ -9747,10 +9839,10 @@ static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_O global = 0; } - + Jim_AddHashEntry(&framePtr->vars, name, var); - + Jim_FreeIntRep(interp, nameObjPtr); nameObjPtr->typePtr = &variableObjType; nameObjPtr->internalRep.varValue.callFrameId = framePtr->id; @@ -9784,7 +9876,7 @@ int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) Jim_DecrRefCount(interp, var->objPtr); var->objPtr = valObjPtr; } - else { + else { Jim_CallFrame *savedCallFrame; savedCallFrame = interp->framePtr; @@ -9845,10 +9937,10 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_CallFrame *framePtr; Jim_Var *varPtr; - + switch (SetVariableFromAny(interp, nameObjPtr)) { case JIM_DICT_SUGAR: - + Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr); return JIM_ERR; @@ -9860,19 +9952,19 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, return JIM_ERR; } - + varPtr->linkFramePtr = NULL; break; } - - + + varName = Jim_String(nameObjPtr); if (varName[0] == ':' && varName[1] == ':') { while (*++varName == ':') { } - + framePtr = interp->topFramePtr; } else { @@ -9896,11 +9988,11 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, return JIM_ERR; } - + if (framePtr == targetCallFrame) { Jim_Obj *objPtr = targetNameObjPtr; - + while (1) { if (strcmp(Jim_String(objPtr), varName) == 0) { Jim_SetResultString(interp, "can't upvar from variable to itself", -1); @@ -9916,9 +10008,9 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, } } - + Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr); - + nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame; Jim_DecrRefCount(interp, targetNameObjPtr); return JIM_OK; @@ -9936,7 +10028,7 @@ Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) else { Jim_Obj *objPtr; - + Jim_CallFrame *savedCallFrame = interp->framePtr; interp->framePtr = varPtr->linkFramePtr; @@ -9945,13 +10037,13 @@ Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) if (objPtr) { return objPtr; } - + } } break; case JIM_DICT_SUGAR: - + return JimDictSugarGet(interp, nameObjPtr, flags); } if (flags & JIM_ERRMSG) { @@ -10005,13 +10097,13 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) retval = SetVariableFromAny(interp, nameObjPtr); if (retval == JIM_DICT_SUGAR) { - + return JimDictSugarSet(interp, nameObjPtr, NULL); } else if (retval == JIM_OK) { varPtr = nameObjPtr->internalRep.varValue.varPtr; - + if (varPtr->linkFramePtr) { framePtr = interp->framePtr; interp->framePtr = varPtr->linkFramePtr; @@ -10030,7 +10122,7 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) retval = Jim_DeleteHashEntry(&framePtr->vars, name); if (retval == JIM_OK) { - + framePtr->id = interp->callFrameEpoch++; } } @@ -10063,7 +10155,7 @@ static void JimDictSugarParseVarKey(Jim_Interp *interp, Jim_Obj *objPtr, keyLen--; } - + keyObjPtr = Jim_NewStringObj(interp, p, keyLen); Jim_IncrRefCount(varObjPtr); @@ -10082,19 +10174,19 @@ static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *valObjP &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST); if (err == JIM_OK) { - + Jim_SetEmptyResult(interp); } else { if (!valObjPtr) { - + if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) { Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", objPtr); return err; } } - + Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", (valObjPtr ? "set" : "unset"), objPtr); } @@ -10120,7 +10212,7 @@ static Jim_Obj *JimDictExpandArrayVariable(Jim_Interp *interp, Jim_Obj *varObjPt ret < 0 ? "variable isn't" : "no such element in"); } else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) { - + Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr)); } @@ -10162,7 +10254,7 @@ static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr) Jim_Obj *varObjPtr, *keyObjPtr; if (objPtr->typePtr == &interpolatedObjType) { - + varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr; keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr; @@ -10207,7 +10299,7 @@ static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr) Jim_Obj *resultObjPtr; if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) { - + resultObjPtr->refCount--; return resultObjPtr; } @@ -10251,7 +10343,7 @@ static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *pare static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) { - + if (localCommands) { Jim_Obj *cmdNameObj; @@ -10270,16 +10362,16 @@ static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) Jim_Cmd *prevCmd = cmd->prevCmd; cmd->prevCmd = NULL; - + JimDecrCmdRefCount(interp, cmd); - + Jim_SetHashVal(ht, he, prevCmd); } else { Jim_DeleteHashEntry(ht, fqname); - Jim_InterpIncrProcEpoch(interp); } + Jim_InterpIncrProcEpoch(interp); } Jim_DecrRefCount(interp, cmdNameObj); JimFreeQualifiedName(interp, fqObjName); @@ -10291,8 +10383,8 @@ static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) } -#define JIM_FCF_FULL 0 -#define JIM_FCF_REUSE 1 +#define JIM_FCF_FULL 0 +#define JIM_FCF_REUSE 1 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action) { JimDeleteLocalProcs(interp, cf->localCommands); @@ -10329,259 +10421,6 @@ static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action) } -#ifdef JIM_REFERENCES - -static void JimReferencesHTValDestructor(void *interp, void *val) -{ - Jim_Reference *refPtr = (void *)val; - - Jim_DecrRefCount(interp, refPtr->objPtr); - if (refPtr->finalizerCmdNamePtr != NULL) { - Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); - } - Jim_Free(val); -} - -static unsigned int JimReferencesHTHashFunction(const void *key) -{ - - const unsigned long *widePtr = key; - unsigned int intValue = (unsigned int)*widePtr; - - return Jim_IntHashFunction(intValue); -} - -static void *JimReferencesHTKeyDup(void *privdata, const void *key) -{ - void *copy = Jim_Alloc(sizeof(unsigned long)); - - JIM_NOTUSED(privdata); - - memcpy(copy, key, sizeof(unsigned long)); - return copy; -} - -static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2) -{ - JIM_NOTUSED(privdata); - - return memcmp(key1, key2, sizeof(unsigned long)) == 0; -} - -static void JimReferencesHTKeyDestructor(void *privdata, void *key) -{ - JIM_NOTUSED(privdata); - - Jim_Free(key); -} - -static const Jim_HashTableType JimReferencesHashTableType = { - JimReferencesHTHashFunction, - JimReferencesHTKeyDup, - NULL, - JimReferencesHTKeyCompare, - JimReferencesHTKeyDestructor, - JimReferencesHTValDestructor -}; - - - -#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN) - -static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id) -{ - const char *fmt = "<reference.<%s>.%020lu>"; - - sprintf(buf, fmt, refPtr->tag, id); - return JIM_REFERENCE_SPACE; -} - -static void UpdateStringOfReference(struct Jim_Obj *objPtr); - -static const Jim_ObjType referenceObjType = { - "reference", - NULL, - NULL, - UpdateStringOfReference, - JIM_TYPE_REFERENCES, -}; - -static void UpdateStringOfReference(struct Jim_Obj *objPtr) -{ - char buf[JIM_REFERENCE_SPACE + 1]; - - JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id); - JimSetStringBytes(objPtr, buf); -} - -static int isrefchar(int c) -{ - return (c == '_' || isalnum(c)); -} - -static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr) -{ - unsigned long value; - int i, len; - const char *str, *start, *end; - char refId[21]; - Jim_Reference *refPtr; - Jim_HashEntry *he; - char *endptr; - - - str = Jim_GetString(objPtr, &len); - - if (len < JIM_REFERENCE_SPACE) - goto badformat; - - start = str; - end = str + len - 1; - while (*start == ' ') - start++; - while (*end == ' ' && end > start) - end--; - if (end - start + 1 != JIM_REFERENCE_SPACE) - goto badformat; - - if (memcmp(start, "<reference.<", 12) != 0) - goto badformat; - if (start[12 + JIM_REFERENCE_TAGLEN] != '>' || end[0] != '>') - goto badformat; - - for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) { - if (!isrefchar(start[12 + i])) - goto badformat; - } - - memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20); - refId[20] = '\0'; - - value = strtoul(refId, &endptr, 10); - if (JimCheckConversion(refId, endptr) != JIM_OK) - goto badformat; - - he = Jim_FindHashEntry(&interp->references, &value); - if (he == NULL) { - Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr); - return JIM_ERR; - } - refPtr = Jim_GetHashEntryVal(he); - - Jim_FreeIntRep(interp, objPtr); - objPtr->typePtr = &referenceObjType; - objPtr->internalRep.refValue.id = value; - objPtr->internalRep.refValue.refPtr = refPtr; - return JIM_OK; - - badformat: - Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr); - return JIM_ERR; -} - -Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr) -{ - struct Jim_Reference *refPtr; - unsigned long id; - Jim_Obj *refObjPtr; - const char *tag; - int tagLen, i; - - - Jim_CollectIfNeeded(interp); - - refPtr = Jim_Alloc(sizeof(*refPtr)); - refPtr->objPtr = objPtr; - Jim_IncrRefCount(objPtr); - refPtr->finalizerCmdNamePtr = cmdNamePtr; - if (cmdNamePtr) - Jim_IncrRefCount(cmdNamePtr); - id = interp->referenceNextId++; - Jim_AddHashEntry(&interp->references, &id, refPtr); - refObjPtr = Jim_NewObj(interp); - refObjPtr->typePtr = &referenceObjType; - refObjPtr->bytes = NULL; - refObjPtr->internalRep.refValue.id = id; - refObjPtr->internalRep.refValue.refPtr = refPtr; - interp->referenceNextId++; - tag = Jim_GetString(tagPtr, &tagLen); - if (tagLen > JIM_REFERENCE_TAGLEN) - tagLen = JIM_REFERENCE_TAGLEN; - for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) { - if (i < tagLen && isrefchar(tag[i])) - refPtr->tag[i] = tag[i]; - else - refPtr->tag[i] = '_'; - } - refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0'; - return refObjPtr; -} - -Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr) -{ - if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR) - return NULL; - return objPtr->internalRep.refValue.refPtr; -} - -int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr) -{ - Jim_Reference *refPtr; - - if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) - return JIM_ERR; - Jim_IncrRefCount(cmdNamePtr); - if (refPtr->finalizerCmdNamePtr) - Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); - refPtr->finalizerCmdNamePtr = cmdNamePtr; - return JIM_OK; -} - -int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr) -{ - Jim_Reference *refPtr; - - if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) - return JIM_ERR; - *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr; - return JIM_OK; -} - - - -static const Jim_HashTableType JimRefMarkHashTableType = { - JimReferencesHTHashFunction, - JimReferencesHTKeyDup, - NULL, - JimReferencesHTKeyCompare, - JimReferencesHTKeyDestructor, - NULL -}; - - -int Jim_Collect(Jim_Interp *interp) -{ - int collected = 0; - return collected; -} - -#define JIM_COLLECT_ID_PERIOD 5000 -#define JIM_COLLECT_TIME_PERIOD 300 - -void Jim_CollectIfNeeded(Jim_Interp *interp) -{ - unsigned long elapsedId; - int elapsedTime; - - elapsedId = interp->referenceNextId - interp->lastCollectId; - elapsedTime = time(NULL) - interp->lastCollectTime; - - - if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) { - Jim_Collect(interp); - } -} -#endif int Jim_IsBigEndian(void) { @@ -10632,7 +10471,7 @@ Jim_Interp *Jim_CreateInterp(void) Jim_IncrRefCount(i->trueObj); Jim_IncrRefCount(i->falseObj); - + Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY); Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0"); @@ -10654,7 +10493,7 @@ void Jim_FreeInterp(Jim_Interp *i) Jim_Obj *objPtr, *nextObjPtr; - + for (cf = i->framePtr; cf; cf = cfx) { cfx = cf->parent; JimFreeCallFrame(i, cf, JIM_FCF_FULL); @@ -10707,7 +10546,7 @@ void Jim_FreeInterp(Jim_Interp *i) } #endif - + objPtr = i->freeList; while (objPtr) { nextObjPtr = objPtr->nextObjPtr; @@ -10715,7 +10554,7 @@ void Jim_FreeInterp(Jim_Interp *i) objPtr = nextObjPtr; } - + for (cf = i->freeFramesList; cf; cf = cfx) { cfx = cf->next; if (cf->vars.table) @@ -10723,7 +10562,7 @@ void Jim_FreeInterp(Jim_Interp *i) Jim_Free(cf); } - + Jim_Free(i); } @@ -10748,13 +10587,13 @@ Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) level = -1; } else { - + level = interp->framePtr->level - level; } } } else { - str = "1"; + str = "1"; level = interp->framePtr->level - 1; } @@ -10762,7 +10601,7 @@ Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) return interp->topFramePtr; } if (level > 0) { - + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { if (framePtr->level == level) { return framePtr; @@ -10781,7 +10620,7 @@ static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *leve if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { if (level <= 0) { - + level = interp->framePtr->level + level; } @@ -10789,7 +10628,7 @@ static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *leve return interp->topFramePtr; } - + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { if (framePtr->level == level) { return framePtr; @@ -10812,7 +10651,7 @@ static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj) { int len; - + Jim_IncrRefCount(stackTraceObj); Jim_DecrRefCount(interp, interp->stackTrace); interp->stackTrace = stackTraceObj; @@ -10833,7 +10672,7 @@ static void JimAppendStackTrace(Jim_Interp *interp, const char *procname, procname = ""; } if (!*procname && !Jim_Length(fileNameObj)) { - + return; } @@ -10843,18 +10682,18 @@ static void JimAppendStackTrace(Jim_Interp *interp, const char *procname, Jim_IncrRefCount(interp->stackTrace); } - + if (!*procname && Jim_Length(fileNameObj)) { - + int len = Jim_ListLength(interp, interp->stackTrace); if (len >= 3) { Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3); if (Jim_Length(objPtr)) { - + objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2); if (Jim_Length(objPtr) == 0) { - + ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0); ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0); return; @@ -10960,14 +10799,14 @@ static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) const char *str; if (objPtr->typePtr == &coercedDoubleObjType) { - + objPtr->typePtr = &intObjType; return JIM_OK; } - + str = Jim_String(objPtr); - + if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) { if (flags & JIM_ERRMSG) { Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr); @@ -10978,7 +10817,7 @@ static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) Jim_SetResultString(interp, "Integer value too big to be represented", -1); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &intObjType; objPtr->internalRep.wideValue = wideValue; @@ -11077,13 +10916,13 @@ static void UpdateStringOfDouble(struct Jim_Obj *objPtr) int i; int len = sprintf(buf, "%.12g", value); - + for (i = 0; i < len; i++) { if (buf[i] == '.' || buf[i] == 'e') { #if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX) char *e = strchr(buf, 'e'); if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') { - + e += 2; memmove(e, e + 1, len - (e - buf)); } @@ -11109,7 +10948,7 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) str = Jim_String(objPtr); #ifdef HAVE_LONG_LONG - + #define MIN_INT_IN_DOUBLE -(1LL << 53) #define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1) @@ -11117,26 +10956,26 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) { - + objPtr->typePtr = &coercedDoubleObjType; return JIM_OK; } else #endif if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &coercedDoubleObjType; objPtr->internalRep.wideValue = wideValue; return JIM_OK; } else { - + if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); } objPtr->typePtr = &doubleObjType; @@ -11173,6 +11012,46 @@ Jim_Obj *Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue) return objPtr; } +static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); + +int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr) +{ + if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) + return JIM_ERR; + *booleanPtr = (int) JimWideValue(objPtr); + return JIM_OK; +} + +static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + static const char * const falses[] = { + "0", "false", "no", "off", NULL + }; + static const char * const trues[] = { + "1", "true", "yes", "on", NULL + }; + + int boolean; + + int index; + if (Jim_GetEnum(interp, objPtr, falses, &index, NULL, 0) == JIM_OK) { + boolean = 0; + } else if (Jim_GetEnum(interp, objPtr, trues, &index, NULL, 0) == JIM_OK) { + boolean = 1; + } else { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr); + } + return JIM_ERR; + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &intObjType; + objPtr->internalRep.wideValue = boolean; + return JIM_OK; +} + static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec); static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr); static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); @@ -11223,7 +11102,7 @@ static unsigned char ListElementQuotingType(const char *s, int len) { int i, level, blevel, trySimple = 1; - + if (len == 0) return JIM_ELESTR_BRACE; if (s[0] == '"' || s[0] == '{') { @@ -11245,7 +11124,7 @@ static unsigned char ListElementQuotingType(const char *s, int len) case '\f': case '\v': trySimple = 0; - + case '{': case '}': goto testbrace; @@ -11254,7 +11133,7 @@ static unsigned char ListElementQuotingType(const char *s, int len) return JIM_ELESTR_SIMPLE; testbrace: - + if (s[len - 1] == '\\') return JIM_ELESTR_QUOTE; level = 0; @@ -11374,7 +11253,7 @@ static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) char *p; unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN]; - + if (objc > STATIC_QUOTING_LEN) { quotingType = Jim_Alloc(objc); } @@ -11393,9 +11272,9 @@ static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) bufLen += len; break; } - + quotingType[i] = JIM_ELESTR_BRACE; - + case JIM_ELESTR_BRACE: bufLen += len + 2; break; @@ -11403,11 +11282,11 @@ static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) bufLen += len * 2; break; } - bufLen++; + bufLen++; } bufLen++; - + p = objPtr->bytes = Jim_Alloc(bufLen + 1); realLength = 0; for (i = 0; i < objc; i++) { @@ -11438,13 +11317,13 @@ static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) realLength += qlen; break; } - + if (i + 1 != objc) { *p++ = ' '; realLength++; } } - *p = '\0'; + *p = '\0'; objPtr->length = realLength; if (quotingType != staticQuoting) { @@ -11479,7 +11358,7 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) Jim_IncrRefCount(listObjPtrPtr[i]); } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &listObjType; objPtr->internalRep.listValue.len = len; @@ -11489,7 +11368,7 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) return JIM_OK; } - + if (objPtr->typePtr == &sourceObjType) { fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; linenr = objPtr->internalRep.sourceValue.lineNumber; @@ -11500,7 +11379,7 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) } Jim_IncrRefCount(fileNameObj); - + str = Jim_GetString(objPtr, &strLen); Jim_FreeIntRep(interp, objPtr); @@ -11509,7 +11388,7 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) objPtr->internalRep.listValue.maxLen = 0; objPtr->internalRep.listValue.ele = NULL; - + if (strLen) { JimParserInit(&parser, str, strLen, linenr); while (!parser.eof) { @@ -11643,7 +11522,7 @@ static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj) jim_wide ret = 0; - + compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command); Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj); Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj); @@ -11665,19 +11544,19 @@ static void ListRemoveDuplicates(Jim_Obj *listObjPtr, int (*comp)(Jim_Obj **lhs, for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) { if (comp(&ele[dst], &ele[src]) == 0) { - + Jim_DecrRefCount(sort_info->interp, ele[dst]); } else { - + dst++; } ele[dst] = ele[src]; } - + ele[++dst] = ele[src]; - + listObjPtr->internalRep.listValue.len = dst; } @@ -11695,7 +11574,7 @@ static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsor JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object")); SetListFromAny(interp, listObjPtr); - + prev_info = sort_info; sort_info = info; @@ -11718,13 +11597,13 @@ static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsor fn = ListSortCommand; break; default: - fn = NULL; + fn = NULL; JimPanic((1, "ListSort called with invalid sort type")); - return -1; + return -1; } if (info->indexed) { - + info->subfn = fn; fn = ListSortIndexHelper; } @@ -11752,7 +11631,7 @@ static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *co if (requiredLen > listPtr->internalRep.listValue.maxLen) { if (requiredLen < 2) { - + requiredLen = 4; } else { @@ -11938,30 +11817,30 @@ Jim_Obj *Jim_ConcatObj(Jim_Interp *interp, int objc, Jim_Obj *const *objv) return objPtr; } else { - + int len = 0, objLen; char *bytes, *p; - + for (i = 0; i < objc; i++) { len += Jim_Length(objv[i]); } if (objc) len += objc - 1; - + p = bytes = Jim_Alloc(len + 1); for (i = 0; i < objc; i++) { const char *s = Jim_GetString(objv[i], &objLen); - + while (objLen && isspace(UCHAR(*s))) { s++; objLen--; len--; } - + while (objLen && isspace(UCHAR(s[objLen - 1]))) { - + if (objLen > 1 && s[objLen - 2] == '\\') { break; } @@ -11992,7 +11871,7 @@ Jim_Obj *Jim_ListRange(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *firstOb if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK || Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK) return NULL; - len = Jim_ListLength(interp, listObjPtr); + len = Jim_ListLength(interp, listObjPtr); first = JimRelToAbsIndex(len, first); last = JimRelToAbsIndex(len, last); JimRelToAbsRange(len, &first, &last, &rangeLen); @@ -12032,12 +11911,12 @@ static void JimObjectHTKeyValDestructor(void *interp, void *val) } static const Jim_HashTableType JimDictHashTableType = { - JimObjectHTHashFunction, - JimObjectHTKeyValDup, - JimObjectHTKeyValDup, - JimObjectHTKeyCompare, - JimObjectHTKeyValDestructor, - JimObjectHTKeyValDestructor + JimObjectHTHashFunction, + JimObjectHTKeyValDup, + JimObjectHTKeyValDup, + JimObjectHTKeyCompare, + JimObjectHTKeyValDestructor, + JimObjectHTKeyValDestructor }; static const Jim_ObjType dictObjType = { @@ -12062,13 +11941,13 @@ void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) Jim_HashTableIterator htiter; Jim_HashEntry *he; - + ht = srcPtr->internalRep.ptr; dupHt = Jim_Alloc(sizeof(*dupHt)); Jim_InitHashTable(dupHt, &JimDictHashTableType, interp); if (ht->size != 0) Jim_ExpandHashTable(dupHt, ht->size); - + JimInitHashTableIterator(ht, &htiter); while ((he = Jim_NextHashEntry(&htiter)) != NULL) { Jim_AddHashEntry(dupHt, he->key, he->u.val); @@ -12088,7 +11967,7 @@ static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len) ht = dictPtr->internalRep.ptr; - + objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *)); JimInitHashTableIterator(ht, &htiter); i = 0; @@ -12102,11 +11981,11 @@ static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len) static void UpdateStringOfDict(struct Jim_Obj *objPtr) { - + int len; Jim_Obj **objv = JimDictPairs(objPtr, &len); - + JimMakeListStringRep(objPtr, objv, len); Jim_Free(objv); @@ -12124,14 +12003,14 @@ static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) Jim_String(objPtr); } - + listlen = Jim_ListLength(interp, objPtr); if (listlen % 2) { Jim_SetResultString(interp, "missing value to go with key", -1); return JIM_ERR; } else { - + Jim_HashTable *ht; int i; @@ -12160,7 +12039,7 @@ static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, { Jim_HashTable *ht = objPtr->internalRep.ptr; - if (valueObjPtr == NULL) { + if (valueObjPtr == NULL) { return Jim_DeleteHashEntry(ht, keyObjPtr); } Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr); @@ -12211,8 +12090,10 @@ int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr, } return JIM_ERR; } - *objPtrPtr = he->u.val; - return JIM_OK; + else { + *objPtrPtr = Jim_GetHashEntryVal(he); + return JIM_OK; + } } @@ -12260,7 +12141,7 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags); if (objPtr == NULL) { if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) { - + return JIM_ERR; } varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0); @@ -12274,13 +12155,13 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, for (i = 0; i < keyc; i++) { dictObjPtr = objPtr; - + if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) { goto err; } if (i == keyc - 1) { - + if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) { if (newObjPtr || (flags & JIM_MUSTEXIST)) { goto err; @@ -12289,7 +12170,7 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, break; } - + Jim_InvalidateStringRep(dictObjPtr); if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr, newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) { @@ -12306,7 +12187,7 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, DictAddElement(interp, dictObjPtr, keyv[i], objPtr); } } - + Jim_InvalidateStringRep(objPtr); Jim_InvalidateStringRep(varObjPtr); if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) { @@ -12343,7 +12224,7 @@ static void UpdateStringOfIndex(struct Jim_Obj *objPtr) sprintf(buf, "%d", objPtr->internalRep.intValue); } else { - + sprintf(buf, "end%d", objPtr->internalRep.intValue + 1); } JimSetStringBytes(objPtr, buf); @@ -12356,10 +12237,10 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) const char *str; char *endptr; - + str = Jim_String(objPtr); - + if (strncmp(str, "end", 3) == 0) { end = 1; str += 3; @@ -12374,7 +12255,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) str = endptr; } - + if (*str == '+' || *str == '-') { int sign = (*str == '+' ? 1 : -1); @@ -12384,7 +12265,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) } str = endptr; } - + while (isspace(UCHAR(*str))) { str++; } @@ -12396,7 +12277,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) idx = INT_MAX; } else { - + idx--; } } @@ -12404,7 +12285,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) idx = -INT_MAX; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &indexObjType; objPtr->internalRep.intValue = idx; @@ -12418,7 +12299,7 @@ static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr) { - + if (objPtr->typePtr == &intObjType) { jim_wide val = JimWideValue(objPtr); @@ -12475,14 +12356,14 @@ static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr) int returnCode; jim_wide wideValue; - + if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR) returnCode = (int)wideValue; else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) { Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &returnCodeObjType; objPtr->internalRep.intValue = returnCode; @@ -12500,15 +12381,16 @@ int Jim_GetReturnCode(Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr) static int JimParseExprOperator(struct JimParserCtx *pc); static int JimParseExprNumber(struct JimParserCtx *pc); static int JimParseExprIrrational(struct JimParserCtx *pc); +static int JimParseExprBoolean(struct JimParserCtx *pc); enum { - - - JIM_EXPROP_MUL = JIM_TT_EXPR_OP, + + + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, JIM_EXPROP_DIV, JIM_EXPROP_MOD, JIM_EXPROP_SUB, @@ -12523,47 +12405,47 @@ enum JIM_EXPROP_GTE, JIM_EXPROP_NUMEQ, JIM_EXPROP_NUMNE, - JIM_EXPROP_BITAND, + JIM_EXPROP_BITAND, JIM_EXPROP_BITXOR, JIM_EXPROP_BITOR, - - JIM_EXPROP_LOGICAND, + + JIM_EXPROP_LOGICAND, JIM_EXPROP_LOGICAND_LEFT, JIM_EXPROP_LOGICAND_RIGHT, - - JIM_EXPROP_LOGICOR, + + JIM_EXPROP_LOGICOR, JIM_EXPROP_LOGICOR_LEFT, JIM_EXPROP_LOGICOR_RIGHT, - - - JIM_EXPROP_TERNARY, + + + JIM_EXPROP_TERNARY, JIM_EXPROP_TERNARY_LEFT, JIM_EXPROP_TERNARY_RIGHT, - - JIM_EXPROP_COLON, + + JIM_EXPROP_COLON, JIM_EXPROP_COLON_LEFT, JIM_EXPROP_COLON_RIGHT, - JIM_EXPROP_POW, + JIM_EXPROP_POW, - JIM_EXPROP_STREQ, + JIM_EXPROP_STREQ, JIM_EXPROP_STRNE, JIM_EXPROP_STRIN, JIM_EXPROP_STRNI, - JIM_EXPROP_NOT, + JIM_EXPROP_NOT, JIM_EXPROP_BITNOT, JIM_EXPROP_UNARYMINUS, JIM_EXPROP_UNARYPLUS, - - JIM_EXPROP_FUNC_FIRST, + + JIM_EXPROP_FUNC_FIRST, JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, JIM_EXPROP_FUNC_WIDE, JIM_EXPROP_FUNC_ABS, @@ -12572,13 +12454,14 @@ enum JIM_EXPROP_FUNC_RAND, JIM_EXPROP_FUNC_SRAND, - - JIM_EXPROP_FUNC_SIN, + + JIM_EXPROP_FUNC_SIN, JIM_EXPROP_FUNC_COS, JIM_EXPROP_FUNC_TAN, JIM_EXPROP_FUNC_ASIN, JIM_EXPROP_FUNC_ACOS, JIM_EXPROP_FUNC_ATAN, + JIM_EXPROP_FUNC_ATAN2, JIM_EXPROP_FUNC_SINH, JIM_EXPROP_FUNC_COSH, JIM_EXPROP_FUNC_TANH, @@ -12589,6 +12472,8 @@ enum JIM_EXPROP_FUNC_LOG10, JIM_EXPROP_FUNC_SQRT, JIM_EXPROP_FUNC_POW, + JIM_EXPROP_FUNC_HYPOT, + JIM_EXPROP_FUNC_FMOD, }; struct JimExprState @@ -12669,7 +12554,11 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) intresult = 0; break; case JIM_EXPROP_FUNC_ABS: +#ifdef JIM_MATH_FUNCTIONS + dC = fabs(dA); +#else dC = dA >= 0 ? dA : -dA; +#endif intresult = 0; break; case JIM_EXPROP_UNARYMINUS: @@ -12861,12 +12750,12 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) break; case JIM_EXPROP_ROTL: case JIM_EXPROP_ROTR:{ - + unsigned long uA = (unsigned long)wA; unsigned long uB = (unsigned long)wB; const unsigned int S = sizeof(unsigned long) * 8; - + uB %= S; if (e->opcode == JIM_EXPROP_ROTR) { @@ -12892,7 +12781,6 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) { - int intresult = 1; int rc = JIM_OK; double dA, dB, dC = 0; jim_wide wA, wB, wC = 0; @@ -12904,26 +12792,32 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) (B->typePtr != &doubleObjType || B->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) { - + switch (e->opcode) { case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: + if (wA == 0 && wB < 0) { + Jim_SetResultString(interp, "exponentiation of zero by negative power", -1); + rc = JIM_ERR; + goto done; + } wC = JimPowWide(wA, wB); - break; + goto intresult; case JIM_EXPROP_ADD: wC = wA + wB; - break; + goto intresult; case JIM_EXPROP_SUB: wC = wA - wB; - break; + goto intresult; case JIM_EXPROP_MUL: wC = wA * wB; - break; + goto intresult; case JIM_EXPROP_DIV: if (wB == 0) { Jim_SetResultString(interp, "Division by zero", -1); rc = JIM_ERR; + goto done; } else { if (wB < 0) { @@ -12934,51 +12828,63 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) if (wA % wB < 0) { wC--; } + goto intresult; } - break; case JIM_EXPROP_LT: wC = wA < wB; - break; + goto intresult; case JIM_EXPROP_GT: wC = wA > wB; - break; + goto intresult; case JIM_EXPROP_LTE: wC = wA <= wB; - break; + goto intresult; case JIM_EXPROP_GTE: wC = wA >= wB; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = wA == wB; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = wA != wB; - break; - default: - abort(); + goto intresult; } } - else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { - intresult = 0; + if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { switch (e->opcode) { +#ifndef JIM_MATH_FUNCTIONS case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: -#ifdef JIM_MATH_FUNCTIONS - dC = pow(dA, dB); -#else + case JIM_EXPROP_FUNC_ATAN2: + case JIM_EXPROP_FUNC_HYPOT: + case JIM_EXPROP_FUNC_FMOD: Jim_SetResultString(interp, "unsupported", -1); rc = JIM_ERR; + goto done; +#else + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + dC = pow(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_ATAN2: + dC = atan2(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_HYPOT: + dC = hypot(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_FMOD: + dC = fmod(dA, dB); + goto doubleresult; #endif - break; case JIM_EXPROP_ADD: dC = dA + dB; - break; + goto doubleresult; case JIM_EXPROP_SUB: dC = dA - dB; - break; + goto doubleresult; case JIM_EXPROP_MUL: dC = dA * dB; - break; + goto doubleresult; case JIM_EXPROP_DIV: if (dB == 0) { #ifdef INFINITY @@ -12990,79 +12896,66 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) else { dC = dA / dB; } - break; + goto doubleresult; case JIM_EXPROP_LT: wC = dA < dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_GT: wC = dA > dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_LTE: wC = dA <= dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_GTE: wC = dA >= dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = dA == dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = dA != dB; - intresult = 1; - break; - default: - abort(); + goto intresult; } } else { - - + + int i = Jim_StringCompareObj(interp, A, B, 0); switch (e->opcode) { case JIM_EXPROP_LT: wC = i < 0; - break; + goto intresult; case JIM_EXPROP_GT: wC = i > 0; - break; + goto intresult; case JIM_EXPROP_LTE: wC = i <= 0; - break; + goto intresult; case JIM_EXPROP_GTE: wC = i >= 0; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = i == 0; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = i != 0; - break; - default: - rc = JIM_ERR; - break; - } - } - - if (rc == JIM_OK) { - if (intresult) { - ExprPush(e, Jim_NewIntObj(interp, wC)); - } - else { - ExprPush(e, Jim_NewDoubleObj(interp, dC)); + goto intresult; } } + rc = JIM_ERR; +done: Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); - return rc; +intresult: + ExprPush(e, Jim_NewIntObj(interp, wC)); + goto done; +doubleresult: + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + goto done; } static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) @@ -13115,6 +13008,7 @@ static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) { long l; double d; + int b; if (Jim_GetLong(interp, obj, &l) == JIM_OK) { return l != 0; @@ -13122,6 +13016,9 @@ static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { return d != 0; } + if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) { + return b != 0; + } return -1; } @@ -13133,17 +13030,17 @@ static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e) switch (ExprBool(interp, A)) { case 0: - + e->skip = JimWideValue(skip); ExprPush(e, Jim_NewIntObj(interp, 0)); break; case 1: - + break; case -1: - + rc = JIM_ERR; } Jim_DecrRefCount(interp, A); @@ -13160,17 +13057,17 @@ static int JimExprOpOrLeft(Jim_Interp *interp, struct JimExprState *e) switch (ExprBool(interp, A)) { case 0: - + break; case 1: - + e->skip = JimWideValue(skip); ExprPush(e, Jim_NewIntObj(interp, 1)); break; case -1: - + rc = JIM_ERR; break; } @@ -13195,7 +13092,7 @@ static int JimExprOpAndOrRight(Jim_Interp *interp, struct JimExprState *e) break; case -1: - + rc = JIM_ERR; break; } @@ -13210,23 +13107,23 @@ static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) Jim_Obj *A = ExprPop(e); int rc = JIM_OK; - + ExprPush(e, A); switch (ExprBool(interp, A)) { case 0: - + e->skip = JimWideValue(skip); - + ExprPush(e, Jim_NewIntObj(interp, 0)); break; case 1: - + break; case -1: - + rc = JIM_ERR; break; } @@ -13242,11 +13139,11 @@ static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e) Jim_Obj *B = ExprPop(e); Jim_Obj *A = ExprPop(e); - + if (ExprBool(interp, A)) { - + e->skip = JimWideValue(skip); - + ExprPush(e, B); } @@ -13266,11 +13163,12 @@ enum LAZY_NONE, LAZY_OP, LAZY_LEFT, - LAZY_RIGHT + LAZY_RIGHT, + RIGHT_ASSOC, }; -#define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1} -#define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1} +#define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1} +#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, LAZY_NONE) static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("*", 110, 2, JimExprOpBin), @@ -13298,23 +13196,24 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("^", 49, 2, JimExprOpIntBin), OPRINIT("|", 48, 2, JimExprOpIntBin), - OPRINIT_LAZY("&&", 10, 2, NULL, LAZY_OP), - OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT), - OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT), + OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP), + OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT), + OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT), + + OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP), + OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT), + OPRINIT_ATTR(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT), - OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP), - OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT), - OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT), + OPRINIT_ATTR("?", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT_ATTR(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT), + OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), - OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP), - OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT), - OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), + OPRINIT_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT), + OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), - OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP), - OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT), - OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), - OPRINIT("**", 250, 2, JimExprOpBin), + OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC), OPRINIT("eq", 60, 2, JimExprOpStrBin), OPRINIT("ne", 60, 2, JimExprOpStrBin), @@ -13344,6 +13243,7 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("asin", 200, 1, JimExprOpDoubleUnary), OPRINIT("acos", 200, 1, JimExprOpDoubleUnary), OPRINIT("atan", 200, 1, JimExprOpDoubleUnary), + OPRINIT("atan2", 200, 2, JimExprOpBin), OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary), OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary), OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary), @@ -13354,6 +13254,8 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("log10", 200, 1, JimExprOpDoubleUnary), OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary), OPRINIT("pow", 200, 2, JimExprOpBin), + OPRINIT("hypot", 200, 2, JimExprOpBin), + OPRINIT("fmod", 200, 2, JimExprOpBin), #endif }; #undef OPRINIT @@ -13364,7 +13266,7 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { static int JimParseExpression(struct JimParserCtx *pc) { - + while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { if (*pc->p == '\n') { pc->linenr++; @@ -13373,7 +13275,7 @@ static int JimParseExpression(struct JimParserCtx *pc) pc->len--; } - + pc->tline = pc->linenr; pc->tstart = pc->p; @@ -13403,7 +13305,7 @@ singlechar: if (JimParseVar(pc) == JIM_ERR) return JimParseExprOperator(pc); else { - + if (pc->tt == JIM_TT_EXPRSUGAR) { return JIM_ERR; } @@ -13432,6 +13334,14 @@ singlechar: case 'n': case 'i': if (JimParseExprIrrational(pc) == JIM_ERR) + if (JimParseExprBoolean(pc) == JIM_ERR) + return JimParseExprOperator(pc); + break; + case 't': + case 'f': + case 'o': + case 'y': + if (JimParseExprBoolean(pc) == JIM_ERR) return JimParseExprOperator(pc); break; default: @@ -13445,17 +13355,17 @@ static int JimParseExprNumber(struct JimParserCtx *pc) { char *end; - + pc->tt = JIM_TT_EXPR_INT; jim_strtoull(pc->p, (char **)&pc->p); - + if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) { - if (strtod(pc->tstart, &end)) { } + if (strtod(pc->tstart, &end)) { } if (end == pc->tstart) return JIM_ERR; if (end > pc->p) { - + pc->tt = JIM_TT_EXPR_DOUBLE; pc->p = end; } @@ -13484,12 +13394,33 @@ static int JimParseExprIrrational(struct JimParserCtx *pc) return JIM_ERR; } +static int JimParseExprBoolean(struct JimParserCtx *pc) +{ + const char *booleans[] = { "false", "no", "off", "true", "yes", "on", NULL }; + const int lengths[] = { 5, 2, 3, 4, 3, 2, 0 }; + int i; + + for (i = 0; booleans[i]; i++) { + const char *boolean = booleans[i]; + int length = lengths[i]; + + if (strncmp(boolean, pc->p, length) == 0) { + pc->p += length; + pc->len -= length; + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EXPR_BOOLEAN; + return JIM_OK; + } + } + return JIM_ERR; +} + static int JimParseExprOperator(struct JimParserCtx *pc) { int i; int bestIdx = -1, bestLen = 0; - + for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) { const char * const opname = Jim_ExprOperators[i].name; const int oplen = Jim_ExprOperators[i].namelen; @@ -13507,7 +13438,7 @@ static int JimParseExprOperator(struct JimParserCtx *pc) return JIM_ERR; } - + if (bestIdx >= JIM_EXPROP_FUNC_FIRST) { const char *p = pc->p + bestLen; int len = pc->len - bestLen; @@ -13541,10 +13472,16 @@ const char *jim_tt_name(int type) { static const char * const tt_names[JIM_TT_EXPR_OP] = { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT", - "DBL", "$()" }; + "DBL", "BOO", "$()" }; if (type < JIM_TT_EXPR_OP) { return tt_names[type]; } + else if (type == JIM_EXPROP_UNARYMINUS) { + return "-VE"; + } + else if (type == JIM_EXPROP_UNARYPLUS) { + return "+VE"; + } else { const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type); static char buf[20]; @@ -13572,9 +13509,9 @@ static const Jim_ObjType exprObjType = { typedef struct ExprByteCode { - ScriptToken *token; - int len; - int inUse; + ScriptToken *token; + int len; + int inUse; } ExprByteCode; static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr) @@ -13606,22 +13543,25 @@ static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dup JIM_NOTUSED(interp); JIM_NOTUSED(srcPtr); - + dupPtr->typePtr = NULL; } - -static int ExprCheckCorrectness(ExprByteCode * expr) +static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr) { int i; int stacklen = 0; int ternary = 0; + int lasttt = JIM_TT_NONE; + const char *errmsg; for (i = 0; i < expr->len; i++) { ScriptToken *t = &expr->token[i]; const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + lasttt = t->type; stacklen -= op->arity; + if (stacklen < 0) { break; } @@ -13632,13 +13572,34 @@ static int ExprCheckCorrectness(ExprByteCode * expr) ternary--; } - + stacklen++; } - if (stacklen != 1 || ternary != 0) { - return JIM_ERR; + if (stacklen == 1 && ternary == 0) { + return JIM_OK; } - return JIM_OK; + + if (stacklen <= 0) { + + if (lasttt >= JIM_EXPROP_FUNC_FIRST) { + errmsg = "too few arguments for math function"; + Jim_SetResultString(interp, "too few arguments for math function", -1); + } else { + errmsg = "premature end of expression"; + } + } + else if (stacklen > 1) { + if (lasttt >= JIM_EXPROP_FUNC_FIRST) { + errmsg = "too many arguments for math function"; + } else { + errmsg = "extra tokens at end of expression"; + } + } + else { + errmsg = "invalid ternary expression"; + } + Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg); + return JIM_ERR; } static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) @@ -13647,7 +13608,7 @@ static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseTok int leftindex, arity, offset; - + leftindex = expr->len - 1; arity = 1; @@ -13664,7 +13625,7 @@ static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseTok } leftindex++; - + memmove(&expr->token[leftindex + 2], &expr->token[leftindex], sizeof(*expr->token) * (expr->len - leftindex)); expr->len += 2; @@ -13676,12 +13637,12 @@ static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseTok expr->token[leftindex].type = JIM_TT_EXPR_INT; expr->token[leftindex].objPtr = Jim_NewIntObj(interp, offset); - + expr->token[expr->len].objPtr = interp->emptyObj; expr->token[expr->len].type = t->type + 2; expr->len++; - + for (i = leftindex - 1; i > 0; i--) { const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(expr->token[i].type); if (op->lazy == LAZY_LEFT) { @@ -13731,7 +13692,7 @@ static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index) right_index--; } - + return -1; } @@ -13773,7 +13734,7 @@ static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr) continue; } - + if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) { continue; } @@ -13786,12 +13747,12 @@ static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr) JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index); - + i++; } } -static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *fileNameObj) +static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj) { Jim_Stack stack; ExprByteCode *expr; @@ -13800,7 +13761,7 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList int prevtt = JIM_TT_NONE; int have_ternary = 0; - + int count = tokenlist->count - 1; expr = Jim_Alloc(sizeof(*expr)); @@ -13815,7 +13776,7 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList if (op->lazy == LAZY_OP) { count += 2; - + if (t->type == JIM_EXPROP_TERNARY) { have_ternary = 1; } @@ -13827,124 +13788,124 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList for (i = 0; i < tokenlist->count && ok; i++) { ParseToken *t = &tokenlist->list[i]; - + struct ScriptToken *token = &expr->token[expr->len]; if (t->type == JIM_TT_EOL) { break; } - switch (t->type) { - case JIM_TT_STR: - case JIM_TT_ESC: - case JIM_TT_VAR: - case JIM_TT_DICTSUGAR: - case JIM_TT_EXPRSUGAR: - case JIM_TT_CMD: - token->type = t->type; -strexpr: - token->objPtr = Jim_NewStringObj(interp, t->token, t->len); - if (t->type == JIM_TT_CMD) { - - JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); - } - expr->len++; - break; + if (TOKEN_IS_EXPR_OP(t->type)) { + const struct Jim_ExprOperator *op; + ParseToken *tt; - case JIM_TT_EXPR_INT: - case JIM_TT_EXPR_DOUBLE: - { - char *endptr; - if (t->type == JIM_TT_EXPR_INT) { - token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); - } - else { - token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); - } - if (endptr != t->token + t->len) { - - Jim_FreeNewObj(interp, token->objPtr); - token->type = JIM_TT_STR; - goto strexpr; - } - token->type = t->type; - expr->len++; + + if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) { + if (t->type == JIM_EXPROP_SUB) { + t->type = JIM_EXPROP_UNARYMINUS; } - break; + else if (t->type == JIM_EXPROP_ADD) { + t->type = JIM_EXPROP_UNARYPLUS; + } + } - case JIM_TT_SUBEXPR_START: - Jim_StackPush(&stack, t); - prevtt = JIM_TT_NONE; - continue; + op = JimExprOperatorInfoByOpcode(t->type); - case JIM_TT_SUBEXPR_COMMA: - - continue; - case JIM_TT_SUBEXPR_END: - ok = 0; - while (Jim_StackLen(&stack)) { - ParseToken *tt = Jim_StackPop(&stack); + while ((tt = Jim_StackPeek(&stack)) != NULL) { + const struct Jim_ExprOperator *tt_op = + JimExprOperatorInfoByOpcode(tt->type); - if (tt->type == JIM_TT_SUBEXPR_START) { - ok = 1; + + if (op->arity != 1 && tt_op->precedence >= op->precedence) { + + if (tt_op->precedence == op->precedence && tt_op->lazy == RIGHT_ASSOC) { break; } - if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; goto err; } + Jim_StackPop(&stack); } - if (!ok) { - Jim_SetResultString(interp, "Unexpected close parenthesis", -1); - goto err; + else { + break; } - break; + } + Jim_StackPush(&stack, t); + } + else if (t->type == JIM_TT_SUBEXPR_START) { + Jim_StackPush(&stack, t); + } + else if (t->type == JIM_TT_SUBEXPR_END || t->type == JIM_TT_SUBEXPR_COMMA) { + ok = 0; + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); - default:{ - - const struct Jim_ExprOperator *op; - ParseToken *tt; - - - if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) { - if (t->type == JIM_EXPROP_SUB) { - t->type = JIM_EXPROP_UNARYMINUS; - } - else if (t->type == JIM_EXPROP_ADD) { - t->type = JIM_EXPROP_UNARYPLUS; - } + if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) { + if (t->type == JIM_TT_SUBEXPR_COMMA) { + + Jim_StackPush(&stack, tt); } + ok = 1; + break; + } + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + goto err; + } + } + if (!ok) { + Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr); + goto err; + } + } + else { + Jim_Obj *objPtr = NULL; - op = JimExprOperatorInfoByOpcode(t->type); - - while ((tt = Jim_StackPeek(&stack)) != NULL) { - const struct Jim_ExprOperator *tt_op = - JimExprOperatorInfoByOpcode(tt->type); + token->type = t->type; - - if (op->arity != 1 && tt_op->precedence >= op->precedence) { - if (ExprAddOperator(interp, expr, tt) != JIM_OK) { - ok = 0; - goto err; - } - Jim_StackPop(&stack); - } - else { - break; - } - } - Jim_StackPush(&stack, t); - break; + if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) { + Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr); + ok = 0; + goto err; + } + + + if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) { + char *endptr; + if (t->type == JIM_TT_EXPR_INT) { + objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); } + else { + objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); + } + if (endptr != t->token + t->len) { + + Jim_FreeNewObj(interp, objPtr); + objPtr = NULL; + } + } + + if (objPtr) { + token->objPtr = objPtr; + } + else { + + token->objPtr = Jim_NewStringObj(interp, t->token, t->len); + if (t->type == JIM_TT_CMD) { + + JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); + } + } + expr->len++; } prevtt = t->type; } - + while (Jim_StackLen(&stack)) { ParseToken *tt = Jim_StackPop(&stack); @@ -13964,7 +13925,7 @@ strexpr: } err: - + Jim_FreeStack(&stack); for (i = 0; i < expr->len; i++) { @@ -13991,7 +13952,7 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) Jim_Obj *fileNameObj; int rc = JIM_ERR; - + if (objPtr->typePtr == &sourceObjType) { fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; line = objPtr->internalRep.sourceValue.lineNumber; @@ -14004,14 +13965,13 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) exprText = Jim_GetString(objPtr, &exprTextLen); - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, exprText, exprTextLen, line); while (!parser.eof) { if (JimParseExpression(&parser) != JIM_OK) { ScriptTokenListFree(&tokenlist); - invalidexpr: Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); expr = NULL; goto err; @@ -14038,10 +13998,10 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) return JIM_ERR; } - - expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj); - + expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj); + + ScriptTokenListFree(&tokenlist); if (!expr) { @@ -14061,16 +14021,18 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) } #endif - - if (ExprCheckCorrectness(expr) != JIM_OK) { + + if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) { + ExprFreeByteCode(interp, expr); - goto invalidexpr; + expr = NULL; + goto err; } rc = JIM_OK; err: - + Jim_DecrRefCount(interp, fileNameObj); Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, expr); @@ -14114,7 +14076,7 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe expr = JimGetExpression(interp, exprObjPtr); if (!expr) { - return JIM_ERR; + return JIM_ERR; } #ifdef JIM_OPTIMIZATION @@ -14187,7 +14149,7 @@ noopt: expr->inUse++; - + if (expr->len > JIM_EE_STATICSTACK_LEN) e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len); @@ -14196,13 +14158,14 @@ noopt: e.stacklen = 0; - + for (i = 0; i < expr->len && retcode == JIM_OK; i++) { Jim_Obj *objPtr; switch (expr->token[i].type) { case JIM_TT_EXPR_INT: case JIM_TT_EXPR_DOUBLE: + case JIM_TT_EXPR_BOOLEAN: case JIM_TT_STR: ExprPush(&e, expr->token[i].objPtr); break; @@ -14242,12 +14205,12 @@ noopt: break; default:{ - + e.skip = 0; e.opcode = expr->token[i].type; retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e); - + i += e.skip; continue; } @@ -14275,6 +14238,7 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) int retcode; jim_wide wideValue; double doubleValue; + int booleanValue; Jim_Obj *exprResultPtr; retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr); @@ -14283,8 +14247,14 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) { if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) { - Jim_DecrRefCount(interp, exprResultPtr); - return JIM_ERR; + if (Jim_GetBoolean(interp, exprResultPtr, &booleanValue) != JIM_OK) { + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_ERR; + } else { + Jim_DecrRefCount(interp, exprResultPtr); + *boolPtr = booleanValue; + return JIM_OK; + } } else { Jim_DecrRefCount(interp, exprResultPtr); @@ -14303,25 +14273,25 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) typedef struct ScanFmtPartDescr { - char *arg; - char *prefix; - size_t width; - int pos; - char type; - char modifier; + char *arg; + char *prefix; + size_t width; + int pos; + char type; + char modifier; } ScanFmtPartDescr; typedef struct ScanFmtStringObj { - jim_wide size; - char *stringRep; - size_t count; - size_t convCount; - size_t maxPos; - const char *error; - char *scratch; - ScanFmtPartDescr descr[1]; + jim_wide size; + char *stringRep; + size_t count; + size_t convCount; + size_t maxPos; + const char *error; + char *scratch; + ScanFmtPartDescr descr[1]; } ScanFmtStringObj; @@ -14372,18 +14342,18 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) int curr; Jim_FreeIntRep(interp, objPtr); - + for (i = 0, maxCount = 0; i < maxFmtLen; ++i) if (fmt[i] == '%') ++maxCount; - - approxSize = sizeof(ScanFmtStringObj) - +(maxCount + 1) * sizeof(ScanFmtPartDescr) - +maxFmtLen * sizeof(char) + 3 + 1 - + maxFmtLen * sizeof(char) + 1 - + maxFmtLen * sizeof(char) - +(maxCount + 1) * sizeof(char) - +1; + + approxSize = sizeof(ScanFmtStringObj) + +(maxCount + 1) * sizeof(ScanFmtPartDescr) + +maxFmtLen * sizeof(char) + 3 + 1 + + maxFmtLen * sizeof(char) + 1 + + maxFmtLen * sizeof(char) + +(maxCount + 1) * sizeof(char) + +1; fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize); memset(fmtObj, 0, approxSize); fmtObj->size = approxSize; @@ -14399,8 +14369,8 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) ScanFmtPartDescr *descr = &fmtObj->descr[curr]; fmtObj->count++; - descr->width = 0; - + descr->width = 0; + if (*fmt != '%' || fmt[1] == '%') { descr->type = 0; descr->prefix = &buffer[i]; @@ -14414,35 +14384,35 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) } buffer[i++] = 0; } - + ++fmt; - + if (fmt >= fmtEnd) goto done; - descr->pos = 0; + descr->pos = 0; if (*fmt == '*') { - descr->pos = -1; + descr->pos = -1; ++fmt; } else - fmtObj->convCount++; - + fmtObj->convCount++; + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { fmt += skip; - + if (descr->pos != -1 && *fmt == '$') { int prev; ++fmt; descr->pos = width; width = 0; - + if ((lastPos == 0 && descr->pos > 0) || (lastPos > 0 && descr->pos == 0)) { fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers"; return JIM_ERR; } - + for (prev = 0; prev < curr; ++prev) { if (fmtObj->descr[prev].pos == -1) continue; @@ -14452,7 +14422,7 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) return JIM_ERR; } } - + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { descr->width = width; fmt += skip; @@ -14461,14 +14431,14 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) fmtObj->maxPos = descr->pos; } else { - + descr->width = width; } } - + if (lastPos == -1) lastPos = descr->pos; - + if (*fmt == '[') { int swapped = 1, beg = i, end, j; @@ -14487,7 +14457,7 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) } end = i; buffer[i++] = 0; - + while (swapped) { swapped = 0; for (j = beg + 1; j < end - 1; ++j) { @@ -14502,7 +14472,7 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) } } else { - + if (strchr("hlL", *fmt) != 0) descr->modifier = tolower((int)*fmt++); @@ -14545,7 +14515,7 @@ static Jim_Obj *JimScanAString(Jim_Interp *interp, const char *sdescr, const cha int n; if (!sdescr && isspace(UCHAR(*str))) - break; + break; n = utf8_tounicode(str, &c); if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN)) @@ -14568,39 +14538,39 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen int i; Jim_Obj *tmpObj = NULL; - + *valObjPtr = 0; if (descr->prefix) { for (i = 0; pos < strLen && descr->prefix[i]; ++i) { - + if (isspace(UCHAR(descr->prefix[i]))) while (pos < strLen && isspace(UCHAR(str[pos]))) ++pos; else if (descr->prefix[i] != str[pos]) - break; + break; else - ++pos; + ++pos; } if (pos >= strLen) { - return -1; + return -1; } else if (descr->prefix[i] != 0) - return 0; + return 0; } - + if (descr->type != 'c' && descr->type != '[' && descr->type != 'n') while (isspace(UCHAR(str[pos]))) ++pos; - + scanned = pos - anchor; - + if (descr->type == 'n') { - + *valObjPtr = Jim_NewIntObj(interp, anchor + scanned); } else if (pos >= strLen) { - + return -1; } else if (descr->type == 'c') { @@ -14610,7 +14580,7 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen return scanned; } else { - + if (descr->width > 0) { size_t sLen = utf8_strlen(&str[pos], strLen - pos); size_t tLen = descr->width > sLen ? sLen : descr->width; @@ -14619,7 +14589,7 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen tok = tmpObj->bytes; } else { - + tok = &str[pos]; } switch (descr->type) { @@ -14628,13 +14598,13 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen case 'x': case 'u': case 'i':{ - char *endp; + char *endp; jim_wide w; int base = descr->type == 'o' ? 8 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10; - + if (base == 0) { w = jim_strtoull(tok, &endp); } @@ -14643,10 +14613,10 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen } if (endp != tok) { - + *valObjPtr = Jim_NewIntObj(interp, w); - + scanned += endp - tok; } else { @@ -14667,9 +14637,9 @@ static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int strLen double value = strtod(tok, &endp); if (endp != tok) { - + *valObjPtr = Jim_NewDoubleObj(interp, value); - + scanned += endp - tok; } else { @@ -14698,61 +14668,61 @@ Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *fmtObjP Jim_Obj *emptyStr = 0; ScanFmtStringObj *fmtObj; - + JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format")); fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr; - + if (fmtObj->error != 0) { if (flags & JIM_ERRMSG) Jim_SetResultString(interp, fmtObj->error, -1); return 0; } - + emptyStr = Jim_NewEmptyStringObj(interp); Jim_IncrRefCount(emptyStr); - + resultList = Jim_NewListObj(interp, NULL, 0); if (fmtObj->maxPos > 0) { for (i = 0; i < fmtObj->maxPos; ++i) Jim_ListAppendElement(interp, resultList, emptyStr); JimListGetElements(interp, resultList, &resultc, &resultVec); } - + for (i = 0, pos = 0; i < fmtObj->count; ++i) { ScanFmtPartDescr *descr = &(fmtObj->descr[i]); Jim_Obj *value = 0; - + if (descr->type == 0) continue; - + if (scanned > 0) scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value); - + if (scanned == -1 && i == 0) goto eof; - + pos += scanned; - + if (value == 0) value = Jim_NewEmptyStringObj(interp); - + if (descr->pos == -1) { Jim_FreeNewObj(interp, value); } else if (descr->pos == 0) - + Jim_ListAppendElement(interp, resultList, value); else if (resultVec[descr->pos - 1] == emptyStr) { - + Jim_DecrRefCount(interp, resultVec[descr->pos - 1]); Jim_IncrRefCount(value); resultVec[descr->pos - 1] = value; } else { - + Jim_FreeNewObj(interp, value); goto err; } @@ -14794,11 +14764,11 @@ static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len) unsigned char *destByte = (unsigned char *)dest; unsigned int si, sj, x; - + if (interp->prngState == NULL) JimPrngInit(interp); prng = interp->prngState; - + for (x = 0; x < len; x++) { prng->i = (prng->i + 1) & 0xff; si = prng->sbox[prng->i]; @@ -14816,15 +14786,15 @@ static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen) int i; Jim_PrngState *prng; - + if (interp->prngState == NULL) JimPrngInit(interp); prng = interp->prngState; - + for (i = 0; i < 256; i++) prng->sbox[i] = i; - + for (i = 0; i < seedLen; i++) { unsigned char t; @@ -14855,7 +14825,7 @@ static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!intObjPtr) { - + wideValue = 0; } else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) { @@ -14869,12 +14839,12 @@ static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } } else { - + Jim_InvalidateStringRep(intObjPtr); JimWideValue(intObjPtr) = wideValue + increment; if (argv[1]->typePtr != &variableObjType) { - + Jim_SetVariable(interp, argv[1], intObjPtr); } } @@ -14883,8 +14853,8 @@ static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } -#define JIM_EVAL_SARGV_LEN 8 -#define JIM_EVAL_SINTV_LEN 8 +#define JIM_EVAL_SARGV_LEN 8 +#define JIM_EVAL_SINTV_LEN 8 static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -14896,12 +14866,12 @@ static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } - + if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL) return JIM_ERR; interp->unknown_called++; - + retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv); interp->unknown_called--; @@ -14923,7 +14893,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) #endif if (interp->framePtr->tailcallCmd) { - + cmdPtr = interp->framePtr->tailcallCmd; interp->framePtr->tailcallCmd = NULL; } @@ -14942,7 +14912,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) } interp->evalDepth++; - + Jim_SetEmptyResult(interp); if (cmdPtr->isproc) { retcode = JimCallProcedure(interp, cmdPtr, objc, objv); @@ -14963,13 +14933,13 @@ int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { int i, retcode; - + for (i = 0; i < objc; i++) Jim_IncrRefCount(objv[i]); retcode = JimInvokeCommand(interp, objc, objv); - + for (i = 0; i < objc; i++) Jim_DecrRefCount(interp, objv[i]); @@ -14991,7 +14961,7 @@ int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, int objc, Jim_Obj *co static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script) { if (!interp->errorFlag) { - + interp->errorFlag = 1; Jim_IncrRefCount(script->fileNameObj); Jim_DecrRefCount(interp, interp->errorFileNameObj); @@ -14999,13 +14969,13 @@ static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script) interp->errorLine = script->linenr; JimResetStackTrace(interp); - + interp->addStackTrace++; } - + if (interp->addStackTrace > 0) { - + JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); @@ -15044,10 +15014,10 @@ static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Ob objPtr = interp->result; break; case JIM_BREAK: - + return JIM_BREAK; case JIM_CONTINUE: - + return JIM_CONTINUE; default: return JIM_ERR; @@ -15086,19 +15056,19 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok break; case JIM_BREAK: if (flags & JIM_SUBST_FLAG) { - + tokens = i; continue; } - - + + case JIM_CONTINUE: if (flags & JIM_SUBST_FLAG) { intv[i] = NULL; continue; } - - + + default: while (i--) { Jim_DecrRefCount(interp, intv[i]); @@ -15113,7 +15083,7 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok totlen += intv[i]->length; } - + if (tokens == 1 && intv[0] && intv == sintv) { Jim_DecrRefCount(interp, intv[0]); return intv[0]; @@ -15123,14 +15093,14 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC && token[2].type == JIM_TT_VAR) { - + objPtr->typePtr = &interpolatedObjType; objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr; objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; Jim_IncrRefCount(intv[2]); } else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) { - + JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber); } @@ -15145,7 +15115,7 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok } } objPtr->bytes[totlen] = '\0'; - + if (intv != sintv) { Jim_Free(intv); } @@ -15189,7 +15159,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) return JimEvalObjList(interp, scriptObjPtr); } - Jim_IncrRefCount(scriptObjPtr); + Jim_IncrRefCount(scriptObjPtr); script = JimGetScript(interp, scriptObjPtr); if (!JimScriptValid(interp, script)) { Jim_DecrRefCount(interp, scriptObjPtr); @@ -15225,7 +15195,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) script->inUse++; - + prevScriptObj = interp->currentScriptObj; interp->currentScriptObj = scriptObjPtr; @@ -15236,15 +15206,15 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) int argc; int j; - + argc = token[i].objPtr->internalRep.scriptLineValue.argc; script->linenr = token[i].objPtr->internalRep.scriptLineValue.line; - + if (argc > JIM_EVAL_SARGV_LEN) argv = Jim_Alloc(sizeof(Jim_Obj *) * argc); - + i++; for (j = 0; j < argc; j++) { @@ -15304,7 +15274,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) argv[j] = wordObjPtr; } else { - + int len = Jim_ListLength(interp, wordObjPtr); int newargc = argc + len - 1; int k; @@ -15317,12 +15287,12 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) } } else { - + argv = Jim_Realloc(argv, sizeof(*argv) * newargc); } } - + for (k = 0; k < len; k++) { argv[j++] = wordObjPtr->internalRep.listValue.ele[k]; Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]); @@ -15330,22 +15300,22 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) Jim_DecrRefCount(interp, wordObjPtr); - + j--; argc += len - 1; } } if (retcode == JIM_OK && argc) { - + retcode = JimInvokeCommand(interp, argc, argv); - + if (Jim_CheckSignal(interp)) { retcode = JIM_SIGNAL; } } - + while (j-- > 0) { Jim_DecrRefCount(interp, argv[j]); } @@ -15356,17 +15326,17 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) } } - + if (retcode == JIM_ERR) { JimAddErrorToStack(interp, script); } - + else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) { - + interp->addStackTrace = 0; } - + interp->currentScriptObj = prevScriptObj; Jim_FreeIntRep(interp, scriptObjPtr); @@ -15380,10 +15350,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj) { int retcode; - + const char *varname = Jim_String(argNameObj); if (*varname == '&') { - + Jim_Obj *objPtr; Jim_CallFrame *savedCallFrame = interp->framePtr; @@ -15394,7 +15364,7 @@ static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argVa return JIM_ERR; } - + objPtr = Jim_NewStringObj(interp, varname + 1, -1); Jim_IncrRefCount(objPtr); retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent); @@ -15408,7 +15378,7 @@ static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argVa static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) { - + Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); int i; @@ -15417,13 +15387,13 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm if (i == cmd->u.proc.argsPos) { if (cmd->u.proc.arglist[i].defaultObjPtr) { - + Jim_AppendString(interp, argmsg, "?", 1); Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); Jim_AppendString(interp, argmsg, " ...?", -1); } else { - + Jim_AppendString(interp, argmsg, "?arg...?", -1); } } @@ -15443,7 +15413,6 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm } } Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); - Jim_FreeNewObj(interp, argmsg); } #ifdef jim_ext_namespace @@ -15452,7 +15421,7 @@ int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) Jim_CallFrame *callFramePtr; int retcode; - + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj); callFramePtr->argv = &interp->emptyObj; callFramePtr->argc = 0; @@ -15464,17 +15433,17 @@ int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) Jim_IncrRefCount(scriptObj); interp->framePtr = callFramePtr; - + if (interp->framePtr->level == interp->maxCallFrameDepth) { Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); retcode = JIM_ERR; } else { - + retcode = Jim_EvalObj(interp, scriptObj); } - + interp->framePtr = interp->framePtr->parent; JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); @@ -15488,7 +15457,7 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj int i, d, retcode, optargs; ScriptObj *script; - + if (argc - 1 < cmd->u.proc.reqArity || (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) { JimSetProcWrongArgs(interp, argv[0], cmd); @@ -15496,17 +15465,17 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj } if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) { - + return JIM_OK; } - + if (interp->framePtr->level == interp->maxCallFrameDepth) { Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); return JIM_ERR; } - + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj); callFramePtr->argv = argv; callFramePtr->argc = argc; @@ -15514,7 +15483,7 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; callFramePtr->staticVars = cmd->u.proc.staticVars; - + script = JimGetScript(interp, interp->currentScriptObj); callFramePtr->fileNameObj = script->fileNameObj; callFramePtr->line = script->linenr; @@ -15523,15 +15492,15 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); interp->framePtr = callFramePtr; - + optargs = (argc - 1 - cmd->u.proc.reqArity); - + i = 1; for (d = 0; d < cmd->u.proc.argListLen; d++) { Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr; if (d == cmd->u.proc.argsPos) { - + Jim_Obj *listObjPtr; int argsLen = 0; if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) { @@ -15539,7 +15508,7 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj } listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen); - + if (cmd->u.proc.arglist[d].defaultObjPtr) { nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr; } @@ -15552,12 +15521,12 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj continue; } - + if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) { retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]); } else { - + retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr); } if (retcode != JIM_OK) { @@ -15565,16 +15534,16 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj } } - + retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr); badargset: - + interp->framePtr = interp->framePtr->parent; JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); - + if (interp->framePtr->tailcallObj) { do { Jim_Obj *tailcallObj = interp->framePtr->tailcallObj; @@ -15590,14 +15559,14 @@ badargset: Jim_DecrRefCount(interp, tailcallObj); } while (interp->framePtr->tailcallObj); - + if (interp->framePtr->tailcallCmd) { JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd); interp->framePtr->tailcallCmd = NULL; } } - + if (retcode == JIM_RETURN) { if (--interp->returnLevel <= 0) { retcode = interp->returnCode; @@ -15713,7 +15682,7 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename) retcode = Jim_EvalObj(interp, scriptObjPtr); - + if (retcode == JIM_RETURN) { if (--interp->returnLevel <= 0) { retcode = interp->returnCode; @@ -15722,7 +15691,7 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename) } } if (retcode == JIM_ERR) { - + interp->addStackTrace++; } @@ -15752,7 +15721,7 @@ static void JimParseSubst(struct JimParserCtx *pc, int flags) if (JimParseVar(pc) == JIM_OK) { return; } - + pc->tstart = pc->p; flags |= JIM_SUBST_NOVAR; } @@ -15783,28 +15752,28 @@ static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags struct ScriptObj *script = Jim_Alloc(sizeof(*script)); ParseTokenList tokenlist; - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, scriptText, scriptTextLen, 1); while (1) { JimParseSubst(&parser, flags); if (parser.eof) { - + break; } ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, parser.tline); } - + script->inUse = 1; script->substFlags = flags; script->fileNameObj = interp->emptyObj; Jim_IncrRefCount(script->fileNameObj); SubstObjAddTokens(interp, script, &tokenlist); - + ScriptTokenListFree(&tokenlist); #ifdef DEBUG_SHOW_SUBST @@ -15819,7 +15788,7 @@ static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags } #endif - + Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, script); objPtr->typePtr = &scriptObjType; @@ -15837,7 +15806,7 @@ int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPt { ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags); - Jim_IncrRefCount(substObjPtr); + Jim_IncrRefCount(substObjPtr); script->inUse++; *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags); @@ -15853,7 +15822,11 @@ int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPt void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) { Jim_Obj *objPtr; - Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc); + Jim_Obj *listObjPtr; + + JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0")); + + listObjPtr = Jim_NewListObj(interp, argv, argc); if (*msg) { Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); @@ -15862,9 +15835,7 @@ void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1); Jim_DecrRefCount(interp, listObjPtr); - Jim_IncrRefCount(objPtr); Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr); - Jim_DecrRefCount(interp, objPtr); } typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, @@ -15878,7 +15849,7 @@ static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_HashEntry *he; Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); - + if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) { he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr)); if (he) { @@ -15909,7 +15880,7 @@ static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *objPtr; if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { - + return; } @@ -15969,7 +15940,7 @@ static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr, if (targetCallFrame == NULL) { return JIM_ERR; } - + if (targetCallFrame == interp->topFramePtr) { Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); return JIM_ERR; @@ -16156,7 +16127,7 @@ static int Jim_SetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv Jim_SetResult(interp, objPtr); return JIM_OK; } - + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) return JIM_ERR; Jim_SetResult(interp, argv[2]); @@ -16199,7 +16170,7 @@ static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_ERR; } - + while (1) { int boolean, retval; @@ -16239,7 +16210,7 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv return JIM_ERR; } - + if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { return retval; } @@ -16255,15 +16226,15 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv Jim_Obj *objPtr; int cmpOffset; - + expr = JimGetExpression(interp, argv[2]); incrScript = JimGetScript(interp, argv[3]); - + if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { goto evalstart; } - + if (incrScript->token[1].type != JIM_TT_ESC || expr->token[0].type != JIM_TT_VAR || (expr->token[1].type != JIM_TT_EXPR_INT && expr->token[1].type != JIM_TT_VAR)) { @@ -16280,17 +16251,17 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv goto evalstart; } - + if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) { goto evalstart; } - + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) { goto evalstart; } - + if (expr->token[1].type == JIM_TT_EXPR_INT) { if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) { goto evalstart; @@ -16299,11 +16270,11 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv else { stopVarNamePtr = expr->token[1].objPtr; Jim_IncrRefCount(stopVarNamePtr); - + stop = 0; } - + varNamePtr = expr->token[0].objPtr; Jim_IncrRefCount(varNamePtr); @@ -16312,12 +16283,12 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv goto testcond; } - + while (retval == JIM_OK) { - - - + + + if (stopVarNamePtr) { objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE); if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) { @@ -16329,14 +16300,14 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv break; } - + retval = Jim_EvalObj(interp, argv[4]); if (retval == JIM_OK || retval == JIM_CONTINUE) { retval = JIM_OK; objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG); - + if (objPtr == NULL) { retval = JIM_ERR; goto out; @@ -16360,21 +16331,21 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv #endif while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { - + retval = Jim_EvalObj(interp, argv[4]); if (retval == JIM_OK || retval == JIM_CONTINUE) { - - evalnext: + +JIM_IF_OPTIM(evalnext:) retval = Jim_EvalObj(interp, argv[3]); if (retval == JIM_OK || retval == JIM_CONTINUE) { - - testcond: + +JIM_IF_OPTIM(testcond:) retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); } } } - out: +JIM_IF_OPTIM(out:) if (stopVarNamePtr) { Jim_DecrRefCount(interp, stopVarNamePtr); } @@ -16420,7 +16391,7 @@ static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg retval = JIM_OK; - + i += incr; if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { @@ -16485,7 +16456,7 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg { int result = JIM_OK; int i, numargs; - Jim_ListIter twoiters[2]; + Jim_ListIter twoiters[2]; Jim_ListIter *iters; Jim_Obj *script; Jim_Obj *resultObj; @@ -16494,8 +16465,8 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); return JIM_ERR; } - script = argv[argc - 1]; - numargs = (argc - 1 - 1); + script = argv[argc - 1]; + numargs = (argc - 1 - 1); if (numargs == 2) { iters = twoiters; @@ -16523,30 +16494,30 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_IncrRefCount(resultObj); while (1) { - + for (i = 0; i < numargs; i += 2) { if (!JimListIterDone(interp, &iters[i + 1])) { break; } } if (i == numargs) { - + break; } - + for (i = 0; i < numargs; i += 2) { Jim_Obj *varName; - + JimListIterInit(&iters[i], argv[i + 1]); while ((varName = JimListIterNext(interp, &iters[i])) != NULL) { Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]); if (!valObj) { - + valObj = interp->emptyObj; } - + Jim_IncrRefCount(valObj); result = Jim_SetVariable(interp, varName, valObj); Jim_DecrRefCount(interp, valObj); @@ -16632,37 +16603,37 @@ static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (argc >= 3) { while (1) { - + if (current >= argc) goto err; if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) != JIM_OK) return retval; - + if (current >= argc) goto err; if (Jim_CompareStringImmediate(interp, argv[current], "then")) current++; - + if (current >= argc) goto err; if (boolean) return Jim_EvalObj(interp, argv[current]); - + if (++current >= argc) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); return JIM_OK; } falsebody = current++; if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { - + if (current != argc - 1) goto err; return Jim_EvalObj(interp, argv[current]); } else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) continue; - + else if (falsebody != argc - 1) goto err; return Jim_EvalObj(interp, argv[falsebody]); @@ -16774,7 +16745,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a break; case SWITCH_RE: command = Jim_NewStringObj(interp, "regexp", -1); - + case SWITCH_CMD:{ int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0); @@ -16784,7 +16755,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a JimListGetElements(interp, argv[opt], &patCount, &vector); caseList = vector; } - + if (rc < 0) { return -rc; } @@ -16922,7 +16893,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * goto wrongargs; } commandObj = argv[++i]; - + case OPT_EXACT: case OPT_GLOB: case OPT_REGEXP: @@ -16970,13 +16941,13 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * break; } - + if (!eq && opt_bool && opt_not && !opt_all) { continue; } if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) { - + Jim_Obj *resultObj; if (opt_bool) { @@ -17003,7 +16974,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * Jim_SetResult(interp, listObjPtr); } else { - + if (opt_bool) { Jim_SetResultBool(interp, opt_not); } @@ -17032,7 +17003,7 @@ static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * } listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!listObjPtr) { - + listObjPtr = Jim_NewListObj(interp, NULL, 0); new_obj = 1; } @@ -17105,12 +17076,12 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const JimRelToAbsRange(len, &first, &last, &rangeLen); - + if (first < len) { - + } else if (len == 0) { - + first = 0; } else { @@ -17119,13 +17090,13 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } - + newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first); - + ListInsertElements(newListObj, -1, argc - 4, argv + 4); - + ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen); Jim_SetResult(interp, newListObj); @@ -17140,7 +17111,7 @@ static int Jim_LsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg return JIM_ERR; } else if (argc == 3) { - + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) return JIM_ERR; Jim_SetResult(interp, argv[2]); @@ -17255,7 +17226,7 @@ static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a int new_obj = 0; stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!stringObjPtr) { - + stringObjPtr = Jim_NewEmptyStringObj(interp); new_obj = 1; } @@ -17304,7 +17275,7 @@ static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } if (rc == JIM_ERR) { - + interp->addStackTrace++; } return rc; @@ -17318,10 +17289,10 @@ static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * Jim_CallFrame *savedCallFrame, *targetCallFrame; const char *str; - + savedCallFrame = interp->framePtr; - + str = Jim_String(argv[1]); if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); @@ -17338,7 +17309,7 @@ static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?"); return JIM_ERR; } - + interp->framePtr = targetCallFrame; if (argc == 2) { retcode = Jim_EvalObj(interp, argv[1]); @@ -17440,11 +17411,11 @@ static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); } - + if (stackTraceObj && returnCode == JIM_ERR) { JimSetStackTrace(interp, stackTraceObj); } - + if (errorCodeObj && returnCode == JIM_ERR) { Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj); } @@ -17465,7 +17436,7 @@ static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } else if (argc >= 2) { - + Jim_CallFrame *cf = interp->framePtr->parent; Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); @@ -17475,17 +17446,17 @@ static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd")); - + JimIncrCmdRefCount(cmdPtr); cf->tailcallCmd = cmdPtr; - + JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj")); cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1); Jim_IncrRefCount(cf->tailcallObj); - + return JIM_EVAL; } return JIM_OK; @@ -17496,7 +17467,7 @@ static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Obj *cmdList; Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); - + cmdList = Jim_DuplicateObj(interp, prefixListObj); Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1); @@ -17554,18 +17525,18 @@ static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } if (cmd) { - + Jim_Obj *qualifiedCmdNameObj; const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj); JimCreateCommand(interp, cmdname, cmd); - + JimUpdateProcNamespace(interp, cmd, cmdname); JimFreeQualifiedName(interp, qualifiedCmdNameObj); - + Jim_SetResult(interp, argv[1]); return JIM_OK; } @@ -17582,13 +17553,13 @@ static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_ERR; } - + interp->local++; retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); interp->local--; - + if (retcode == 0) { Jim_Obj *cmdNameObj = Jim_GetResult(interp); @@ -17621,14 +17592,14 @@ static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); return JIM_ERR; } - + cmdPtr->u.proc.upcall++; JimIncrCmdRefCount(cmdPtr); - + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); - + cmdPtr->u.proc.upcall--; JimDecrCmdRefCount(interp, cmdPtr); @@ -17659,7 +17630,7 @@ static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar if (len == 3) { #ifdef jim_ext_namespace - + nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2)); #else Jim_SetResultString(interp, "namespaces not enabled", -1); @@ -17672,7 +17643,7 @@ static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); if (cmd) { - + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); Jim_IncrRefCount(nargv[0]); @@ -17702,7 +17673,7 @@ static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int i; Jim_CallFrame *targetCallFrame; - + if (argc > 3 && (argc % 2 == 0)) { targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); argc--; @@ -17715,13 +17686,13 @@ static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_ERR; } - + if (argc < 3) { Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); return JIM_ERR; } - + for (i = 1; i < argc; i += 2) { if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK) return JIM_ERR; @@ -17738,11 +17709,11 @@ static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); return JIM_ERR; } - + if (interp->framePtr->level == 0) - return JIM_OK; + return JIM_OK; for (i = 1; i < argc; i++) { - + const char *name = Jim_String(argv[i]); if (name[0] != ':' || name[1] != ':') { if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK) @@ -17769,17 +17740,17 @@ static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr, str = Jim_String(objPtr); strLen = Jim_Utf8Length(interp, objPtr); - + resultObjPtr = Jim_NewStringObj(interp, "", 0); while (strLen) { for (i = 0; i < numMaps; i += 2) { - Jim_Obj *objPtr; + Jim_Obj *eachObjPtr; const char *k; int kl; - objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i); - k = Jim_String(objPtr); - kl = Jim_Utf8Length(interp, objPtr); + eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i); + k = Jim_String(eachObjPtr); + kl = Jim_Utf8Length(interp, eachObjPtr); if (strLen >= kl && kl) { int rc; @@ -17796,7 +17767,7 @@ static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr, } } } - if (i == numMaps) { + if (i == numMaps) { int c; if (noMatchStart == NULL) noMatchStart = str; @@ -17840,7 +17811,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a } if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) - return JIM_ERR; + return Jim_CheckShowCommands(interp, argv[1], options); switch (option) { case OPT_LENGTH: @@ -17861,7 +17832,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a case OPT_CAT:{ Jim_Obj *objPtr; if (argc == 3) { - + objPtr = argv[2]; } else { @@ -17880,7 +17851,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a case OPT_COMPARE: case OPT_EQUAL: { - + long opt_length = -1; int n = argc - 4; int i = 2; @@ -17893,12 +17864,12 @@ badcompareargs: return JIM_ERR; } if (subopt == 0) { - + opt_case = 0; n--; } else { - + if (n < 2) { goto badcompareargs; } @@ -17913,7 +17884,7 @@ badcompareargs: } argv += argc - 2; if (opt_length < 0 && option != OPT_COMPARE && opt_case) { - + Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1])); } else { @@ -18027,7 +17998,6 @@ badcompareargs: case OPT_REVERSE:{ char *buf, *p; const char *str; - int len; int i; if (argc != 3) { @@ -18071,7 +18041,7 @@ badcompareargs: Jim_SetResultString(interp, "", 0); } else if (len == Jim_Length(argv[2])) { - + Jim_SetResultString(interp, str + idx, 1); } else { @@ -18225,7 +18195,7 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int i; int sig = 0; - + jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL); static const int max_ignore_code = sizeof(ignore_mask) * 8; @@ -18236,7 +18206,7 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar jim_wide option; int ignore; - + if (strcmp(arg, "--") == 0) { i++; break; @@ -18287,24 +18257,24 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar interp->signal_level += sig; if (Jim_CheckSignal(interp)) { - + exitCode = JIM_SIGNAL; } else { exitCode = Jim_EvalObj(interp, argv[0]); - + interp->errorFlag = 0; } interp->signal_level -= sig; - + if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) { - + return exitCode; } if (sig && exitCode == JIM_SIGNAL) { - + if (interp->signal_set_result) { interp->signal_set_result(interp, interp->sigmask); } @@ -18347,238 +18317,210 @@ static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_OK; } -#ifdef JIM_REFERENCES -static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 3 && argc != 4) { - Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?"); + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); return JIM_ERR; } - if (argc == 3) { - Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL)); - } - else { - Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3])); - } - return JIM_OK; -} - -static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_Reference *refPtr; - - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "reference"); + if (JimValidName(interp, "new procedure", argv[2])) { return JIM_ERR; } - if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) - return JIM_ERR; - Jim_SetResult(interp, refPtr->objPtr); - return JIM_OK; + + return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2])); } +#define JIM_DICTMATCH_KEYS 0x0001 +#define JIM_DICTMATCH_VALUES 0x002 -static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types) { - Jim_Reference *refPtr; + Jim_HashEntry *he; + Jim_Obj *listObjPtr; + Jim_HashTableIterator htiter; - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "reference newValue"); + if (SetDictFromAny(interp, objPtr) != JIM_OK) { return JIM_ERR; } - if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) - return JIM_ERR; - Jim_IncrRefCount(argv[2]); - Jim_DecrRefCount(interp, refPtr->objPtr); - refPtr->objPtr = argv[2]; - Jim_SetResult(interp, argv[2]); - return JIM_OK; -} + listObjPtr = Jim_NewListObj(interp, NULL, 0); -static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - Jim_SetResultInt(interp, Jim_Collect(interp)); + JimInitHashTableIterator(objPtr->internalRep.ptr, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + if (patternObj) { + Jim_Obj *matchObj = (match_type == JIM_DICTMATCH_KEYS) ? (Jim_Obj *)he->key : Jim_GetHashEntryVal(he); + if (!JimGlobMatch(Jim_String(patternObj), Jim_String(matchObj), 0)) { - - while (interp->freeList) { - Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr; - Jim_Free(interp->freeList); - interp->freeList = nextObjPtr; + continue; + } + } + if (return_types & JIM_DICTMATCH_KEYS) { + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); + } + if (return_types & JIM_DICTMATCH_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he)); + } } + Jim_SetResult(interp, listObjPtr); return JIM_OK; } - -static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) { - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?"); - return JIM_ERR; - } - if (argc == 2) { - Jim_Obj *cmdNamePtr; - - if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK) - return JIM_ERR; - if (cmdNamePtr != NULL) - Jim_SetResult(interp, cmdNamePtr); - } - else { - if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK) - return JIM_ERR; - Jim_SetResult(interp, argv[2]); + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return -1; } - return JIM_OK; + return ((Jim_HashTable *)objPtr->internalRep.ptr)->used; } - -static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { - Jim_Obj *listObjPtr; - Jim_HashTableIterator htiter; - Jim_HashEntry *he; + Jim_Obj *objPtr = Jim_NewDictObj(interp, NULL, 0); + int i; - listObjPtr = Jim_NewListObj(interp, NULL, 0); + JimPanic((objc == 0, "Jim_DictMerge called with objc=0")); - JimInitHashTableIterator(&interp->references, &htiter); - while ((he = Jim_NextHashEntry(&htiter)) != NULL) { - char buf[JIM_REFERENCE_SPACE + 1]; - Jim_Reference *refPtr = Jim_GetHashEntryVal(he); - const unsigned long *refId = he->key; - JimFormatReference(buf, refPtr, *refId); - Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1)); + + for (i = 0; i < objc; i++) { + Jim_HashTable *ht; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + + if (SetDictFromAny(interp, objv[i]) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return NULL; + } + ht = objv[i]->internalRep.ptr; + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + Jim_ReplaceHashEntry(objPtr->internalRep.ptr, Jim_GetHashEntryKey(he), Jim_GetHashEntryVal(he)); + } } - Jim_SetResult(interp, listObjPtr); - return JIM_OK; + return objPtr; } -#endif - -static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr) { - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); - return JIM_ERR; - } + Jim_HashTable *ht; + unsigned int i; + char buffer[100]; + int sum = 0; + int nonzero_count = 0; + Jim_Obj *output; + int bucket_counts[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (JimValidName(interp, "new procedure", argv[2])) { + if (SetDictFromAny(interp, objPtr) != JIM_OK) { return JIM_ERR; } - return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2])); -} + ht = (Jim_HashTable *)objPtr->internalRep.ptr; -#define JIM_DICTMATCH_VALUES 0x0001 -typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type); + snprintf(buffer, sizeof(buffer), "%d entries in table, %d buckets\n", ht->used, ht->size); + output = Jim_NewStringObj(interp, buffer, -1); -static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type) -{ - Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); - if (type & JIM_DICTMATCH_VALUES) { - Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he)); + for (i = 0; i < ht->size; i++) { + Jim_HashEntry *he = ht->table[i]; + int entries = 0; + while (he) { + entries++; + he = he->next; + } + if (entries > 9) { + bucket_counts[10]++; + } + else { + bucket_counts[entries]++; + } + if (entries) { + sum += entries; + nonzero_count++; + } + } + for (i = 0; i < 10; i++) { + snprintf(buffer, sizeof(buffer), "number of buckets with %d entries: %d\n", i, bucket_counts[i]); + Jim_AppendString(interp, output, buffer, -1); } + snprintf(buffer, sizeof(buffer), "number of buckets with 10 or more entries: %d\n", bucket_counts[10]); + Jim_AppendString(interp, output, buffer, -1); + snprintf(buffer, sizeof(buffer), "average search distance for entry: %.1f", nonzero_count ? (double)sum / nonzero_count : 0.0); + Jim_AppendString(interp, output, buffer, -1); + Jim_SetResult(interp, output); + return JIM_OK; } -static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, - JimDictMatchCallbackType *callback, int type) +static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char *subcmd, int argc, Jim_Obj *const *argv) { - Jim_HashEntry *he; - Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + Jim_Obj *prefixObj = Jim_NewStringObj(interp, basecmd, -1); - - Jim_HashTableIterator htiter; - JimInitHashTableIterator(ht, &htiter); - while ((he = Jim_NextHashEntry(&htiter)) != NULL) { - if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) { - callback(interp, listObjPtr, he, type); - } - } + Jim_AppendString(interp, prefixObj, " ", 1); + Jim_AppendString(interp, prefixObj, subcmd, -1); - return listObjPtr; + return Jim_EvalObjPrefix(interp, prefixObj, argc, argv); } - -int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +static int JimDictWith(Jim_Interp *interp, Jim_Obj *dictVarName, Jim_Obj *const *keyv, int keyc, Jim_Obj *scriptObj) { - if (SetDictFromAny(interp, objPtr) != JIM_OK) { + int i; + Jim_Obj *objPtr; + Jim_Obj *dictObj; + Jim_Obj **dictValues; + int len; + int ret = JIM_OK; + + + dictObj = Jim_GetVariable(interp, dictVarName, JIM_ERRMSG); + if (dictObj == NULL || Jim_DictKeysVector(interp, dictObj, keyv, keyc, &objPtr, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } - Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0)); - return JIM_OK; -} -int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) -{ - if (SetDictFromAny(interp, objPtr) != JIM_OK) { + if (Jim_DictPairs(interp, objPtr, &dictValues, &len) == JIM_ERR) { return JIM_ERR; } - Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES)); - return JIM_OK; -} - -int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) -{ - if (SetDictFromAny(interp, objPtr) != JIM_OK) { - return -1; + for (i = 0; i < len; i += 2) { + if (Jim_SetVariable(interp, dictValues[i], dictValues[i + 1]) == JIM_ERR) { + Jim_Free(dictValues); + return JIM_ERR; + } } - return ((Jim_HashTable *)objPtr->internalRep.ptr)->used; -} -int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr) -{ - Jim_HashTable *ht; - unsigned int i; - if (SetDictFromAny(interp, objPtr) != JIM_OK) { - return JIM_ERR; - } + if (Jim_Length(scriptObj)) { + ret = Jim_EvalObj(interp, scriptObj); - ht = (Jim_HashTable *)objPtr->internalRep.ptr; - - printf("%d entries in table, %d buckets\n", ht->used, ht->size); + if (ret == JIM_OK && Jim_GetVariable(interp, dictVarName, 0) != NULL) { - for (i = 0; i < ht->size; i++) { - Jim_HashEntry *he = ht->table[i]; + Jim_Obj **newkeyv = Jim_Alloc(sizeof(*newkeyv) * (keyc + 1)); + for (i = 0; i < keyc; i++) { + newkeyv[i] = keyv[i]; + } - if (he) { - printf("%d: ", i); + for (i = 0; i < len; i += 2) { - while (he) { - printf(" %s", Jim_String(he->key)); - he = he->next; + objPtr = Jim_GetVariable(interp, dictValues[i], 0); + newkeyv[keyc] = dictValues[i]; + Jim_SetDictKeysVector(interp, dictVarName, newkeyv, keyc + 1, objPtr, 0); } - printf("\n"); + Jim_Free(newkeyv); } } - return JIM_OK; -} - -static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char *subcmd, int argc, Jim_Obj *const *argv) -{ - Jim_Obj *prefixObj = Jim_NewStringObj(interp, basecmd, -1); - Jim_AppendString(interp, prefixObj, " ", 1); - Jim_AppendString(interp, prefixObj, subcmd, -1); + Jim_Free(dictValues); - return Jim_EvalObjPrefix(interp, prefixObj, argc, argv); + return ret; } static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr; + int types = JIM_DICTMATCH_KEYS; int option; static const char * const options[] = { "create", "get", "set", "unset", "exists", "keys", "size", "info", @@ -18598,7 +18540,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) { - return JIM_ERR; + return Jim_CheckShowCommands(interp, argv[1], options); } switch (option) { @@ -18645,12 +18587,15 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } return JIM_OK; + case OPT_VALUES: + types = JIM_DICTMATCH_VALUES; + case OPT_KEYS: if (argc != 3 && argc != 4) { Jim_WrongNumArgs(interp, 2, argv, "dictionary ?pattern?"); return JIM_ERR; } - return Jim_DictKeys(interp, argv[2], argc == 4 ? argv[3] : NULL); + return Jim_DictMatchTypes(interp, argv[2], argc == 4 ? argv[3] : NULL, types, types); case OPT_SIZE: if (argc != 3) { @@ -18667,15 +18612,16 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg if (argc == 2) { return JIM_OK; } - if (Jim_DictSize(interp, argv[2]) < 0) { + objPtr = Jim_DictMerge(interp, argc - 2, argv + 2); + if (objPtr == NULL) { return JIM_ERR; } - - break; + Jim_SetResult(interp, objPtr); + return JIM_OK; case OPT_UPDATE: if (argc < 6 || argc % 2) { - + argc = 2; } break; @@ -18695,8 +18641,15 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg return JIM_ERR; } return Jim_DictInfo(interp, argv[2]); + + case OPT_WITH: + if (argc < 4) { + Jim_WrongNumArgs(interp, 2, argv, "dictVar ?key ...? script"); + return JIM_ERR; + } + return JimDictWith(interp, argv[2], argv + 3, argc - 4, argv[argc - 1]); } - + return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2); } @@ -18766,7 +18719,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg int nons = 0; if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) { - + argc--; argv++; nons = 1; @@ -18777,12 +18730,11 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?"); return JIM_ERR; } - if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) - != JIM_OK) { - return JIM_ERR; + if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return Jim_CheckShowCommands(interp, argv[1], commands); } - + switch (cmd) { case INFO_EXISTS: if (argc != 3) { @@ -18811,17 +18763,17 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } case INFO_CHANNELS: - mode++; + mode++; #ifndef jim_ext_aio Jim_SetResultString(interp, "aio not enabled", -1); return JIM_ERR; #endif - + case INFO_PROCS: - mode++; - + mode++; + case INFO_COMMANDS: - + if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); return JIM_ERR; @@ -18837,13 +18789,13 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg break; case INFO_VARS: - mode++; - + mode++; + case INFO_LOCALS: - mode++; - + mode++; + case INFO_GLOBALS: - + if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); return JIM_ERR; @@ -18953,9 +18905,8 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg break; case INFO_STATICS: if (cmdPtr->u.proc.staticVars) { - int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES; Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars, - NULL, JimVariablesMatch, mode)); + NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES)); } break; } @@ -18987,11 +18938,11 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg break; case INFO_HOSTNAME: - + return Jim_Eval(interp, "os.gethostname"); case INFO_NAMEOFEXECUTABLE: - + return Jim_Eval(interp, "{info nameofexecutable}"); case INFO_RETURNCODES: @@ -19072,7 +19023,7 @@ static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a result = Jim_GetVariable(interp, objPtr, 0) != NULL; } else { - + Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE); if (cmd) { @@ -19115,7 +19066,7 @@ static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar } strLen = Jim_Utf8Length(interp, argv[1]); - + if (argc == 2) { splitChars = " \n\t\r"; splitLen = 4; @@ -19128,7 +19079,7 @@ static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar noMatchStart = str; resObjPtr = Jim_NewListObj(interp, NULL, 0); - + if (splitLen) { Jim_Obj *objPtr; while (strLen--) { @@ -19157,7 +19108,7 @@ static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int n = utf8_tounicode(str, &c); #ifdef JIM_OPTIMIZATION if (c >= 9 && c < 128) { - + c -= 9; if (!commonObj) { commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON); @@ -19191,7 +19142,7 @@ static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); return JIM_ERR; } - + if (argc == 2) { joinStr = " "; joinStrLen = 1; @@ -19470,9 +19421,9 @@ static int JimRangeLen(jim_wide start, jim_wide end, jim_wide step) return -1; len = end - start; if (len < 0) - len = -len; + len = -len; if (step < 0) - step = -step; + step = -step; len = 1 + ((len - 1) / step); if (len > INT_MAX) len = INT_MAX; @@ -19646,36 +19597,64 @@ void Jim_MakeErrorMessage(Jim_Interp *interp) Jim_EvalObjVector(interp, 2, argv); } -static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, - const char *prefix, const char *const *tablePtr, const char *name) +static char **JimSortStringTable(const char *const *tablePtr) { int count; char **tablePtrSorted; - int i; + for (count = 0; tablePtr[count]; count++) { } + + tablePtrSorted = Jim_Alloc(sizeof(char *) * (count + 1)); + memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); + qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); + tablePtrSorted[count] = NULL; + + return tablePtrSorted; +} + +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name) +{ + char **tablePtrSorted; + int i; + if (name == NULL) { name = "option"; } Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg); - tablePtrSorted = Jim_Alloc(sizeof(char *) * count); - memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); - qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); - for (i = 0; i < count; i++) { - if (i + 1 == count && count > 1) { + tablePtrSorted = JimSortStringTable(tablePtr); + for (i = 0; tablePtrSorted[i]; i++) { + if (tablePtrSorted[i + 1] == NULL && i > 0) { Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1); } Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL); - if (i + 1 != count) { + if (tablePtrSorted[i + 1]) { Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1); } } Jim_Free(tablePtrSorted); } + +int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr) +{ + if (Jim_CompareStringImmediate(interp, objPtr, "-commands")) { + int i; + char **tablePtrSorted = JimSortStringTable(tablePtr); + Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + for (i = 0; tablePtrSorted[i]; i++) { + Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, tablePtrSorted[i], -1)); + } + Jim_Free(tablePtrSorted); + return JIM_OK; + } + return JIM_ERR; +} + int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr, int *indexPtr, const char *name, int flags) { @@ -19690,7 +19669,7 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { - + *indexPtr = i; return JIM_OK; } @@ -19708,7 +19687,7 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, } } - + if (match >= 0) { *indexPtr = match; return JIM_OK; @@ -19745,11 +19724,13 @@ int Jim_IsList(Jim_Obj *objPtr) void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) { - + int len = strlen(format); int extra = 0; int n = 0; const char *params[5]; + int nobjparam = 0; + Jim_Obj *objparam[5]; char *buf; va_list args; int i; @@ -19768,6 +19749,8 @@ void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) Jim_Obj *objPtr = va_arg(args, Jim_Obj *); params[n] = Jim_GetString(objPtr, &l); + objparam[nobjparam++] = objPtr; + Jim_IncrRefCount(objPtr); } else { if (format[i] == '%') { @@ -19786,6 +19769,10 @@ void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) va_end(args); Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); + + for (i = 0; i < nobjparam; i++) { + Jim_DecrRefCount(interp, objparam[i]); + } } @@ -19810,7 +19797,7 @@ FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *fhObj) static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - + return JIM_OK; } @@ -19889,22 +19876,22 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type cmd = argv[1]; - + if (Jim_CompareStringImmediate(interp, cmd, "-help")) { if (argc == 2) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } help = 1; - + cmd = argv[2]; } - + if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { - + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); add_commands(interp, command_table, " "); return &dummy_subcmd; @@ -19914,14 +19901,14 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type for (ct = command_table; ct->cmd; ct++) { if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { - + break; } if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { if (partial) { - + if (help) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } @@ -19933,15 +19920,15 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type continue; } - + if (partial && !ct->cmd) { ct = partial; } if (!ct->cmd) { - + if (help) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } @@ -19951,22 +19938,22 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type if (help) { Jim_SetResultString(interp, "Usage: ", -1); - + add_cmd_usage(interp, ct, argv[0]); return &dummy_subcmd; } - + if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { Jim_SetResultString(interp, "wrong # args: should be \"", -1); - + add_cmd_usage(interp, ct, argv[0]); Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); return 0; } - + return ct; } @@ -20021,7 +20008,7 @@ int utf8_fromunicode(char *p, unsigned uc) *p = 0x80 | (uc & 0x3f); return 3; } - + else { *p++ = 0xf0 | ((uc & 0x1c0000) >> 18); *p++ = 0x80 | ((uc & 0x3f000) >> 12); @@ -20212,7 +20199,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ format += step; step = utf8_tounicode(format, &ch); } else if (ch == 'l') { - + format += step; step = utf8_tounicode(format, &ch); if (ch == 'l') { @@ -20239,7 +20226,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes); formatted_chars = Jim_Utf8Length(interp, objv[objIndex]); if (gotPrecision && (precision < formatted_chars)) { - + formatted_chars = precision; formatted_bytes = utf8_index(formatted_buf, precision); } @@ -20251,7 +20238,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) { goto error; } - + formatted_bytes = utf8_getchars(spec, code); formatted_buf = spec; formatted_chars = 1; @@ -20269,7 +20256,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ length = sizeof(w) * 8; - + if (num_buffer_size < length + 1) { num_buffer_size = length + 1; num_buffer = Jim_Realloc(num_buffer, num_buffer_size); @@ -20297,7 +20284,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ case 'g': case 'G': doubleType = 1; - + case 'd': case 'u': case 'o': @@ -20307,7 +20294,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ double d; int length; - + if (width) { p += sprintf(p, "%ld", width); } @@ -20315,7 +20302,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ p += sprintf(p, ".%ld", precision); } - + if (doubleType) { if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) { goto error; @@ -20346,7 +20333,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ *p++ = (char) ch; *p = '\0'; - + if (width > length) { length = width; } @@ -20354,7 +20341,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ length += precision; } - + if (num_buffer_size < length + 1) { num_buffer_size = length + 1; num_buffer = Jim_Realloc(num_buffer, num_buffer_size); @@ -20372,7 +20359,7 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ } default: { - + spec[0] = ch; spec[1] = '\0'; Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec); @@ -20424,33 +20411,33 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ -#define END 0 -#define BOL 1 -#define EOL 2 -#define ANY 3 -#define ANYOF 4 -#define ANYBUT 5 -#define BRANCH 6 -#define BACK 7 -#define EXACTLY 8 -#define NOTHING 9 -#define REP 10 -#define REPMIN 11 -#define REPX 12 -#define REPXMIN 13 -#define BOLX 14 -#define EOLX 15 -#define WORDA 16 -#define WORDZ 17 +#define END 0 +#define BOL 1 +#define EOL 2 +#define ANY 3 +#define ANYOF 4 +#define ANYBUT 5 +#define BRANCH 6 +#define BACK 7 +#define EXACTLY 8 +#define NOTHING 9 +#define REP 10 +#define REPMIN 11 +#define REPX 12 +#define REPXMIN 13 +#define BOLX 14 +#define EOLX 15 +#define WORDA 16 +#define WORDZ 17 -#define OPENNC 1000 -#define OPEN 1001 - +#define OPENNC 1000 +#define OPEN 1001 -#define CLOSENC 2000 -#define CLOSE 2001 + +#define CLOSENC 2000 +#define CLOSE 2001 #define CLOSE_END (CLOSE+REG_MAX_PAREN) #define REG_MAGIC 0xFADED00D @@ -20467,14 +20454,14 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{') #define META "^$.[()|?{+*" -#define HASWIDTH 1 -#define SIMPLE 2 -#define SPSTART 4 -#define WORST 0 +#define HASWIDTH 1 +#define SIMPLE 2 +#define SPSTART 4 +#define WORST 0 #define MAX_REP_COUNT 1000000 -static int reg(regex_t *preg, int paren , int *flagp ); +static int reg(regex_t *preg, int paren, int *flagp ); static int regpiece(regex_t *preg, int *flagp ); static int regbranch(regex_t *preg, int *flagp ); static int regatom(regex_t *preg, int *flagp ); @@ -20522,11 +20509,11 @@ int regcomp(regex_t *preg, const char *exp, int cflags) if (exp == NULL) FAIL(preg, REG_ERR_NULL_ARGUMENT); - + preg->cflags = cflags; preg->regparse = exp; - + preg->proglen = (strlen(exp) + 1) * 5; preg->program = malloc(preg->proglen * sizeof(int)); if (preg->program == NULL) @@ -20537,20 +20524,20 @@ int regcomp(regex_t *preg, const char *exp, int cflags) return preg->err; } - - if (preg->re_nsub >= REG_MAX_PAREN) + + if (preg->re_nsub >= REG_MAX_PAREN) FAIL(preg,REG_ERR_TOO_BIG); - - preg->regstart = 0; + + preg->regstart = 0; preg->reganch = 0; preg->regmust = 0; preg->regmlen = 0; - scan = 1; - if (OP(preg, regnext(preg, scan)) == END) { + scan = 1; + if (OP(preg, regnext(preg, scan)) == END) { scan = OPERAND(scan); - + if (OP(preg, scan) == EXACTLY) { preg->regstart = preg->program[OPERAND(scan)]; } @@ -20581,7 +20568,7 @@ int regcomp(regex_t *preg, const char *exp, int cflags) return 0; } -static int reg(regex_t *preg, int paren , int *flagp ) +static int reg(regex_t *preg, int paren, int *flagp ) { int ret; int br; @@ -20589,12 +20576,12 @@ static int reg(regex_t *preg, int paren , int *flagp ) int parno = 0; int flags; - *flagp = HASWIDTH; + *flagp = HASWIDTH; + - if (paren) { if (preg->regparse[0] == '?' && preg->regparse[1] == ':') { - + preg->regparse += 2; parno = -1; } @@ -20605,12 +20592,12 @@ static int reg(regex_t *preg, int paren , int *flagp ) } else ret = 0; - + br = regbranch(preg, &flags); if (br == 0) return 0; if (ret != 0) - regtail(preg, ret, br); + regtail(preg, ret, br); else ret = br; if (!(flags&HASWIDTH)) @@ -20621,21 +20608,21 @@ static int reg(regex_t *preg, int paren , int *flagp ) br = regbranch(preg, &flags); if (br == 0) return 0; - regtail(preg, ret, br); + regtail(preg, ret, br); if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } - + ender = regnode(preg, (paren) ? CLOSE+parno : END); regtail(preg, ret, ender); - + for (br = ret; br != 0; br = regnext(preg, br)) regoptail(preg, br, ender); - + if (paren && *preg->regparse++ != ')') { preg->err = REG_ERR_UNMATCHED_PAREN; return 0; @@ -20659,7 +20646,7 @@ static int regbranch(regex_t *preg, int *flagp ) int latest; int flags; - *flagp = WORST; + *flagp = WORST; ret = regnode(preg, BRANCH); chain = 0; @@ -20677,7 +20664,7 @@ static int regbranch(regex_t *preg, int *flagp ) } chain = latest; } - if (chain == 0) + if (chain == 0) (void) regnode(preg, NOTHING); return(ret); @@ -20707,7 +20694,7 @@ static int regpiece(regex_t *preg, int *flagp) return 0; } - + if (op == '{') { char *end; @@ -20779,7 +20766,7 @@ static void reg_addrange(regex_t *preg, int lower, int upper) if (lower > upper) { reg_addrange(preg, upper, lower); } - + regc(preg, upper - lower + 1); regc(preg, lower); } @@ -20847,13 +20834,13 @@ static int reg_decode_escape(const char *s, int *ch) case 'v': *ch = '\v'; break; case 'u': if (*s == '{') { - + n = parse_hex(s + 1, 6, ch); if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) { s += n + 2; } else { - + *ch = 'u'; } } @@ -20888,11 +20875,11 @@ static int regatom(regex_t *preg, int *flagp) int ch; int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase); - *flagp = WORST; + *flagp = WORST; preg->regparse += n; switch (ch) { - + case '^': ret = regnode(preg, BOL); break; @@ -20906,20 +20893,20 @@ static int regatom(regex_t *preg, int *flagp) case '[': { const char *pattern = preg->regparse; - if (*pattern == '^') { + if (*pattern == '^') { ret = regnode(preg, ANYBUT); pattern++; } else ret = regnode(preg, ANYOF); - + if (*pattern == ']' || *pattern == '-') { reg_addrange(preg, *pattern, *pattern); pattern++; } while (*pattern && *pattern != ']') { - + int start; int end; @@ -20932,7 +20919,7 @@ static int regatom(regex_t *preg, int *flagp) } } if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') { - + pattern += utf8_tounicode(pattern, &end); pattern += reg_utf8_tounicode_case(pattern, &end, nocase); if (end == '\\') { @@ -20959,9 +20946,9 @@ static int regatom(regex_t *preg, int *flagp) int i; for (i = 0; i < CC_NUM; i++) { - int n = strlen(character_class[i]); + n = strlen(character_class[i]); if (strncmp(pattern, character_class[i], n) == 0) { - + pattern += n + 1; break; } @@ -20970,7 +20957,7 @@ static int regatom(regex_t *preg, int *flagp) switch (i) { case CC_ALNUM: reg_addrange(preg, '0', '9'); - + case CC_ALPHA: if ((preg->cflags & REG_ICASE) == 0) { reg_addrange(preg, 'a', 'z'); @@ -20992,7 +20979,7 @@ static int regatom(regex_t *preg, int *flagp) case CC_XDIGIT: reg_addrange(preg, 'a', 'f'); reg_addrange(preg, 'A', 'F'); - + case CC_DIGIT: reg_addrange(preg, '0', '9'); break; @@ -21016,7 +21003,7 @@ static int regatom(regex_t *preg, int *flagp) continue; } } - + reg_addrange(preg, start, start); } regc(preg, '\0'); @@ -21039,7 +21026,7 @@ static int regatom(regex_t *preg, int *flagp) case '|': case ')': preg->err = REG_ERR_INTERNAL; - return 0; + return 0; case '?': case '+': case '*': @@ -21092,10 +21079,10 @@ static int regatom(regex_t *preg, int *flagp) regc(preg, '\0'); *flagp |= HASWIDTH|SIMPLE; break; - + default: - - + + preg->regparse--; goto de_fault; } @@ -21104,18 +21091,18 @@ static int regatom(regex_t *preg, int *flagp) default: { int added = 0; - + preg->regparse -= n; ret = regnode(preg, EXACTLY); - + while (*preg->regparse && strchr(META, *preg->regparse) == NULL) { n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE)); if (ch == '\\' && preg->regparse[n]) { if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) { - + break; } n += reg_decode_escape(preg->regparse + n, &ch); @@ -21127,19 +21114,19 @@ static int regatom(regex_t *preg, int *flagp) if (ISMULT(preg->regparse[n])) { - + if (added) { - + break; } - + regc(preg, ch); added++; preg->regparse += n; break; } - + regc(preg, ch); added++; preg->regparse += n; @@ -21170,11 +21157,11 @@ static int regnode(regex_t *preg, int op) { reg_grow(preg, 2); - + preg->program[preg->p++] = op; preg->program[preg->p++] = 0; - + return preg->p - 2; } @@ -21188,9 +21175,9 @@ static int reginsert(regex_t *preg, int op, int size, int opnd ) { reg_grow(preg, size); - + memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd)); - + memset(preg->program + opnd, 0, sizeof(int) * size); preg->program[opnd] = op; @@ -21206,7 +21193,7 @@ static void regtail(regex_t *preg, int p, int val) int temp; int offset; - + scan = p; for (;;) { temp = regnext(preg, scan); @@ -21226,7 +21213,7 @@ static void regtail(regex_t *preg, int p, int val) static void regoptail(regex_t *preg, int p, int val ) { - + if (p != 0 && OP(preg, p) == BRANCH) { regtail(preg, OPERAND(p), val); } @@ -21242,12 +21229,12 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat const char *s; int scan; - + if (preg == NULL || preg->program == NULL || string == NULL) { return REG_ERR_NULL_ARGUMENT; } - + if (*preg->program != REG_MAGIC) { return REG_ERR_CORRUPTED; } @@ -21260,9 +21247,9 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat preg->eflags = eflags; preg->pmatch = pmatch; preg->nmatch = nmatch; - preg->start = string; + preg->start = string; + - for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) { int op = OP(preg, scan); if (op == END) @@ -21271,7 +21258,7 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat preg->program[scan + 4] = 0; } - + if (preg->regmust != 0) { s = string; while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) { @@ -21280,17 +21267,17 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat } s++; } - if (s == NULL) + if (s == NULL) return REG_NOMATCH; } - + preg->regbol = string; - + if (preg->reganch) { if (eflags & REG_NOTBOL) { - + goto nextline; } while (1) { @@ -21300,7 +21287,7 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat if (*string) { nextline: if (preg->cflags & REG_NEWLINE) { - + string = strchr(string, '\n'); if (string) { preg->regbol = ++string; @@ -21312,10 +21299,10 @@ nextline: } } - + s = string; if (preg->regstart != '\0') { - + while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) { if (regtry(preg, s)) return REG_NOERROR; @@ -21323,7 +21310,7 @@ nextline: } } else - + while (1) { if (regtry(preg, s)) return REG_NOERROR; @@ -21336,11 +21323,11 @@ nextline: } } - + return REG_NOMATCH; } - + static int regtry( regex_t *preg, const char *string ) { int i; @@ -21381,7 +21368,7 @@ static int prefix_cmp(const int *prog, int proglen, const char *string, int noca static int reg_range_find(const int *range, int c) { while (*range) { - + if (c >= range[1] && c <= (range[0] + range[1] - 1)) { return 1; } @@ -21393,7 +21380,7 @@ static int reg_range_find(const int *range, int c) static const char *str_find(const char *string, int c, int nocase) { if (nocase) { - + c = utf8_upper(c); } while (*string) { @@ -21437,11 +21424,11 @@ static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) return 0; } if (matchmin) { - + max = no; no = min; } - + while (1) { if (matchmin) { if (no > max) { @@ -21455,18 +21442,18 @@ static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) } preg->reginput = save + utf8_index(save, no); reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); - + if (reg_iseol(preg, nextch) || c == nextch) { if (regmatch(preg, next)) { return(1); } } if (matchmin) { - + no++; } else { - + no--; } } @@ -21480,9 +21467,9 @@ static int regmatchrepeat(regex_t *preg, int scan, int matchmin) int max = scanpt[2]; int min = scanpt[3]; - + if (scanpt[4] < min) { - + scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; @@ -21495,11 +21482,11 @@ static int regmatchrepeat(regex_t *preg, int scan, int matchmin) } if (matchmin) { - + if (regmatch(preg, regnext(preg, scan))) { return 1; } - + scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; @@ -21507,7 +21494,7 @@ static int regmatchrepeat(regex_t *preg, int scan, int matchmin) scanpt[4]--; return 0; } - + if (scanpt[4] < max) { scanpt[4]++; if (regmatch(preg, scan + 5)) { @@ -21515,15 +21502,15 @@ static int regmatchrepeat(regex_t *preg, int scan, int matchmin) } scanpt[4]--; } - + return regmatch(preg, regnext(preg, scan)); } static int regmatch(regex_t *preg, int prog) { - int scan; - int next; + int scan; + int next; const char *save; scan = prog; @@ -21537,7 +21524,7 @@ static int regmatch(regex_t *preg, int prog) int c; #ifdef DEBUG if (regnarrate) { - fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); + fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); } #endif next = regnext(preg, scan); @@ -21548,7 +21535,7 @@ static int regmatch(regex_t *preg, int prog) if ((preg->eflags & REG_NOTBOL)) { return(0); } - + case BOL: if (preg->reginput != preg->regbol) { return(0); @@ -21556,7 +21543,7 @@ static int regmatch(regex_t *preg, int prog) break; case EOLX: if (c != 0) { - + return 0; } break; @@ -21566,27 +21553,27 @@ static int regmatch(regex_t *preg, int prog) } break; case WORDA: - + if ((!isalnum(UCHAR(c))) && c != '_') return(0); - + if (preg->reginput > preg->regbol && (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) return(0); break; case WORDZ: - + if (preg->reginput > preg->regbol) { - + if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') { c = preg->reginput[-1]; - + if (isalnum(UCHAR(c)) || c == '_') { break; } } } - + return(0); case ANY: @@ -21626,8 +21613,8 @@ static int regmatch(regex_t *preg, int prog) case BACK: break; case BRANCH: - if (OP(preg, next) != BRANCH) - next = OPERAND(scan); + if (OP(preg, next) != BRANCH) + next = OPERAND(scan); else { do { save = preg->reginput; @@ -21638,7 +21625,7 @@ static int regmatch(regex_t *preg, int prog) scan = regnext(preg, scan); } while (scan != 0 && OP(preg, scan) == BRANCH); return(0); - + } break; case REP: @@ -21650,7 +21637,7 @@ static int regmatch(regex_t *preg, int prog) return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); case END: - return 1; + return 1; case OPENNC: case CLOSENC: @@ -21697,7 +21684,7 @@ static int regrepeat(regex_t *preg, int p, int max) opnd = OPERAND(p); switch (OP(preg, p)) { case ANY: - + while (!reg_iseol(preg, *scan) && count < max) { count++; scan++; @@ -21733,9 +21720,9 @@ static int regrepeat(regex_t *preg, int p, int max) scan += n; } break; - default: + default: preg->err = REG_ERR_INTERNAL; - count = 0; + count = 0; break; } preg->reginput = scan; @@ -21760,7 +21747,7 @@ static int regnext(regex_t *preg, int p ) static int regopsize(regex_t *preg, int p ) { - + switch (OP(preg, p)) { case REP: case REPMIN: @@ -21881,7 +21868,7 @@ DIR *opendir(const char *name) if (name && name[0]) { size_t base_length = strlen(name); - const char *all = + const char *all = strchr("/\\", name[base_length - 1]) ? "*" : "/*"; if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 && @@ -21890,13 +21877,13 @@ DIR *opendir(const char *name) if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1) dir->result.d_name = 0; - else { + else { Jim_Free(dir->name); Jim_Free(dir); dir = 0; } } - else { + else { Jim_Free(dir); dir = 0; errno = ENOMEM; @@ -21918,7 +21905,7 @@ int closedir(DIR * dir) Jim_Free(dir->name); Jim_Free(dir); } - if (result == -1) + if (result == -1) errno = EBADF; return result; } @@ -21949,6 +21936,9 @@ struct dirent *readdir(DIR * dir) #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#ifdef HAVE_SYS_STAT_H + #include <sys/stat.h> +#endif #include "linenoise.h" #else #define MAX_LINE_LEN 512 @@ -21994,14 +21984,22 @@ void Jim_HistoryAdd(const char *line) void Jim_HistorySave(const char *filename) { #ifdef USE_LINENOISE +#ifdef HAVE_UMASK + mode_t mask; + + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); +#endif linenoiseHistorySave(filename); +#ifdef HAVE_UMASK + mask = umask(mask); +#endif #endif } void Jim_HistoryShow(void) { #ifdef USE_LINENOISE - + int i; int len; char **history = linenoiseHistory(&len); @@ -22011,12 +22009,42 @@ void Jim_HistoryShow(void) #endif } +#ifdef USE_LINENOISE +struct JimCompletionInfo { + Jim_Interp *interp; + Jim_Obj *command; +}; + +void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata) +{ + struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata; + Jim_Obj *objv[2]; + int ret; + + objv[0] = info->command; + objv[1] = Jim_NewStringObj(info->interp, prefix, -1); + + ret = Jim_EvalObjVector(info->interp, 2, objv); + + + if (ret == JIM_OK) { + int i; + Jim_Obj *listObj = Jim_GetResult(info->interp); + int len = Jim_ListLength(info->interp, listObj); + for (i = 0; i < len; i++) { + linenoiseAddCompletion(comp, Jim_String(Jim_ListGetIndex(info->interp, listObj, i))); + } + } +} +#endif + int Jim_InteractivePrompt(Jim_Interp *interp) { int retcode = JIM_OK; char *history_file = NULL; #ifdef USE_LINENOISE const char *home; + struct JimCompletionInfo compinfo; home = getenv("HOME"); if (home && isatty(STDIN_FILENO)) { @@ -22025,6 +22053,13 @@ int Jim_InteractivePrompt(Jim_Interp *interp) snprintf(history_file, history_len, "%s/.jim_history", home); Jim_HistoryLoad(history_file); } + + compinfo.interp = interp; + compinfo.command = Jim_NewStringObj(interp, "tcl::autocomplete", -1); + Jim_IncrRefCount(compinfo.command); + + + linenoiseSetCompletionCallback(JimCompletionCallback, &compinfo); #endif printf("Welcome to Jim version %d.%d\n", @@ -22067,7 +22102,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp) goto out; } if (Jim_Length(scriptObjPtr) != 0) { - + Jim_AppendString(interp, scriptObjPtr, "\n", 1); } Jim_AppendString(interp, scriptObjPtr, line, -1); @@ -22079,7 +22114,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp) } #ifdef USE_LINENOISE if (strcmp(Jim_String(scriptObjPtr), "h") == 0) { - + Jim_HistoryShow(); Jim_DecrRefCount(interp, scriptObjPtr); continue; @@ -22106,6 +22141,12 @@ int Jim_InteractivePrompt(Jim_Interp *interp) } out: Jim_Free(history_file); + +#ifdef USE_LINENOISE + Jim_DecrRefCount(interp, compinfo.command); + linenoiseSetCompletionCallback(NULL, NULL); +#endif + return retcode; } @@ -22122,7 +22163,7 @@ static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) int n; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); - + for (n = 0; n < argc; n++) { Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); @@ -22148,12 +22189,12 @@ void usage(const char* executable_name) printf("Without options: Interactive mode\n"); printf("\n"); printf("Options:\n"); - printf(" --version : prints the version string\n"); - printf(" --help : prints this text\n"); - printf(" -e CMD : executes command CMD\n"); - printf(" NOTE: all subsequent options will be passed as arguments to the command\n"); - printf(" [filename] : executes the script contained in the named file\n"); - printf(" NOTE: all subsequent options will be passed to the script\n\n"); + printf(" --version : prints the version string\n"); + printf(" --help : prints this text\n"); + printf(" -e CMD : executes command CMD\n"); + printf(" NOTE: all subsequent options will be passed as arguments to the command\n"); + printf(" [filename|-] : executes the script contained in the named file, or from stdin if \"-\"\n"); + printf(" NOTE: all subsequent options will be passed to the script\n\n"); } int main(int argc, char *const argv[]) @@ -22162,7 +22203,7 @@ int main(int argc, char *const argv[]) Jim_Interp *interp; char *const orig_argv0 = argv[0]; - + if (argc > 1 && strcmp(argv[1], "--version") == 0) { printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); return 0; @@ -22172,11 +22213,11 @@ int main(int argc, char *const argv[]) return 0; } - + interp = Jim_CreateInterp(); Jim_RegisterCoreCommands(interp); - + if (Jim_InitStaticExtensions(interp) != JIM_OK) { JimPrintErrorMessage(interp); } @@ -22186,7 +22227,7 @@ int main(int argc, char *const argv[]) retcode = Jim_initjimshInit(interp); if (argc == 1) { - + if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); } @@ -22196,9 +22237,9 @@ int main(int argc, char *const argv[]) } } else { - + if (argc > 2 && strcmp(argv[1], "-e") == 0) { - + JimSetArgv(interp, argc - 3, argv + 3); retcode = Jim_Eval(interp, argv[2]); if (retcode != JIM_ERR) { @@ -22208,7 +22249,11 @@ int main(int argc, char *const argv[]) else { Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); JimSetArgv(interp, argc - 2, argv + 2); - retcode = Jim_EvalFile(interp, argv[1]); + if (strcmp(argv[1], "-") == 0) { + retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]"); + } else { + retcode = Jim_EvalFile(interp, argv[1]); + } } if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); diff --git a/autosetup/pkg-config.tcl b/autosetup/pkg-config.tcl index a24e78a..6ef78fe 100644 --- a/autosetup/pkg-config.tcl +++ b/autosetup/pkg-config.tcl @@ -3,15 +3,15 @@ # @synopsis: # -# The 'pkg-config' module allows package information to be found via pkg-config +# The 'pkg-config' module allows package information to be found via 'pkg-config'. # # If not cross-compiling, the package path should be determined automatically -# by pkg-config. +# by 'pkg-config'. # If cross-compiling, the default package path is the compiler sysroot. -# If the C compiler doesn't support -print-sysroot, the path can be supplied -# by the --sysroot option or by defining SYSROOT. +# If the C compiler doesn't support '-print-sysroot', the path can be supplied +# by the '--sysroot' option or by defining 'SYSROOT'. # -# PKG_CONFIG may be set to use an alternative to pkg-config +# 'PKG_CONFIG' may be set to use an alternative to 'pkg-config'. use cc @@ -21,12 +21,13 @@ module-options { # @pkg-config-init ?required? # -# Initialises the pkg-config system. Unless required is set to 0, -# it is a fatal error if the pkg-config +# Initialises the 'pkg-config' system. Unless '$required' is set to 0, +# it is a fatal error if a usable 'pkg-config' is not found . +# # This command will normally be called automatically as required, -# but it may be invoked explicitly if lack of pkg-config is acceptable. +# but it may be invoked explicitly if lack of 'pkg-config' is acceptable. # -# Returns 1 if ok, or 0 if pkg-config not found/usable (only if required=0) +# Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$required' is 0). # proc pkg-config-init {{required 1}} { if {[is-defined HAVE_PKG_CONFIG]} { @@ -49,7 +50,7 @@ proc pkg-config-init {{required 1}} { set found 1 if {[opt-val sysroot] ne ""} { - define SYSROOT [file-normalize [opt-val sysroot]] + define SYSROOT [file-normalize [lindex [opt-val sysroot] end]] msg-result "Using specified sysroot [get-define SYSROOT]" } elseif {[get-define build] ne [get-define host]} { if {[catch {exec-with-stderr [get-define CC] -print-sysroot} result errinfo] == 0} { @@ -83,17 +84,17 @@ proc pkg-config-init {{required 1}} { # @pkg-config module ?requirements? # -# Use pkg-config to find the given module meeting the given requirements. +# Use 'pkg-config' to find the given module meeting the given requirements. # e.g. # ## pkg-config pango >= 1.37.0 # -# If found, returns 1 and sets HAVE_PKG_PANGO to 1 along with: +# If found, returns 1 and sets 'HAVE_PKG_PANGO' to 1 along with: # ## PKG_PANGO_VERSION to the found version -## PKG_PANGO_LIBS to the required libs (--libs-only-l) +## PKG_PANGO_LIBS to the required libs (--libs-only-l) ## PKG_PANGO_LDFLAGS to the required linker flags (--libs-only-L) -## PKG_PANGO_CFLAGS to the required compiler flags (--cflags) +## PKG_PANGO_CFLAGS to the required compiler flags (--cflags) # # If not found, returns 0. # @@ -124,10 +125,10 @@ proc pkg-config {module args} { # @pkg-config-get module setting # -# Convenience access to the results of pkg-config +# Convenience access to the results of 'pkg-config'. # -# For example, [pkg-config-get pango CFLAGS] returns -# the value of PKG_PANGO_CFLAGS, or "" if not defined. +# For example, '[pkg-config-get pango CFLAGS]' returns +# the value of 'PKG_PANGO_CFLAGS', or '""' if not defined. proc pkg-config-get {module name} { set prefix [feature-define-name $module PKG_] get-define ${prefix}_${name} "" diff --git a/autosetup/system.tcl b/autosetup/system.tcl index 7b4045d..1414cb3 100644 --- a/autosetup/system.tcl +++ b/autosetup/system.tcl @@ -4,12 +4,12 @@ # @synopsis: # # This module supports common system interrogation and options -# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. # -# It also support the 'feature' naming convention, where searching -# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H +# It also support the "feature" naming convention, where searching +# for a feature such as 'sys/type.h' defines 'HAVE_SYS_TYPES_H'. # -# It defines the following variables, based on --prefix unless overridden by the user: +# It defines the following variables, based on '--prefix' unless overridden by the user: # ## datadir ## sysconfdir @@ -19,13 +19,18 @@ ## mandir ## includedir # -module-options { +# If '--prefix' is not supplied, it defaults to '/usr/local' unless 'defaultprefix' is defined *before* +# including the 'system' module. + +set defaultprefix [get-define defaultprefix /usr/local] + +module-options [subst -noc -nob { host:host-alias => {a complete or partial cpu-vendor-opsys for the system where the application will run (defaults to the same value as --build)} build:build-alias => {a complete or partial cpu-vendor-opsys for the system where the application will be built (defaults to the result of running config.guess)} - prefix:dir => {the target directory for the build (defaults to /usr/local)} + prefix:dir => {the target directory for the build (defaults to '$defaultprefix')} # These (hidden) options are supported for autoconf/automake compatibility exec-prefix: @@ -42,10 +47,18 @@ module-options { localstatedir: maintainer-mode=0 dependency-tracking=0 -} +}] -# Returns 1 if exists, or 0 if not +# @check-feature name { script } +# +# defines feature '$name' to the return value of '$script', +# which should be 1 if found or 0 if not found. +# +# e.g. the following will define 'HAVE_CONST' to 0 or 1. # +## check-feature const { +## cctest -code {const int _x = 0;} +## } proc check-feature {name code} { msg-checking "Checking for $name..." set r [uplevel 1 $code] @@ -60,9 +73,10 @@ proc check-feature {name code} { # @have-feature name ?default=0? # -# Returns the value of the feature if defined, or $default if not. -# See 'feature-define-name' for how the feature name -# is translated into the define name. +# Returns the value of feature '$name' if defined, or '$default' if not. +# +# See 'feature-define-name' for how the "feature" name +# is translated into the "define" name. # proc have-feature {name {default 0}} { get-define [feature-define-name $name] $default @@ -70,9 +84,10 @@ proc have-feature {name {default 0}} { # @define-feature name ?value=1? # -# Sets the feature 'define' to the given value. -# See 'feature-define-name' for how the feature name -# is translated into the define name. +# Sets the feature 'define' to '$value'. +# +# See 'feature-define-name' for how the "feature" name +# is translated into the "define" name. # proc define-feature {name {value 1}} { define [feature-define-name $name] $value @@ -80,7 +95,7 @@ proc define-feature {name {value 1}} { # @feature-checked name # -# Returns 1 if the feature has been checked, whether true or not +# Returns 1 if feature '$name' has been checked, whether true or not. # proc feature-checked {name} { is-defined [feature-define-name $name] @@ -88,17 +103,20 @@ proc feature-checked {name} { # @feature-define-name name ?prefix=HAVE_? # -# Converts a name to the corresponding define, -# e.g. sys/stat.h becomes HAVE_SYS_STAT_H. +# Converts a "feature" name to the corresponding "define", +# e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'. # -# Converts * to P and all non-alphanumeric to underscore. +# Converts '*' to 'P' and all non-alphanumeric to underscore. # proc feature-define-name {name {prefix HAVE_}} { string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] } -# If $file doesn't exist, or it's contents are different than $buf, -# the file is written and $script is executed. +# @write-if-changed filename contents ?script? +# +# If '$filename' doesn't exist, or it's contents are different to '$contents', +# the file is written and '$script' is evaluated. +# # Otherwise a "file is unchanged" message is displayed. proc write-if-changed {file buf {script {}}} { set old [readfile $file ""] @@ -112,16 +130,16 @@ proc write-if-changed {file buf {script {}}} { # @make-template template ?outfile? # -# Reads the input file <srcdir>/$template and writes the output file $outfile. -# If $outfile is blank/omitted, $template should end with ".in" which +# Reads the input file '<srcdir>/$template' and writes the output file '$outfile'. +# If '$outfile' is blank/omitted, '$template' should end with '.in' which # is removed to create the output file name. # -# Each pattern of the form @define@ is replaced with the corresponding -# define, if it exists, or left unchanged if not. +# Each pattern of the form '@define@' is replaced with the corresponding +# "define", if it exists, or left unchanged if not. # -# The special value @srcdir@ is substituted with the relative +# The special value '@srcdir@' is substituted with the relative # path to the source directory from the directory where the output -# file is created, while the special value @top_srcdir@ is substituted +# file is created, while the special value '@top_srcdir@' is substituted # with the relative path to the top level source directory. # # Conditional sections may be specified as follows: @@ -131,14 +149,14 @@ proc write-if-changed {file buf {script {}}} { ## lines ## @endif # -# Where 'name' is a defined variable name and @else is optional. +# Where 'name' is a defined variable name and '@else' is optional. # If the expression does not match, all lines through '@endif' are ignored. # # The alternative forms may also be used: ## @if name ## @if name != value # -# Where the first form is true if the variable is defined, but not empty or 0 +# Where the first form is true if the variable is defined, but not empty nor 0. # # Currently these expressions can't be nested. # @@ -210,7 +228,7 @@ proc make-template {template {out {}}} { } # build/host tuples and cross-compilation prefix -set build [opt-val build] +set build [lindex [opt-val build] end] define build_alias $build if {$build eq ""} { define build [config_guess] @@ -218,7 +236,7 @@ if {$build eq ""} { define build [config_sub $build] } -set host [opt-val host] +set host [lindex [opt-val host] end] define host_alias $host if {$host eq ""} { define host [get-define build] @@ -229,8 +247,7 @@ if {$host eq ""} { } define cross [get-env CROSS $cross] -# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use" -set prefix [opt-val prefix [get-define defaultprefix /usr/local]] +set prefix [lindex [opt-val prefix $defaultprefix] end] # These are for compatibility with autoconf define target [get-define host] @@ -241,7 +258,7 @@ define srcdir $autosetup(srcdir) define top_srcdir [get-env top_srcdir [get-define srcdir]] # autoconf supports all of these -set exec_prefix [opt-val exec-prefix $prefix] +set exec_prefix [lindex [opt-val exec-prefix $prefix] end] define exec_prefix $exec_prefix foreach {name defpath} { bindir /bin @@ -249,7 +266,7 @@ foreach {name defpath} { libexecdir /libexec libdir /lib } { - define $name [opt-val $name $exec_prefix$defpath] + define $name [lindex [opt-val $name $exec_prefix$defpath] end] } foreach {name defpath} { datadir /share @@ -260,7 +277,7 @@ foreach {name defpath} { mandir /share/man includedir /include } { - define $name [opt-val $name $prefix$defpath] + define $name [lindex [opt-val $name $prefix$defpath] end] } define SHELL [get-env SHELL [find-an-executable sh bash ksh]] diff --git a/autosetup/tmake.tcl b/autosetup/tmake.tcl index b946362..a9d7219 100644 --- a/autosetup/tmake.tcl +++ b/autosetup/tmake.tcl @@ -17,9 +17,9 @@ define CONFIGURED # @make-tmake-settings outfile patterns ... # -# Examines all defined variables which match the given patterns (defaults to "*") +# Examines all defined variables which match the given patterns (defaults to '*') # and writes a tmake-compatible .conf file defining those variables. -# For example, if ABC is "3 monkeys" and ABC matches a pattern, then the file will include: +# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include: # ## define ABC {3 monkeys} # @@ -27,7 +27,7 @@ define CONFIGURED # # Typical usage is: # -# make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} +## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} proc make-tmake-settings {file args} { file mkdir [file dirname $file] set lines {} @@ -1,3 +1,3 @@ #!/bin/sh dir="`dirname "$0"`/autosetup" -WRAPPER="$0"; export WRAPPER; exec "`$dir/find-tclsh`" "$dir/autosetup" "$@" +WRAPPER="$0"; export WRAPPER; exec "`$dir/autosetup-find-tclsh`" "$dir/autosetup" "$@" |