diff --git a/Makefile.autosetup b/Makefile.autosetup index e6a3bb517..533cd018b 100644 --- a/Makefile.autosetup +++ b/Makefile.autosetup @@ -1,9 +1,12 @@ include @builddir@/mk/defs.mk -DIRS= external compat libpkg/repo libpkg src docs scripts @testsdir@ +DIRS= external compat libpkg/repo libpkg src docs scripts +@if TESTS +DIRS+= tests +@endif include $(MK)/dir.mk -@if coverage == "1" +@if coverage check: clean-profiles clean-profiles: @@ -11,7 +14,7 @@ clean-profiles: @endif check: all -@if testsdir == "tests" +@if TESTS export LLVM_PROFILE_FILE=/tmp/pkg.%p.profraw if [ "$(HTML)" != "" ]; then \ args="-r $(top_builddir)/res.db" ; \ @@ -26,7 +29,7 @@ check: all exit $${FAILED} @endif -@if coverage == "1" +@if coverage check-coverage: check llvm-profdata merge --output=pkg.profdata /tmp/pkg.*.profraw diff --git a/auto.def b/auto.def index 488f636bc..de221a975 100644 --- a/auto.def +++ b/auto.def @@ -204,7 +204,7 @@ foreach header [list endian.h sys/endian.h] { } if {[string match *-darwin* [get-define host]]} { - define libabidir libmachista + define libmachista define waflags "" define nowaflags "" } else { @@ -219,17 +219,17 @@ if {[string match *-darwin* [get-define host]]} { cc-with { -libs { -lelf } } { if {[cc-check-functions gelf_getehdr]} { define-feature libelf + define libelf-external define-append EXTRA_LIBS -lelf - define libabidir "" cc-check-types Elf_Note } else { + define libelf-internal define-feature libelf 0 - define libabidir "libelf" } } } else { define-feature libelf 0 - define libabidir "libelf" + define libelf-internal } } @@ -261,11 +261,10 @@ if {[opt-bool with-coverage]} { } } -define testsdir "" if {[pkg-config-init 0]} { # atf if {[pkg-config atf-c] && [cc-check-progs kyua]} { - define testsdir tests + define TESTS puts "test suite will be built" } else { puts "Skipping test suite" diff --git a/autosetup/README.autosetup b/autosetup/README.autosetup index 2e077b81b..a848c3f88 100644 --- a/autosetup/README.autosetup +++ b/autosetup/README.autosetup @@ -1,4 +1,4 @@ -README.autosetup created by autosetup v0.6.8 +README.autosetup created by autosetup v0.6.9+ This is the autosetup directory for a local install of autosetup. It contains autosetup, support files and loadable modules. diff --git a/autosetup/autosetup b/autosetup/autosetup index 51c6fd63a..320cc4d4f 100755 --- a/autosetup/autosetup +++ b/autosetup/autosetup @@ -5,7 +5,8 @@ # \ dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@" -set autosetup(version) 0.6.8 +# Note that the version has a trailing + on unreleased versions +set autosetup(version) 0.6.9+ # Can be set to 1 to debug early-init problems set autosetup(debug) [expr {"--debug" in $argv}] @@ -81,6 +82,8 @@ proc main {argv} { set autosetup(optionhelp) {} set autosetup(showhelp) 0 + use util + # Parse options use getopt @@ -90,13 +93,13 @@ proc main {argv} { #"=Core Options:" options-add { - help:=local => "display help and options. Optionally specify a module name, such as --help=system" + help:=all => "display help and options. Optional: module name, such as --help=system" licence license => "display the autosetup license" - version => "display the version of autosetup" + 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" + debug => "display debugging output as autosetup runs" + install:=. => "install autosetup to the current or given directory" } if {$autosetup(installed)} { # hidden options so we can produce a nice error @@ -201,19 +204,26 @@ proc main {argv} { autosetup_add_dep $autosetup(autodef) - define CONFIGURE_OPTS "" + # Add $argv to CONFIGURE_OPTS, but ignore duplicates and quote if needed + set configure_opts {} foreach arg $autosetup(argv) { - define-append CONFIGURE_OPTS [quote-if-needed $arg] + set quoted [quote-if-needed $arg] + # O(n^2), but n will be small + if {$quoted ni $configure_opts} { + lappend configure_opts $quoted + } } + define CONFIGURE_OPTS [join $configure_opts] define AUTOREMAKE [file-normalize $autosetup(exe)] define-append AUTOREMAKE [get-define CONFIGURE_OPTS] # Log how we were invoked configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]" + configlog "Tclsh: [info nameofexecutable]" - # Note that auto.def is *not* loaded in the global scope - source $autosetup(autodef) + # Load auto.def as module "auto.def" + autosetup_load_module auto.def source $autosetup(autodef) # Could warn here if options {} was not specified @@ -338,8 +348,8 @@ proc opt-str {names varname args} { if {![info exists result]} { # No user-specified value. Has options-defaults been set? foreach opt $names { - if {[dict exists $::autosetup(options-defaults) $opt]} { - set result [dict get $autosetup(options-defaults) $opt] + if {[dict exists $::autosetup(optdefault) $opt]} { + set result [dict get $autosetup(optdefault) $opt] } } } @@ -371,7 +381,7 @@ proc option-check-names {args} { # Parse the option definition in $opts and update # ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately # -proc options-add {opts {header ""}} { +proc options-add {opts} { global autosetup # First weed out comment lines @@ -387,8 +397,7 @@ proc options-add {opts {header ""}} { set opt [lindex $opts $i] if {[string match =* $opt]} { # This is a special heading - lappend autosetup(optionhelp) $opt "" - set header {} + lappend autosetup(optionhelp) [list $opt $autosetup(module)] continue } unset -nocomplain defaultvalue equal value @@ -449,8 +458,8 @@ proc options-add {opts {header ""}} { # String option. lappend autosetup(options) $name - if {$colon eq ":"} { - # Was ":name=default" given? + if {$equal ne "="} { + # Was the option given as "name:value=default"? # If so, set $value to the display name and $defaultvalue to the default # (This is the preferred way to set a default value for a string option) if {[regexp {^([^=]+)=(.*)$} $value -> value defaultvalue]} { @@ -464,9 +473,9 @@ proc options-add {opts {header ""}} { set defaultvalue [dict get $autosetup(options-defaults) $name] dict set autosetup(optdefault) $name $defaultvalue } elseif {![info exists defaultvalue]} { - # For backward compatiblity, if ":name" was given, use name as both - # the display text and the default value, but only if the user - # specified the option without the value + # No default value was given by value=default or options-defaults + # so use the value as the default when the plain option with no + # value is given (.e.g. just --opt instead of --opt=value) set defaultvalue $value } @@ -505,13 +514,8 @@ proc options-add {opts {header ""}} { if {[info exists defaultvalue]} { set desc [string map [list @default@ $defaultvalue] $desc] } - #string match \n* $desc - if {$header ne ""} { - lappend autosetup(optionhelp) $header "" - set header "" - } # A multi-line description - lappend autosetup(optionhelp) $opthelp $desc + lappend autosetup(optionhelp) [list $opthelp $autosetup(module) $desc] incr i 2 } } @@ -519,21 +523,9 @@ proc options-add {opts {header ""}} { # @module-options optionlist # -# Like 'options', but used within a module. +# Deprecated. Simply use 'options' from within a module. proc module-options {opts} { - set header "" - if {$::autosetup(showhelp) > 1 && [llength $opts]} { - set header "Module Options:" - } - options-add $opts $header - - if {$::autosetup(showhelp)} { - # Ensure that the module isn't executed on --help - # We are running under eval or source, so use break - # to prevent further execution - #return -code break -level 2 - return -code break - } + options $opts } proc max {a b} { @@ -562,10 +554,17 @@ proc options-wrap-desc {text length firstprefix nextprefix initial} { } } -proc options-show {} { +# Display options (from $autosetup(optionhelp)) for modules that match +# glob pattern $what +proc options-show {what} { + set local 0 # Determine the max option width set max 0 - foreach {opt desc} $::autosetup(optionhelp) { + foreach help $::autosetup(optionhelp) { + lassign $help opt module desc + if {![string match $what $module]} { + continue + } if {[string match =* $opt] || [string match \n* $desc]} { continue } @@ -578,13 +577,23 @@ proc options-show {} { } incr cols -1 # Now output - foreach {opt desc} $::autosetup(optionhelp) { + foreach help $::autosetup(optionhelp) { + lassign $help opt module desc + if {![string match $what $module]} { + continue + } + if {$local == 0 && $module eq "auto.def"} { + puts "Local Options:" + incr local + } if {[string match =* $opt]} { + # Output a special heading line" puts [string range $opt 1 end] continue } puts -nonewline " [format %-${max}s $opt]" if {[string match \n* $desc]} { + # Output a pre-formatted help description as-is puts $desc } else { options-wrap-desc [string trim $desc] $cols " " $indent [expr $max + 2] @@ -606,12 +615,16 @@ proc options-show {} { # 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: +# An argument option (one which takes a parameter) is of one of the following forms: # -## name:[=]value => "Description of this option" +## name:value => "Description of this option" +## name:value=default => "Description of this option with a default value" +## name:=value => "Description of this option with an optional value" # # 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=default' form is used, the option has the given default value even if not +# specified by the user. +# If the 'name:=value' form is used, the value is optional and the given value is used # if it is not provided. # # The description may contain '@default@', in which case it will be replaced with the default @@ -625,19 +638,22 @@ proc options-show {} { ## lfs=1 largefile=1 => "Disable large file support" # proc options {optlist} { - # Allow options as a list or args - options-add $optlist "Local Options:" + global autosetup - if {$::autosetup(showhelp)} { - options-show - exit 0 + options-add $optlist + + if {$autosetup(showhelp)} { + # If --help, stop now to show help + return -code break } - # Check for invalid options - if {[opt-bool option-checking]} { - foreach o [dict keys $::autosetup(getopt)] { - if {$o ni $::autosetup(options)} { - user-error "Unknown option --$o" + if {$autosetup(module) eq "auto.def"} { + # Check for invalid options + if {[opt-bool option-checking]} { + foreach o [dict keys $::autosetup(getopt)] { + if {$o ni $::autosetup(options)} { + user-error "Unknown option --$o" + } } } } @@ -707,6 +723,9 @@ proc define-append {name args} { if {[get-define $name ""] ne ""} { # Avoid duplicates foreach arg $args { + if {$arg eq ""} { + continue + } set found 0 foreach str [split $::define($name) " "] { if {$str eq $arg} { @@ -745,6 +764,18 @@ proc is-defined {name} { info exists ::define($name) } +# @is-define-set name +# +# Returns 1 if the given variable is defined and is set +# to a value other than "" or 0 +# +proc is-define-set {name} { + if {[get-define $name] in {0 ""}} { + return 0 + } + return 1 +} + # @all-defines # # Returns a dictionary (name, value list) of all defined variables. @@ -1040,7 +1071,6 @@ proc maybe-show-timestamp {} { # 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)" } @@ -1155,8 +1185,9 @@ proc use {args} { continue } set libmodule($m) 1 + if {[info exists modsource(${m}.tcl)]} { - automf_load eval $modsource(${m}.tcl) + autosetup_load_module $m eval $modsource(${m}.tcl) } else { set locs [list ${m}.tcl ${m}/init.tcl] set found 0 @@ -1176,7 +1207,7 @@ proc use {args} { # For the convenience of the "use" source, point to the directory # it is being loaded from set ::usedir [file dirname $source] - automf_load source $source + autosetup_load_module $m source $source autosetup_add_dep $source } else { autosetup-error "use: No such module: $m" @@ -1189,19 +1220,24 @@ 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) + autosetup_load_module $mod eval $modsource($mod) } # Now any external auto modules foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { - automf_load source $file + autosetup_load_module [file tail $file] source $file } } # Load module source in the global scope by executing the given command -proc automf_load {args} { +proc autosetup_load_module {module args} { + global autosetup + set prev $autosetup(module) + set autosetup(module) $module + if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] } + set autosetup(module) $prev } # Initial settings @@ -1213,6 +1249,7 @@ set autosetup(sysinstall) 0 set autosetup(msg-checking) 0 set autosetup(msg-quiet) 0 set autosetup(inittypes) {} +set autosetup(module) autosetup # Embedded modules are inserted below here set autosetup(installed) 1 @@ -1295,7 +1332,7 @@ set modsource(formatting.tcl) { # Module which provides common text formatting -# This is designed for documenation which looks like: +# This is designed for documentation which looks like: # code {...} # or # code { @@ -1418,22 +1455,22 @@ proc autosetup_help {what} { puts "This is [autosetup_version], a build environment \"autoconfigurator\"" puts "See the documentation online at http://msteveb.github.com/autosetup/\n" - if {$what eq "local"} { + if {$what in {all local}} { + # Need to load auto.def now if {[file exists $::autosetup(autodef)]} { - # This relies on auto.def having a call to 'options' - # which will display options and quit - source $::autosetup(autodef) - } else { - options-show + # Load auto.def as module "auto.def" + autosetup_load_module auto.def source $::autosetup(autodef) } - } else { - incr ::autosetup(showhelp) - if {[catch {use $what}]} { - user-error "Unknown module: $what" + if {$what eq "all"} { + set what * } else { - options-show + set what auto.def } + } else { + use $what + puts "Options for module $what:" } + options-show $what exit 0 } @@ -1686,7 +1723,7 @@ set modsource(install.tcl) { # Module which can install autosetup # autosetup(installed)=1 means that autosetup is not running from source -# autosetup(sysinstall)=1 means that autosetup is running from a sysinstall verion +# autosetup(sysinstall)=1 means that autosetup is running from a sysinstall version # 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}} { @@ -1847,7 +1884,7 @@ WRAPPER="$0"; export WRAPPER; "autosetup" "$@" writefile configure \ {#!/bin/sh dir="`dirname "$0"`/autosetup" -WRAPPER="$0"; export WRAPPER; exec "`$dir/autosetup-find-tclsh`" "$dir/autosetup" "$@" +WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@" } } catch {exec chmod 755 configure} @@ -2344,6 +2381,16 @@ proc prefix {pre list} { } return $result } + +# @lpop list +# +# Removes the last entry from the given list and returns it. +proc lpop {listname} { + upvar $listname list + set val [lindex $list end] + set list [lrange $list 0 end-1] + return $val +} } # ----- @module wiki-formatting.tcl ----- diff --git a/autosetup/autosetup-config.guess b/autosetup/autosetup-config.guess index 6c32c8645..256083a70 100755 --- a/autosetup/autosetup-config.guess +++ b/autosetup/autosetup-config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2014-11-04' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2014-11-04' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2014-11-04' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +149,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -168,21 +175,31 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -197,44 +214,67 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in os=netbsd ;; esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -251,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -319,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -346,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + eval "$set_cc_for_build" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -386,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -415,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -461,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -503,17 +534,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -530,7 +561,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -542,14 +573,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -560,7 +591,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -574,7 +605,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -583,18 +614,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -609,28 +640,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -663,13 +694,13 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -680,23 +711,23 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -721,11 +752,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -734,7 +765,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -742,9 +773,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -769,127 +800,109 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -902,58 +915,64 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -967,64 +986,70 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1038,34 +1063,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1075,12 +1100,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1090,9 +1115,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1100,7 +1125,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1112,9 +1137,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1134,9 +1159,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1145,28 +1170,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1177,7 +1202,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1197,23 +1222,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1232,46 +1257,56 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub @@ -1282,27 +1317,33 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1311,18 +1352,18 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1343,14 +1384,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1359,34 +1400,48 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp @@ -1405,16 +1460,16 @@ hostinfo = `(hostinfo) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/autosetup/autosetup-config.sub b/autosetup/autosetup-config.sub index 7ffe37378..9ccf09a7a 100755 --- a/autosetup/autosetup-config.sub +++ b/autosetup/autosetup-config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2014-12-03' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2014-12-03' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2014-12-03' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,12 +53,11 @@ timestamp='2014-12-03' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -68,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -95,7 +94,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -113,24 +112,24 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -179,44 +178,44 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -228,10 +227,7 @@ case $os in os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -255,15 +251,16 @@ case $basic_machine in | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ + | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ - | i370 | i860 | i960 | ia64 \ + | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ @@ -299,13 +296,14 @@ case $basic_machine in | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ @@ -314,7 +312,7 @@ case $basic_machine in | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ - | we32k \ + | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -335,7 +333,7 @@ case $basic_machine in basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown @@ -364,7 +362,7 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -376,17 +374,18 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ @@ -427,13 +426,15 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ + | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ @@ -442,6 +443,7 @@ case $basic_machine in | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ + | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -455,7 +457,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -489,7 +491,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -518,6 +520,9 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -531,7 +536,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -539,13 +544,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -634,10 +639,18 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -727,9 +740,6 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -742,26 +752,26 @@ case $basic_machine in basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -780,19 +790,16 @@ case $basic_machine in os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -824,10 +831,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -846,7 +853,7 @@ case $basic_machine in os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -888,7 +895,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -933,6 +940,12 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -965,7 +978,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -981,7 +994,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -996,16 +1009,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1015,23 +1028,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1085,17 +1098,10 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1114,7 +1120,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1236,6 +1242,9 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1244,20 +1253,12 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1286,10 +1287,6 @@ case $basic_machine in vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1299,9 +1296,6 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1321,7 +1315,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1329,10 +1323,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1343,8 +1337,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases that might get confused + # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux @@ -1355,45 +1349,48 @@ case $os in -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1410,12 +1407,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1424,10 +1421,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1438,12 +1435,6 @@ case $os in -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1468,7 +1459,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1490,7 +1481,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1505,32 +1496,38 @@ case $os in -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; + -ios) + ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1620,12 +1617,12 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + pru-*) + os=-elf + ;; *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1665,7 +1662,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1680,9 +1677,6 @@ case $basic_machine in i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1792,15 +1786,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/autosetup/autosetup-test-tclsh b/autosetup/autosetup-test-tclsh old mode 100755 new mode 100644 diff --git a/autosetup/cc-db.tcl b/autosetup/cc-db.tcl index 5dadbafa3..12f1aed2c 100644 --- a/autosetup/cc-db.tcl +++ b/autosetup/cc-db.tcl @@ -8,7 +8,7 @@ use cc -module-options {} +options {} # openbsd needs sys/types.h to detect some system headers cc-include-needs sys/socket.h sys/types.h diff --git a/autosetup/cc-lib.tcl b/autosetup/cc-lib.tcl index c4b45bcae..45a3b0d3c 100644 --- a/autosetup/cc-lib.tcl +++ b/autosetup/cc-lib.tcl @@ -7,12 +7,10 @@ use cc -module-options {} - # @cc-check-lfs # # The equivalent of the 'AC_SYS_LARGEFILE' macro. -# +# # defines 'HAVE_LFS' if LFS is available, # and defines '_FILE_OFFSET_BITS=64' if necessary # @@ -38,7 +36,7 @@ proc cc-check-lfs {} { # @cc-check-endian # # 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. # diff --git a/autosetup/cc-shared.tcl b/autosetup/cc-shared.tcl index 9540d1979..cbe568018 100644 --- a/autosetup/cc-shared.tcl +++ b/autosetup/cc-shared.tcl @@ -9,23 +9,26 @@ ## SH_CFLAGS Flags to use compiling sources destined for a shared library ## SH_LDFLAGS Flags to use linking (creating) a shared library ## SH_SOPREFIX Prefix to use to set the soname when creating a shared library +## SH_SOFULLPATH Set to 1 if the shared library soname should include the full install path ## SH_SOEXT Extension for shared libs ## SH_SOEXTVER Format for versioned shared libs - %s = version ## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object ## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed ## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved +## SH_LINKRPATH Format for setting the rpath when linking an executable, %s = path ## SH_LINKFLAGS Flags to use linking an executable which will load shared objects ## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries ## STRIPLIBFLAGS Arguments to strip a dynamic library -module-options {} +options {} # Defaults: gcc on unix -define SHOBJ_CFLAGS -fpic +define SHOBJ_CFLAGS -fPIC define SHOBJ_LDFLAGS -shared -define SH_CFLAGS -fpic +define SH_CFLAGS -fPIC define SH_LDFLAGS -shared define SH_LINKFLAGS -rdynamic +define SH_LINKRPATH "-Wl,-rpath -Wl,%s" define SH_SOEXT .so define SH_SOEXTVER .so.%s define SH_SOPREFIX -Wl,-soname, @@ -46,6 +49,7 @@ switch -glob -- [get-define host] { define SH_SOEXT .dylib define SH_SOEXTVER .%s.dylib define SH_SOPREFIX -Wl,-install_name, + define SH_SOFULLPATH define LD_LIBRARY_PATH DYLD_LIBRARY_PATH define STRIPLIBFLAGS -x } @@ -54,6 +58,7 @@ switch -glob -- [get-define host] { define SHOBJ_LDFLAGS -shared define SH_CFLAGS "" define SH_LDFLAGS -shared + define SH_LINKRPATH "" define SH_LINKFLAGS "" define SH_SOEXT .dll define SH_SOEXTVER .dll @@ -64,23 +69,19 @@ switch -glob -- [get-define host] { if {[msg-quiet cc-check-decls __SUNPRO_C]} { msg-result "Found sun stdio compiler" # sun stdio compiler - # XXX: These haven't been fully tested. + # XXX: These haven't been fully tested. define SHOBJ_CFLAGS -KPIC define SHOBJ_LDFLAGS "-G" define SH_CFLAGS -KPIC define SH_LINKFLAGS -Wl,-export-dynamic define SH_SOPREFIX -Wl,-h, - } else { - # sparc has a very small GOT table limit, so use -fPIC - define SH_CFLAGS -fPIC - define SHOBJ_CFLAGS -fPIC } } *-*-solaris* { if {[msg-quiet cc-check-decls __SUNPRO_C]} { msg-result "Found sun stdio compiler" # sun stdio compiler - # XXX: These haven't been fully tested. + # XXX: These haven't been fully tested. define SHOBJ_CFLAGS -KPIC define SHOBJ_LDFLAGS "-G" define SH_CFLAGS -KPIC @@ -105,11 +106,6 @@ switch -glob -- [get-define host] { define SH_SOPREFIX "" define LD_LIBRARY_PATH LIBRARY_PATH } - microblaze* { - # Microblaze generally needs -fPIC rather than -fpic - define SHOBJ_CFLAGS -fPIC - define SH_CFLAGS -fPIC - } } if {![is-defined SHOBJ_LDFLAGS_R]} { diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl index 50a2d4452..750ce92d0 100644 --- a/autosetup/cc.tcl +++ b/autosetup/cc.tcl @@ -11,6 +11,7 @@ # ## CC - C compiler ## CXX - C++ compiler +## CPP - C preprocessor ## CCACHE - Set to "none" to disable automatic use of ccache ## CFLAGS - Additional C compiler flags ## CXXFLAGS - Additional C++ compiler flags @@ -28,7 +29,7 @@ use system -module-options {} +options {} # Checks for the existence of the given function by linking # @@ -213,7 +214,7 @@ proc cc-check-members {args} { # These libraries are not automatically added to 'LIBS'. # # Returns 1 if found or 0 if not. -# +# proc cc-check-function-in-lib {function libs {otherlibs {}}} { msg-checking "Checking libs for $function..." set found 0 @@ -434,7 +435,7 @@ proc cc-with {settings args} { } # @cctest ?settings? -# +# # 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. # @@ -465,7 +466,6 @@ proc cc-with {settings args} { # Any failures are recorded in 'config.log' # proc cctest {args} { - set src conftest__.c set tmp conftest__ # Easiest way to merge in the settings @@ -507,9 +507,11 @@ proc cctest {args} { lappend cmdline {*}[get-define CCACHE] switch -exact -- $opts(-lang) { c++ { + set src conftest__.cpp lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS] } c { + set src conftest__.c lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS] } default { @@ -678,11 +680,11 @@ if {[get-define CC] eq ""} { define CPP [get-env CPP "[get-define CC] -E"] # XXX: Could avoid looking for a C++ compiler until requested -# Note that if CXX isn't found, we just set it to "false". It might not be needed. +# If CXX isn't found, it is set to the empty string. if {[env-is-set CXX]} { define CXX [find-an-executable -required [get-env CXX ""]] } else { - define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++ false] + define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] } # CXXFLAGS default to CFLAGS if not specified @@ -697,6 +699,15 @@ if {[get-define CC] eq ""} { define CCACHE [find-an-executable [get-env CCACHE ccache]] +# If any of these are set in the environment, propagate them to the AUTOREMAKE commandline +foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { + if {[env-is-set $i]} { + # Note: If the variable is set on the command line, get-env will return that value + # so the command line will continue to override the environment + define-append AUTOREMAKE [quote-if-needed $i=[get-env $i ""]] + } +} + # Initial cctest settings cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} set autosetup(cc-include-deps) {} diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index fc2133fa4..63d459664 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -59,7 +59,7 @@ #define HAVE_UNISTD_H #define HAVE_UMASK #endif -#define JIM_VERSION 77 +#define JIM_VERSION 78 #ifndef JIM_WIN32COMPAT_H #define JIM_WIN32COMPAT_H @@ -129,11 +129,6 @@ DIR *opendir(const char *name); int closedir(DIR *dir); struct dirent *readdir(DIR *dir); -#elif defined(__MINGW32__) - -#include -#define strtod __strtod - #endif #endif @@ -375,6 +370,12 @@ typedef struct Jim_Obj { void *ptr2; } twoPtrValue; + struct { + void *ptr; + int int1; + int int2; + } ptrIntValue; + struct { struct Jim_Var *varPtr; unsigned long callFrameId; @@ -412,11 +413,6 @@ typedef struct Jim_Obj { struct Jim_Obj *varNameObjPtr; struct Jim_Obj *indexObjPtr; } dictSubstValue; - - struct { - void *compre; - unsigned flags; - } regexpValue; struct { int line; int argc; @@ -574,7 +570,7 @@ typedef struct Jim_Interp { 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 + execution. It's set to ~0 while the collection is running as sentinel to avoid to recursive calls via the [collect] command inside finalizers. */ @@ -639,7 +635,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 *filename_template); +JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file); JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); @@ -847,7 +843,7 @@ JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp, - Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr); + Jim_Obj *exprObjPtr); JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr); @@ -904,7 +900,8 @@ JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp); JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp); JIM_EXPORT void Jim_HistoryLoad(const char *filename); JIM_EXPORT void Jim_HistorySave(const char *filename); -JIM_EXPORT char *Jim_HistoryGetline(const char *prompt); +JIM_EXPORT char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt); +JIM_EXPORT void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *commandObj); JIM_EXPORT void Jim_HistoryAdd(const char *line); JIM_EXPORT void Jim_HistoryShow(void); @@ -1054,6 +1051,79 @@ void regfree(regex_t *preg); } #endif +#endif +#ifndef JIM_SIGNAL_H +#define JIM_SIGNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +const char *Jim_SignalId(int sig); + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef JIMIOCOMPAT_H +#define JIMIOCOMPAT_H + + +#include +#include + + +void Jim_SetResultErrno(Jim_Interp *interp, const char *msg); + +int Jim_OpenForWrite(const char *filename, int append); + +int Jim_OpenForRead(const char *filename); + +#if defined(__MINGW32__) + #ifndef STRICT + #define STRICT + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include + #include + #include + + typedef HANDLE pidtype; + #define JIM_BAD_PID INVALID_HANDLE_VALUE + + #define JIM_NO_PID INVALID_HANDLE_VALUE + + + #define WIFEXITED(STATUS) (((STATUS) & 0xff00) == 0) + #define WEXITSTATUS(STATUS) ((STATUS) & 0x00ff) + #define WIFSIGNALED(STATUS) (((STATUS) & 0xff00) != 0) + #define WTERMSIG(STATUS) (((STATUS) >> 8) & 0xff) + #define WNOHANG 1 + + int Jim_Errno(void); + pidtype waitpid(pidtype pid, int *status, int nohang); + + #define HAVE_PIPE + #define pipe(P) _pipe((P), 0, O_NOINHERIT) + +#elif defined(HAVE_UNISTD_H) + #include + #include + #include + #include + + typedef int pidtype; + #define Jim_Errno() errno + #define JIM_BAD_PID -1 + #define JIM_NO_PID 0 + + #ifndef HAVE_EXECVPE + #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) + #endif +#endif + #endif int Jim_bootstrapInit(Jim_Interp *interp) { @@ -1063,11 +1133,15 @@ int Jim_bootstrapInit(Jim_Interp *interp) return Jim_EvalSource(interp, "bootstrap.tcl", 1, "\n" "\n" -"proc package {cmd pkg} {\n" +"proc package {cmd pkg args} {\n" " if {$cmd eq \"require\"} {\n" " foreach path $::auto_path {\n" -" if {[file exists $path/$pkg.tcl]} {\n" -" uplevel #0 [list source $path/$pkg.tcl]\n" +" set pkgpath $path/$pkg.tcl\n" +" if {$path eq \".\"} {\n" +" set pkgpath $pkg.tcl\n" +" }\n" +" if {[file exists $pkgpath]} {\n" +" uplevel #0 [list source $pkgpath]\n" " return\n" " }\n" " }\n" @@ -1374,6 +1448,13 @@ int Jim_stdlibInit(Jim_Interp *interp) return Jim_EvalSource(interp, "stdlib.tcl", 1, "\n" "\n" +"if {![exists -command ref]} {\n" +"\n" +" proc ref {args} {{count 0}} {\n" +" format %08x [incr count]\n" +" }\n" +"}\n" +"\n" "\n" "proc lambda {arglist args} {\n" " tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args\n" @@ -1435,6 +1516,13 @@ int Jim_stdlibInit(Jim_Interp *interp) "\n" "\n" "\n" +"proc defer {script} {\n" +" upvar jim::defer v\n" +" lappend v $script\n" +"}\n" +"\n" +"\n" +"\n" "proc errorInfo {msg {stacktrace \"\"}} {\n" " if {$stacktrace eq \"\"} {\n" "\n" @@ -1666,7 +1754,7 @@ int Jim_tclcompatInit(Jim_Interp *interp) "\n" "\n" "proc popen {cmd {mode r}} {\n" -" lassign [socket pipe] r w\n" +" lassign [pipe] r w\n" " try {\n" " if {[string match \"w*\" $mode]} {\n" " lappend cmd <@$r &\n" @@ -1683,11 +1771,26 @@ int Jim_tclcompatInit(Jim_Interp *interp) " if {$cmd eq \"pid\"} {\n" " return $pids\n" " }\n" +" if {$cmd eq \"getfd\"} {\n" +" $f getfd\n" +" }\n" " if {$cmd eq \"close\"} {\n" " $f close\n" "\n" -" foreach p $pids { os.wait $p }\n" -" return\n" +" set retopts {}\n" +" foreach p $pids {\n" +" lassign [wait $p] status - rc\n" +" if {$status eq \"CHILDSTATUS\"} {\n" +" if {$rc == 0} {\n" +" continue\n" +" }\n" +" set msg \"child process exited abnormally\"\n" +" } else {\n" +" set msg \"child killed: received signal\"\n" +" }\n" +" set retopts [list -code error -errorcode [list $status $p $rc] $msg]\n" +" }\n" +" return {*}$retopts\n" " }\n" " tailcall $f $cmd {*}$args\n" " }\n" @@ -1720,6 +1823,7 @@ int Jim_tclcompatInit(Jim_Interp *interp) "\n" "\n" "\n" +"\n" "proc try {args} {\n" " set catchopts {}\n" " while {[string match -* [lindex $args 0]]} {\n" @@ -1810,11 +1914,15 @@ int Jim_tclcompatInit(Jim_Interp *interp) #if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_SELECT) && defined(HAVE_NETINET_IN_H) && defined(HAVE_NETDB_H) && defined(HAVE_ARPA_INET_H) #include #include +#include #include #include #ifdef HAVE_SYS_UN_H #include #endif +#define HAVE_SOCKETS +#elif defined (__MINGW32__) + #else #define JIM_ANSIC #endif @@ -1849,7 +1957,11 @@ int Jim_tclcompatInit(Jim_Interp *interp) #endif #endif -#define JimCheckStreamError(interp, af) af->fops->error(af) +#ifdef JIM_ANSIC + +#undef HAVE_PIPE +#undef HAVE_SOCKETPAIR +#endif struct AioFile; @@ -1956,6 +2068,15 @@ static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name) } } +static int JimCheckStreamError(Jim_Interp *interp, AioFile *af) +{ + int ret = af->fops->error(af); + if (ret) { + JimAioSetError(interp, af->filename); + } + return ret; +} + static void JimAioDelProc(Jim_Interp *interp, void *privData) { AioFile *af = privData; @@ -2068,6 +2189,16 @@ FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) return af->fp; } +static int aio_cmd_getfd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + fflush(af->fp); + Jim_SetResultInt(interp, fileno(af->fp)); + + return JIM_OK; +} + static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); @@ -2226,7 +2357,7 @@ static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc == 3) { -#if !defined(JIM_ANSIC) && defined(HAVE_SHUTDOWN) +#if defined(HAVE_SOCKETS) && defined(HAVE_SHUTDOWN) static const char * const options[] = { "r", "w", NULL }; enum { OPT_R, OPT_W, }; int option; @@ -2317,6 +2448,7 @@ static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #endif + #ifdef HAVE_FSYNC static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -2450,6 +2582,13 @@ static const jim_subcmd_type aio_command_table[] = { 1, 2, + }, + { "getfd", + NULL, + aio_cmd_getfd, + 0, + 0, + }, { "gets", "?var?", @@ -2624,17 +2763,17 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *fi Jim_IncrRefCount(filename); if (fh == NULL) { -#if !defined(JIM_ANSIC) if (fd >= 0) { +#ifndef JIM_ANSIC fh = fdopen(fd, mode); +#endif } else -#endif fh = fopen(Jim_String(filename), mode); if (fh == NULL) { JimAioSetError(interp, filename); -#if !defined(JIM_ANSIC) +#ifndef JIM_ANSIC if (fd >= 0) { close(fd); } @@ -2648,14 +2787,16 @@ 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; - af->fd = fileno(fh); af->filename = filename; + af->openFlags = openFlags; +#ifndef JIM_ANSIC + af->fd = fileno(fh); #ifdef FD_CLOEXEC if ((openFlags & AIO_KEEPOPEN) == 0) { (void)fcntl(af->fd, F_SETFD, FD_CLOEXEC); } #endif - af->openFlags = openFlags; +#endif af->addr_family = family; af->fops = &stdio_fops; af->ssl = NULL; @@ -2674,7 +2815,6 @@ static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0])) { Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); - if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1])) { Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); Jim_SetResult(interp, objPtr); @@ -2690,46 +2830,26 @@ static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, } #endif - -int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template) +#ifdef HAVE_PIPE +static int JimAioPipeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { -#ifdef HAVE_MKSTEMP - int fd; - mode_t mask; - Jim_Obj *filenameObj; + int p[2]; + static const char *mode[2] = { "r", "w" }; - if (filename_template == NULL) { - const char *tmpdir = getenv("TMPDIR"); - if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) { - tmpdir = "/tmp/"; - } - filenameObj = Jim_NewStringObj(interp, tmpdir, -1); - if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') { - Jim_AppendString(interp, filenameObj, "/", 1); - } - Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1); - } - else { - filenameObj = Jim_NewStringObj(interp, filename_template, -1); + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; } - - mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); - fd = mkstemp(filenameObj->bytes); - umask(mask); - if (fd < 0) { - JimAioSetError(interp, filenameObj); - Jim_FreeNewObj(interp, filenameObj); - return -1; + if (pipe(p) != 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; } - Jim_SetResult(interp, filenameObj); - return fd; -#else - Jim_SetResultString(interp, "platform has no tempfile support", -1); - return -1; -#endif + return JimMakeChannelPair(interp, p, argv[0], "aio.pipe%ld", 0, mode); } +#endif + int Jim_aioInit(Jim_Interp *interp) @@ -2742,9 +2862,12 @@ int Jim_aioInit(Jim_Interp *interp) #endif Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); -#ifndef JIM_ANSIC +#ifdef HAVE_SOCKETS Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); #endif +#ifdef HAVE_PIPE + Jim_CreateCommand(interp, "pipe", JimAioPipeCommand, NULL, NULL); +#endif JimMakeChannel(interp, stdin, -1, NULL, "stdin", 0, "r"); @@ -2828,8 +2951,8 @@ int Jim_readdirInit(Jim_Interp *interp) static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) { - regfree(objPtr->internalRep.regexpValue.compre); - Jim_Free(objPtr->internalRep.regexpValue.compre); + regfree(objPtr->internalRep.ptrIntValue.ptr); + Jim_Free(objPtr->internalRep.ptrIntValue.ptr); } static const Jim_ObjType regexpObjType = { @@ -2848,9 +2971,9 @@ static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned f if (objPtr->typePtr == ®expObjType && - objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) { + objPtr->internalRep.ptrIntValue.ptr && objPtr->internalRep.ptrIntValue.int1 == flags) { - return objPtr->internalRep.regexpValue.compre; + return objPtr->internalRep.ptrIntValue.ptr; } @@ -2872,8 +2995,8 @@ static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned f Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = ®expObjType; - objPtr->internalRep.regexpValue.flags = flags; - objPtr->internalRep.regexpValue.compre = compre; + objPtr->internalRep.ptrIntValue.int1 = flags; + objPtr->internalRep.ptrIntValue.ptr = compre; return compre; } @@ -3335,13 +3458,20 @@ int Jim_regexpInit(Jim_Interp *interp) # define MAXPATHLEN JIM_PATH_LEN # endif -#if defined(__MINGW32__) || defined(_MSC_VER) +#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER) #define ISWINDOWS 1 #else #define ISWINDOWS 0 #endif +#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) + #define STAT_MTIME_US(STAT) ((STAT).st_mtimespec.tv_sec * 1000000ll + (STAT).st_mtimespec.tv_nsec / 1000) +#elif defined(HAVE_STRUCT_STAT_ST_MTIM) + #define STAT_MTIME_US(STAT) ((STAT).st_mtim.tv_sec * 1000000ll + (STAT).st_mtim.tv_nsec / 1000) +#endif + + static const char *JimGetFileType(int mode) { if (S_ISREG(mode)) { @@ -3399,6 +3529,9 @@ static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat AppendStatElement(interp, listObj, "atime", sb->st_atime); AppendStatElement(interp, listObj, "mtime", sb->st_mtime); AppendStatElement(interp, listObj, "ctime", sb->st_ctime); +#ifdef STAT_MTIME_US + AppendStatElement(interp, listObj, "mtimeus", STAT_MTIME_US(*sb)); +#endif Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1)); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1)); @@ -3715,7 +3848,7 @@ static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL); + int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL, 0); if (fd < 0) { return JIM_ERR; @@ -3833,37 +3966,62 @@ static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } +static int JimSetFileTimes(Jim_Interp *interp, const char *filename, jim_wide us) +{ +#ifdef HAVE_UTIMES + struct timeval times[2]; + + times[1].tv_sec = times[0].tv_sec = us / 1000000; + times[1].tv_usec = times[0].tv_usec = us % 1000000; + + if (utimes(filename, times) != 0) { + Jim_SetResultFormatted(interp, "can't set time on \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif +} + static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct stat sb; if (argc == 2) { -#ifdef HAVE_UTIMES - jim_wide newtime; - struct timeval times[2]; - - if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) { + jim_wide secs; + if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) { return JIM_ERR; } + return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000); + } + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_mtime); + return JIM_OK; +} - times[1].tv_sec = times[0].tv_sec = newtime; - times[1].tv_usec = times[0].tv_usec = 0; +#ifdef STAT_MTIME_US +static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct stat sb; - if (utimes(Jim_String(argv[0]), times) != 0) { - Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno)); + if (argc == 2) { + jim_wide us; + if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) { return JIM_ERR; } -#else - Jim_SetResultString(interp, "Not implemented", -1); - return JIM_ERR; -#endif + return JimSetFileTimes(interp, Jim_String(argv[0]), us); } if (file_stat(interp, argv[0], &sb) != JIM_OK) { return JIM_ERR; } - Jim_SetResultInt(interp, sb.st_mtime); + Jim_SetResultInt(interp, STAT_MTIME_US(sb)); return JIM_OK; } +#endif static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -3988,6 +4146,15 @@ static const jim_subcmd_type file_command_table[] = { 2, }, +#ifdef STAT_MTIME_US + { "mtimeus", + "name ?time?", + file_cmd_mtimeus, + 1, + 2, + + }, +#endif { "copy", "?-force? source dest", file_cmd_copy, @@ -4286,83 +4453,22 @@ int Jim_execInit(Jim_Interp *interp) #include #include +#include -#if defined(__MINGW32__) - - #ifndef STRICT - #define STRICT - #endif - #define WIN32_LEAN_AND_MEAN - #include - #include - - typedef HANDLE fdtype; - typedef HANDLE pidtype; - #define JIM_BAD_FD INVALID_HANDLE_VALUE - #define JIM_BAD_PID INVALID_HANDLE_VALUE - #define JimCloseFd CloseHandle - - #define WIFEXITED(STATUS) 1 - #define WEXITSTATUS(STATUS) (STATUS) - #define WIFSIGNALED(STATUS) 0 - #define WTERMSIG(STATUS) 0 - #define WNOHANG 1 - - static fdtype JimFileno(FILE *fh); - static pidtype JimWaitPid(pidtype pid, int *status, int nohang); - static fdtype JimDupFd(fdtype infd); - 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, - fdtype inputId, fdtype outputId, fdtype errorId); - static int JimErrno(void); -#else - #include - #include - #include - #include - - typedef int fdtype; - typedef int pidtype; - #define JimPipe pipe - #define JimErrno() errno - #define JIM_BAD_FD -1 - #define JIM_BAD_PID -1 - #define JimFileno fileno - #define JimReadFd read - #define JimCloseFd close - #define JimWaitPid waitpid - #define JimDupFd dup - #define JimFdOpenForRead(FD) fdopen((FD), "r") - #define JimOpenForRead(NAME) open((NAME), O_RDONLY, 0) - - #ifndef HAVE_EXECVPE - #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) - #endif -#endif +struct WaitInfoTable; -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, - pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr); -static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr); + pidtype **pidArrayPtr, int *inPipePtr, int *outPipePtr, int *errFilePtr); +static void JimDetachPids(struct WaitInfoTable *table, int numPids, const pidtype *pidPtr); static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj); -static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len); -static fdtype JimOpenForWrite(const char *filename, int append); -static int JimRewindFd(fdtype fd); - -static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) -{ - Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError()); -} +static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv); -static const char *JimStrError(void) -{ - return strerror(JimErrno()); -} +#if defined(__MINGW32__) +static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId); +#endif static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) { @@ -4375,10 +4481,10 @@ static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) } } -static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj) +static int JimAppendStreamToString(Jim_Interp *interp, int fd, Jim_Obj *strObj) { char buf[256]; - FILE *fh = JimFdOpenForRead(fd); + FILE *fh = fdopen(fd, "r"); int ret = 0; if (fh == NULL) { @@ -4454,31 +4560,16 @@ static void JimFreeEnv(char **env, char **original_environ) } } -#ifndef jim_ext_signal - -const char *Jim_SignalId(int sig) -{ - static char buf[10]; - snprintf(buf, sizeof(buf), "%d", sig); - return buf; -} - -const char *Jim_SignalName(int sig) -{ - return Jim_SignalId(sig); -} -#endif - -static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj) +static Jim_Obj *JimMakeErrorCode(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj) { - Jim_Obj *errorCode; + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); - if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) { - return JIM_OK; + if (pid == JIM_BAD_PID || pid == JIM_NO_PID) { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, -1)); } - errorCode = Jim_NewListObj(interp, NULL, 0); - - if (WIFEXITED(waitStatus)) { + else if (WIFEXITED(waitStatus)) { Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus))); @@ -4486,14 +4577,17 @@ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, J else { const char *type; const char *action; + const char *signame; if (WIFSIGNALED(waitStatus)) { type = "CHILDKILLED"; action = "killed"; + signame = Jim_SignalId(WTERMSIG(waitStatus)); } else { type = "CHILDSUSP"; action = "suspended"; + signame = "none"; } Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1)); @@ -4503,10 +4597,17 @@ static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, J } Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); - Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1)); - Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, signame, -1)); + } + return errorCode; +} + +static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj) +{ + if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) { + return JIM_OK; } - Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + Jim_SetGlobalVariableStr(interp, "errorCode", JimMakeErrorCode(interp, pid, waitStatus, errStrObj)); return JIM_ERR; } @@ -4519,10 +4620,12 @@ struct WaitInfo int flags; }; + struct WaitInfoTable { struct WaitInfo *info; int size; int used; + int refcount; }; @@ -4534,8 +4637,10 @@ static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData) { struct WaitInfoTable *table = privData; - Jim_Free(table->info); - Jim_Free(table); + if (--table->refcount == 0) { + Jim_Free(table->info); + Jim_Free(table); + } } static struct WaitInfoTable *JimAllocWaitInfoTable(void) @@ -4543,27 +4648,46 @@ static struct WaitInfoTable *JimAllocWaitInfoTable(void) struct WaitInfoTable *table = Jim_Alloc(sizeof(*table)); table->info = NULL; table->size = table->used = 0; + table->refcount = 1; return table; } -static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +static int JimWaitRemove(struct WaitInfoTable *table, pidtype pid) { - fdtype outputId; - fdtype errorId; - pidtype *pidPtr; - int numPids, result; - int child_siginfo = 1; - Jim_Obj *childErrObj; - Jim_Obj *errStrObj; + int i; - if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { - Jim_Obj *listObj; - int i; - argc--; - numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); - if (numPids < 0) { + for (i = 0; i < table->used; i++) { + if (pid == table->info[i].pid) { + if (i != table->used - 1) { + table->info[i] = table->info[table->used - 1]; + } + table->used--; + return 0; + } + } + return -1; +} + +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int outputId; + int errorId; + pidtype *pidPtr; + int numPids, result; + int child_siginfo = 1; + Jim_Obj *childErrObj; + Jim_Obj *errStrObj; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { + Jim_Obj *listObj; + int i; + + argc--; + numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); + if (numPids < 0) { return JIM_ERR; } @@ -4572,7 +4696,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); } Jim_SetResult(interp, listObj); - JimDetachPids(interp, numPids, pidPtr); + JimDetachPids(table, numPids, pidPtr); Jim_Free(pidPtr); return JIM_OK; } @@ -4589,7 +4713,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 (outputId != -1) { if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) { result = JIM_ERR; Jim_SetResultErrno(interp, "error reading from output pipe"); @@ -4604,9 +4728,9 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) result = JIM_ERR; } - if (errorId != JIM_BAD_FD) { + if (errorId != -1) { int ret; - JimRewindFd(errorId); + lseek(errorId, 0, SEEK_SET); ret = JimAppendStreamToString(interp, errorId, errStrObj); if (ret < 0) { Jim_SetResultErrno(interp, "error reading from error pipe"); @@ -4633,6 +4757,50 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return result; } +static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr) +{ + if (JimWaitRemove(table, pid) == 0) { + + waitpid(pid, statusPtr, 0); + return pid; + } + + + return JIM_BAD_PID; +} + +static void JimDetachPids(struct WaitInfoTable *table, int numPids, const pidtype *pidPtr) +{ + int j; + + for (j = 0; j < numPids; j++) { + + int i; + for (i = 0; i < table->used; i++) { + if (pidPtr[j] == table->info[i].pid) { + table->info[i].flags |= WI_DETACHED; + break; + } + } + } +} + +static int JimGetChannelFd(Jim_Interp *interp, const char *name) +{ + Jim_Obj *objv[2]; + + objv[0] = Jim_NewStringObj(interp, name, -1); + objv[1] = Jim_NewStringObj(interp, "getfd", -1); + + if (Jim_EvalObjVector(interp, 2, objv) == JIM_OK) { + jim_wide fd; + if (Jim_GetWide(interp, Jim_GetResult(interp), &fd) == JIM_OK) { + return fd; + } + } + return -1; +} + static void JimReapDetachedPids(struct WaitInfoTable *table) { struct WaitInfo *waitPtr; @@ -4648,7 +4816,7 @@ static void JimReapDetachedPids(struct WaitInfoTable *table) for (count = table->used; count > 0; waitPtr++, count--) { if (waitPtr->flags & WI_DETACHED) { int status; - pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG); + pidtype pid = waitpid(waitPtr->pid, &status, WNOHANG); if (pid == waitPtr->pid) { table->used--; @@ -4662,62 +4830,58 @@ static void JimReapDetachedPids(struct WaitInfoTable *table) } } -static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr) +static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - int i; - - - for (i = 0; i < table->used; i++) { - if (pid == table->info[i].pid) { - - JimWaitPid(pid, statusPtr, 0); + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + int nohang = 0; + pidtype pid; + long pidarg; + int status; + Jim_Obj *errCodeObj; - if (i != table->used - 1) { - table->info[i] = table->info[table->used - 1]; - } - table->used--; - return pid; - } + if (argc == 1) { + JimReapDetachedPids(table); + return JIM_OK; } + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) { + nohang = 1; + } + if (argc != nohang + 2) { + Jim_WrongNumArgs(interp, 1, argv, "?-nohang? ?pid?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[nohang + 1], &pidarg) != JIM_OK) { + return JIM_ERR; + } - return JIM_BAD_PID; -} + pid = waitpid((pidtype)pidarg, &status, nohang ? WNOHANG : 0); -static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr) -{ - int j; - struct WaitInfoTable *table = Jim_CmdPrivData(interp); + errCodeObj = JimMakeErrorCode(interp, pid, status, NULL); - for (j = 0; j < numPids; j++) { + if (pid != JIM_BAD_PID && (WIFEXITED(status) || WIFSIGNALED(status))) { - int i; - for (i = 0; i < table->used; i++) { - if (pidPtr[j] == table->info[i].pid) { - table->info[i].flags |= WI_DETACHED; - break; - } - } + JimWaitRemove(table, pid); } + Jim_SetResult(interp, errCodeObj); + return JIM_OK; } -static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name) +static int Jim_PidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - FILE *fh; - Jim_Obj *fhObj; - - fhObj = Jim_NewStringObj(interp, name, -1); - Jim_IncrRefCount(fhObj); - fh = Jim_AioFilehandle(interp, fhObj); - Jim_DecrRefCount(interp, fhObj); + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } - return fh; + Jim_SetResultInt(interp, (jim_wide)getpid()); + return JIM_OK; } static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr, - fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr) + int *inPipePtr, int *outPipePtr, int *errFilePtr) { pidtype *pidPtr = NULL; /* Points to malloc-ed array holding all * the pids of child processes. */ @@ -4754,35 +4918,36 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** * or NULL if output goes to stdout/pipe. */ const char *error = NULL; /* Holds name of stderr file to pipe to, * or NULL if stderr goes to stderr/pipe. */ - fdtype inputId = JIM_BAD_FD; - fdtype outputId = JIM_BAD_FD; - fdtype errorId = JIM_BAD_FD; - fdtype lastOutputId = JIM_BAD_FD; - fdtype pipeIds[2]; + int inputId = -1; + int outputId = -1; + int errorId = -1; + int lastOutputId = -1; + int pipeIds[2]; int firstArg, lastArg; /* Indexes of first and last arguments in * current command. */ int lastBar; int i; pidtype pid; char **save_environ; +#ifndef __MINGW32__ + char **child_environ; +#endif struct WaitInfoTable *table = Jim_CmdPrivData(interp); char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1)); int arg_count = 0; - JimReapDetachedPids(table); - if (inPipePtr != NULL) { - *inPipePtr = JIM_BAD_FD; + *inPipePtr = -1; } if (outPipePtr != NULL) { - *outPipePtr = JIM_BAD_FD; + *outPipePtr = -1; } if (errFilePtr != NULL) { - *errFilePtr = JIM_BAD_FD; + *errFilePtr = -1; } - pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + pipeIds[0] = pipeIds[1] = -1; cmdCount = 1; lastBar = -1; @@ -4881,100 +5046,103 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** if (input != NULL) { if (inputFile == FILE_TEXT) { - inputId = JimCreateTemp(interp, input, input_len); - if (inputId == JIM_BAD_FD) { + inputId = Jim_MakeTempFile(interp, NULL, 1); + if (inputId == -1) { + goto error; + } + if (write(inputId, input, input_len) != input_len) { + Jim_SetResultErrno(interp, "couldn't write temp file"); + close(inputId); goto error; } + lseek(inputId, 0L, SEEK_SET); } else if (inputFile == FILE_HANDLE) { + int fd = JimGetChannelFd(interp, input); - FILE *fh = JimGetAioFilehandle(interp, input); - - if (fh == NULL) { + if (fd < 0) { goto error; } - inputId = JimDupFd(JimFileno(fh)); + inputId = dup(fd); } else { - inputId = JimOpenForRead(input); - if (inputId == JIM_BAD_FD) { - Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError()); + inputId = Jim_OpenForRead(input); + if (inputId == -1) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, strerror(Jim_Errno())); goto error; } } } else if (inPipePtr != NULL) { - if (JimPipe(pipeIds) != 0) { + if (pipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create input pipe for command"); goto error; } inputId = pipeIds[0]; *inPipePtr = pipeIds[1]; - pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + pipeIds[0] = pipeIds[1] = -1; } if (output != NULL) { if (outputFile == FILE_HANDLE) { - FILE *fh = JimGetAioFilehandle(interp, output); - if (fh == NULL) { + int fd = JimGetChannelFd(interp, output); + if (fd < 0) { goto error; } - fflush(fh); - lastOutputId = JimDupFd(JimFileno(fh)); + lastOutputId = dup(fd); } else { - lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND); - if (lastOutputId == JIM_BAD_FD) { - Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError()); + lastOutputId = Jim_OpenForWrite(output, outputFile == FILE_APPEND); + if (lastOutputId == -1) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, strerror(Jim_Errno())); goto error; } } } else if (outPipePtr != NULL) { - if (JimPipe(pipeIds) != 0) { + if (pipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create output pipe"); goto error; } lastOutputId = pipeIds[1]; *outPipePtr = pipeIds[0]; - pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + pipeIds[0] = pipeIds[1] = -1; } if (error != NULL) { if (errorFile == FILE_HANDLE) { if (strcmp(error, "1") == 0) { - if (lastOutputId != JIM_BAD_FD) { - errorId = JimDupFd(lastOutputId); + if (lastOutputId != -1) { + errorId = dup(lastOutputId); } else { error = "stdout"; } } - if (errorId == JIM_BAD_FD) { - FILE *fh = JimGetAioFilehandle(interp, error); - if (fh == NULL) { + if (errorId == -1) { + int fd = JimGetChannelFd(interp, error); + if (fd < 0) { goto error; } - fflush(fh); - errorId = JimDupFd(JimFileno(fh)); + errorId = dup(fd); } } else { - errorId = JimOpenForWrite(error, errorFile == FILE_APPEND); - if (errorId == JIM_BAD_FD) { - Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError()); + errorId = Jim_OpenForWrite(error, errorFile == FILE_APPEND); + if (errorId == -1) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, strerror(Jim_Errno())); goto error; } } } else if (errFilePtr != NULL) { - errorId = JimCreateTemp(interp, NULL, 0); - if (errorId == JIM_BAD_FD) { + errorId = Jim_MakeTempFile(interp, NULL, 1); + if (errorId == -1) { goto error; } - *errFilePtr = JimDupFd(errorId); + *errFilePtr = dup(errorId); } @@ -4984,23 +5152,31 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** } for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) { int pipe_dup_err = 0; - fdtype origErrorId = errorId; + int origErrorId = errorId; for (lastArg = firstArg; lastArg < arg_count; lastArg++) { - if (arg_array[lastArg][0] == '|') { - if (arg_array[lastArg][1] == '&') { - pipe_dup_err = 1; - } + if (strcmp(arg_array[lastArg], "|") == 0) { break; } + if (strcmp(arg_array[lastArg], "|&") == 0) { + pipe_dup_err = 1; + break; + } + } + + if (lastArg == firstArg) { + Jim_SetResultString(interp, "missing command to exec", -1); + goto error; } + arg_array[lastArg] = NULL; if (lastArg == arg_count) { outputId = lastOutputId; + lastOutputId = -1; } else { - if (JimPipe(pipeIds) != 0) { + if (pipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create pipe"); goto error; } @@ -5021,6 +5197,9 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** goto error; } #else + i = strlen(arg_array[firstArg]); + + child_environ = Jim_GetEnviron(); pid = vfork(); if (pid < 0) { Jim_SetResultErrno(interp, "couldn't fork child process"); @@ -5029,21 +5208,44 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** if (pid == 0) { - if (inputId != -1) dup2(inputId, 0); - if (outputId != -1) dup2(outputId, 1); - if (errorId != -1) dup2(errorId, 2); + if (inputId != -1) { + dup2(inputId, fileno(stdin)); + close(inputId); + } + if (outputId != -1) { + dup2(outputId, fileno(stdout)); + if (outputId != errorId) { + close(outputId); + } + } + if (errorId != -1) { + dup2(errorId, fileno(stderr)); + close(errorId); + } - for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) { - close(i); + if (outPipePtr) { + close(*outPipePtr); + } + if (errFilePtr) { + close(*errFilePtr); + } + if (pipeIds[0] != -1) { + close(pipeIds[0]); + } + if (lastOutputId != -1) { + close(lastOutputId); } (void)signal(SIGPIPE, SIG_DFL); - execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron()); + execvpe(arg_array[firstArg], &arg_array[firstArg], child_environ); + if (write(fileno(stderr), "couldn't exec \"", 15) && + write(fileno(stderr), arg_array[firstArg], i) && + write(fileno(stderr), "\"\n", 2)) { - fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]); + } #ifdef JIM_MAINTAINER { @@ -5072,28 +5274,27 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** errorId = origErrorId; - if (inputId != JIM_BAD_FD) { - JimCloseFd(inputId); + if (inputId != -1) { + close(inputId); } - if (outputId != JIM_BAD_FD) { - JimCloseFd(outputId); - outputId = JIM_BAD_FD; + if (outputId != -1) { + close(outputId); } inputId = pipeIds[0]; - pipeIds[0] = pipeIds[1] = JIM_BAD_FD; + pipeIds[0] = pipeIds[1] = -1; } *pidArrayPtr = pidPtr; cleanup: - if (inputId != JIM_BAD_FD) { - JimCloseFd(inputId); + if (inputId != -1) { + close(inputId); } - if (lastOutputId != JIM_BAD_FD) { - JimCloseFd(lastOutputId); + if (lastOutputId != -1) { + close(lastOutputId); } - if (errorId != JIM_BAD_FD) { - JimCloseFd(errorId); + if (errorId != -1) { + close(errorId); } Jim_Free(arg_array); @@ -5103,28 +5304,28 @@ JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype ** error: - if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) { - JimCloseFd(*inPipePtr); - *inPipePtr = JIM_BAD_FD; + if ((inPipePtr != NULL) && (*inPipePtr != -1)) { + close(*inPipePtr); + *inPipePtr = -1; } - if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) { - JimCloseFd(*outPipePtr); - *outPipePtr = JIM_BAD_FD; + if ((outPipePtr != NULL) && (*outPipePtr != -1)) { + close(*outPipePtr); + *outPipePtr = -1; } - if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) { - JimCloseFd(*errFilePtr); - *errFilePtr = JIM_BAD_FD; + if ((errFilePtr != NULL) && (*errFilePtr != -1)) { + close(*errFilePtr); + *errFilePtr = -1; } - if (pipeIds[0] != JIM_BAD_FD) { - JimCloseFd(pipeIds[0]); + if (pipeIds[0] != -1) { + close(pipeIds[0]); } - if (pipeIds[1] != JIM_BAD_FD) { - JimCloseFd(pipeIds[1]); + if (pipeIds[1] != -1) { + close(pipeIds[1]); } if (pidPtr != NULL) { for (i = 0; i < numPids; i++) { if (pidPtr[i] != JIM_BAD_PID) { - JimDetachPids(interp, 1, &pidPtr[i]); + JimDetachPids(table, 1, &pidPtr[i]); } } Jim_Free(pidPtr); @@ -5156,6 +5357,7 @@ static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, int Jim_execInit(Jim_Interp *interp) { + struct WaitInfoTable *waitinfo; if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) return JIM_ERR; @@ -5163,227 +5365,18 @@ int Jim_execInit(Jim_Interp *interp) (void)signal(SIGPIPE, SIG_IGN); #endif - Jim_CreateCommand(interp, "exec", Jim_ExecCmd, JimAllocWaitInfoTable(), JimFreeWaitInfoTable); + waitinfo = JimAllocWaitInfoTable(); + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, waitinfo, JimFreeWaitInfoTable); + waitinfo->refcount++; + Jim_CreateCommand(interp, "wait", Jim_WaitCommand, waitinfo, JimFreeWaitInfoTable); + Jim_CreateCommand(interp, "pid", Jim_PidCommand, 0, 0); + return JIM_OK; } #if defined(__MINGW32__) -static SECURITY_ATTRIBUTES *JimStdSecAttrs(void) -{ - static SECURITY_ATTRIBUTES secAtts; - - secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); - secAtts.lpSecurityDescriptor = NULL; - secAtts.bInheritHandle = TRUE; - return &secAtts; -} - -static int JimErrno(void) -{ - switch (GetLastError()) { - case ERROR_FILE_NOT_FOUND: return ENOENT; - case ERROR_PATH_NOT_FOUND: return ENOENT; - case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; - case ERROR_ACCESS_DENIED: return EACCES; - case ERROR_INVALID_HANDLE: return EBADF; - case ERROR_BAD_ENVIRONMENT: return E2BIG; - case ERROR_BAD_FORMAT: return ENOEXEC; - case ERROR_INVALID_ACCESS: return EACCES; - case ERROR_INVALID_DRIVE: return ENOENT; - case ERROR_CURRENT_DIRECTORY: return EACCES; - case ERROR_NOT_SAME_DEVICE: return EXDEV; - case ERROR_NO_MORE_FILES: return ENOENT; - case ERROR_WRITE_PROTECT: return EROFS; - case ERROR_BAD_UNIT: return ENXIO; - case ERROR_NOT_READY: return EBUSY; - case ERROR_BAD_COMMAND: return EIO; - case ERROR_CRC: return EIO; - case ERROR_BAD_LENGTH: return EIO; - case ERROR_SEEK: return EIO; - case ERROR_WRITE_FAULT: return EIO; - case ERROR_READ_FAULT: return EIO; - case ERROR_GEN_FAILURE: return EIO; - case ERROR_SHARING_VIOLATION: return EACCES; - case ERROR_LOCK_VIOLATION: return EACCES; - case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE; - case ERROR_HANDLE_DISK_FULL: return ENOSPC; - case ERROR_NOT_SUPPORTED: return ENODEV; - case ERROR_REM_NOT_LIST: return EBUSY; - case ERROR_DUP_NAME: return EEXIST; - case ERROR_BAD_NETPATH: return ENOENT; - case ERROR_NETWORK_BUSY: return EBUSY; - case ERROR_DEV_NOT_EXIST: return ENODEV; - case ERROR_TOO_MANY_CMDS: return EAGAIN; - case ERROR_ADAP_HDW_ERR: return EIO; - case ERROR_BAD_NET_RESP: return EIO; - case ERROR_UNEXP_NET_ERR: return EIO; - case ERROR_NETNAME_DELETED: return ENOENT; - case ERROR_NETWORK_ACCESS_DENIED: return EACCES; - case ERROR_BAD_DEV_TYPE: return ENODEV; - case ERROR_BAD_NET_NAME: return ENOENT; - case ERROR_TOO_MANY_NAMES: return ENFILE; - case ERROR_TOO_MANY_SESS: return EIO; - case ERROR_SHARING_PAUSED: return EAGAIN; - case ERROR_REDIR_PAUSED: return EAGAIN; - case ERROR_FILE_EXISTS: return EEXIST; - case ERROR_CANNOT_MAKE: return ENOSPC; - case ERROR_OUT_OF_STRUCTURES: return ENFILE; - case ERROR_ALREADY_ASSIGNED: return EEXIST; - case ERROR_INVALID_PASSWORD: return EPERM; - case ERROR_NET_WRITE_FAULT: return EIO; - case ERROR_NO_PROC_SLOTS: return EAGAIN; - case ERROR_DISK_CHANGE: return EXDEV; - case ERROR_BROKEN_PIPE: return EPIPE; - case ERROR_OPEN_FAILED: return ENOENT; - case ERROR_DISK_FULL: return ENOSPC; - case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE; - case ERROR_INVALID_TARGET_HANDLE: return EBADF; - case ERROR_INVALID_NAME: return ENOENT; - case ERROR_PROC_NOT_FOUND: return ESRCH; - case ERROR_WAIT_NO_CHILDREN: return ECHILD; - case ERROR_CHILD_NOT_COMPLETE: return ECHILD; - case ERROR_DIRECT_ACCESS_HANDLE: return EBADF; - case ERROR_SEEK_ON_DEVICE: return ESPIPE; - case ERROR_BUSY_DRIVE: return EAGAIN; - case ERROR_DIR_NOT_EMPTY: return EEXIST; - case ERROR_NOT_LOCKED: return EACCES; - case ERROR_BAD_PATHNAME: return ENOENT; - case ERROR_LOCK_FAILED: return EACCES; - case ERROR_ALREADY_EXISTS: return EEXIST; - case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG; - case ERROR_BAD_PIPE: return EPIPE; - case ERROR_PIPE_BUSY: return EAGAIN; - case ERROR_PIPE_NOT_CONNECTED: return EPIPE; - case ERROR_DIRECTORY: return ENOTDIR; - } - return EINVAL; -} - -static int JimPipe(fdtype pipefd[2]) -{ - if (CreatePipe(&pipefd[0], &pipefd[1], NULL, 0)) { - return 0; - } - return -1; -} - -static fdtype JimDupFd(fdtype infd) -{ - fdtype dupfd; - pidtype pid = GetCurrentProcess(); - - if (DuplicateHandle(pid, infd, pid, &dupfd, 0, TRUE, DUPLICATE_SAME_ACCESS)) { - return dupfd; - } - return JIM_BAD_FD; -} - -static int JimRewindFd(fdtype fd) -{ - return SetFilePointer(fd, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ? -1 : 0; -} - -#if 0 -static int JimReadFd(fdtype fd, char *buffer, size_t len) -{ - DWORD num; - - if (ReadFile(fd, buffer, len, &num, NULL)) { - return num; - } - if (GetLastError() == ERROR_HANDLE_EOF || GetLastError() == ERROR_BROKEN_PIPE) { - return 0; - } - return -1; -} -#endif - -static FILE *JimFdOpenForRead(fdtype fd) -{ - return _fdopen(_open_osfhandle((int)fd, _O_RDONLY | _O_TEXT), "r"); -} - -static fdtype JimFileno(FILE *fh) -{ - return (fdtype)_get_osfhandle(_fileno(fh)); -} - -static fdtype JimOpenForRead(const char *filename) -{ - return CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -} - -static fdtype JimOpenForWrite(const char *filename, int append) -{ - 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) -{ - return _fdopen(_open_osfhandle((int)fd, _O_TEXT), "w"); -} - -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); - *status = ret; - CloseHandle(pid); - return pid; -} - -static HANDLE JimCreateTemp(Jim_Interp *interp, const char *contents, int len) -{ - char name[MAX_PATH]; - HANDLE handle; - - if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, "JIM", 0, name)) { - return JIM_BAD_FD; - } - - handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, JimStdSecAttrs(), - CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - goto error; - } - - if (contents != NULL) { - - FILE *fh = JimFdOpenForWrite(JimDupFd(handle)); - if (fh == NULL) { - goto error; - } - - if (fwrite(contents, len, 1, fh) != 1) { - fclose(fh); - goto error; - } - fseek(fh, 0, SEEK_SET); - fclose(fh); - } - return handle; - - error: - Jim_SetResultErrno(interp, "failed to create temp file"); - CloseHandle(handle); - DeleteFile(name); - return JIM_BAD_FD; -} - static int JimWinFindExecutable(const char *originalName, char fullPath[MAX_PATH]) { @@ -5493,11 +5486,11 @@ 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, int inputId, int outputId, int errorId) { STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; - HANDLE hProcess, h; + HANDLE hProcess; char execPath[MAX_PATH]; pidtype pid = JIM_BAD_PID; Jim_Obj *cmdLineObj; @@ -5519,38 +5512,31 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, fdtype inputId, startInfo.hStdOutput= INVALID_HANDLE_VALUE; startInfo.hStdError = INVALID_HANDLE_VALUE; - if (inputId == JIM_BAD_FD) { - if (CreatePipe(&startInfo.hStdInput, &h, JimStdSecAttrs(), 0) != FALSE) { - CloseHandle(h); - } - } else { - DuplicateHandle(hProcess, inputId, hProcess, &startInfo.hStdInput, - 0, TRUE, DUPLICATE_SAME_ACCESS); + if (inputId == -1) { + inputId = _fileno(stdin); } - if (startInfo.hStdInput == JIM_BAD_FD) { + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(inputId), hProcess, &startInfo.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { goto end; } - if (outputId == JIM_BAD_FD) { - startInfo.hStdOutput = CreateFile("NUL:", GENERIC_WRITE, 0, - JimStdSecAttrs(), OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - } else { - DuplicateHandle(hProcess, outputId, hProcess, &startInfo.hStdOutput, - 0, TRUE, DUPLICATE_SAME_ACCESS); + if (outputId == -1) { + outputId = _fileno(stdout); } - if (startInfo.hStdOutput == JIM_BAD_FD) { + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(outputId), hProcess, &startInfo.hStdOutput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { goto end; } - if (errorId == JIM_BAD_FD) { - startInfo.hStdError = CreateFile("NUL:", GENERIC_WRITE, 0, - JimStdSecAttrs(), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } else { - DuplicateHandle(hProcess, errorId, hProcess, &startInfo.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS); + if (errorId == -1) { + errorId = _fileno(stderr); } - if (startInfo.hStdError == JIM_BAD_FD) { + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(errorId), hProcess, &startInfo.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdError == INVALID_HANDLE_VALUE) { goto end; } @@ -5578,46 +5564,19 @@ JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, fdtype inputId, end: Jim_FreeNewObj(interp, cmdLineObj); - if (startInfo.hStdInput != JIM_BAD_FD) { + if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdInput); } - if (startInfo.hStdOutput != JIM_BAD_FD) { + if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdOutput); } - if (startInfo.hStdError != JIM_BAD_FD) { + if (startInfo.hStdError != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdError); } return pid; } -#else - -static int JimOpenForWrite(const char *filename, int append) -{ - return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666); -} -static int JimRewindFd(int fd) -{ - return lseek(fd, 0L, SEEK_SET); -} - -static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) -{ - int fd = Jim_MakeTempFile(interp, NULL); - - if (fd != JIM_BAD_FD) { - unlink(Jim_String(Jim_GetResult(interp))); - if (contents) { - if (write(fd, contents, len) != len) { - Jim_SetResultErrno(interp, "couldn't write temp file"); - close(fd); - return -1; - } - lseek(fd, 0L, SEEK_SET); - } - } - return fd; -} +#else static char **JimOriginalEnviron(void) { @@ -5640,9 +5599,17 @@ static void JimRestoreEnv(char **env) #endif + +#ifdef STRPTIME_NEEDS_XOPEN_SOURCE #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 500 #endif +#endif + + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include @@ -5654,30 +5621,60 @@ static void JimRestoreEnv(char **env) #include #endif +struct clock_options { + int gmt; + const char *format; +}; + +static int parse_clock_options(Jim_Interp *interp, int argc, Jim_Obj *const *argv, struct clock_options *opts) +{ + static const char * const options[] = { "-gmt", "-format", NULL }; + enum { OPT_GMT, OPT_FORMAT, }; + int i; + + for (i = 0; i < argc; i += 2) { + int option; + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_GMT: + if (Jim_GetBoolean(interp, argv[i + 1], &opts->gmt) != JIM_OK) { + return JIM_ERR; + } + break; + case OPT_FORMAT: + opts->format = Jim_String(argv[i + 1]); + break; + } + } + return JIM_OK; +} + static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { char buf[100]; time_t t; - long seconds; - - const char *format = "%a %b %d %H:%M:%S %Z %Y"; + jim_wide seconds; + struct clock_options options = { 0, "%a %b %d %H:%M:%S %Z %Y" }; + struct tm *tm; - if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) { - return -1; + if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) { + return JIM_ERR; } - - if (argc == 3) { - format = Jim_String(argv[2]); + if (argc % 2 == 0) { + return -1; } - - if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) { + if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { return JIM_ERR; } + t = seconds; + tm = options.gmt ? gmtime(&t) : localtime(&t); - if (strftime(buf, sizeof(buf), format, localtime(&t)) == 0) { - Jim_SetResultString(interp, "format string too long", -1); + if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) { + Jim_SetResultString(interp, "format string too long or invalid time", -1); return JIM_ERR; } @@ -5687,27 +5684,49 @@ static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #ifdef HAVE_STRPTIME +static time_t jim_timegm(const struct tm *tm) +{ + int m = tm->tm_mon + 1; + int y = 1900 + tm->tm_year - (m <= 2); + int era = (y >= 0 ? y : y - 399) / 400; + unsigned yoe = (unsigned)(y - era * 400); + unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + tm->tm_mday - 1; + unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + long days = (era * 146097 + (int)doe - 719468); + int secs = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + + return days * 24 * 60 * 60 + secs; +} + static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { char *pt; struct tm tm; - time_t now = time(0); + time_t now = time(NULL); + + struct clock_options options = { 0, NULL }; - if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) { + if (argc % 2 == 0) { return -1; } + if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { + return JIM_ERR; + } + if (options.format == NULL) { + return -1; + } localtime_r(&now, &tm); - pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm); + pt = strptime(Jim_String(argv[0]), options.format, &tm); if (pt == 0 || *pt != 0) { Jim_SetResultString(interp, "Failed to parse time according to format", -1); return JIM_ERR; } - Jim_SetResultInt(interp, mktime(&tm)); + Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm)); return JIM_OK; } @@ -5743,19 +5762,19 @@ static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } static const jim_subcmd_type clock_command_table[] = { - { "seconds", - NULL, - clock_cmd_seconds, - 0, - 0, - - }, { "clicks", NULL, clock_cmd_micros, 0, 0, + }, + { "format", + "seconds ?-format string? ?-gmt boolean?", + clock_cmd_format, + 1, + 5, + }, { "microseconds", NULL, @@ -5771,22 +5790,22 @@ static const jim_subcmd_type clock_command_table[] = { 0, }, - { "format", - "seconds ?-format format?", - clock_cmd_format, - 1, - 3, - - }, #ifdef HAVE_STRPTIME { "scan", - "str -format format", + "str -format format ?-gmt boolean?", clock_cmd_scan, 3, - 3, + 5, }, #endif + { "seconds", + NULL, + clock_cmd_seconds, + 0, + 0, + + }, { NULL } }; @@ -6200,7 +6219,7 @@ static const char *JimCharsetMatch(const char *pattern, int c, int flags) pattern += utf8_tounicode_case(pattern, &start, nocase); if (pattern[0] == '-' && pattern[1]) { - pattern += utf8_tounicode(pattern, &pchar); + pattern++; pattern += utf8_tounicode_case(pattern, &end, nocase); @@ -7795,23 +7814,19 @@ static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc start = pc->tstart; end = pc->tend; - if (start > end) { + len = (end - start) + 1; + if (len < 0) { len = 0; - token = Jim_Alloc(1); - token[0] = '\0'; } - else { - len = (end - start) + 1; - token = Jim_Alloc(len + 1); - if (pc->tt != JIM_TT_ESC) { + token = Jim_Alloc(len + 1); + if (pc->tt != JIM_TT_ESC) { - memcpy(token, start, len); - token[len] = '\0'; - } - else { + memcpy(token, start, len); + token[len] = '\0'; + } + else { - len = JimEscape(token, start, len); - } + len = JimEscape(token, start, len); } return Jim_NewStringObjNoAlloc(interp, token, len); @@ -8010,7 +8025,6 @@ Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) dupPtr->bytes = NULL; } else if (objPtr->length == 0) { - dupPtr->bytes = JimEmptyStringRep; dupPtr->length = 0; dupPtr->typePtr = NULL; @@ -8054,8 +8068,7 @@ 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); + Jim_GetString(objPtr, NULL); } return objPtr->length; } @@ -8065,9 +8078,7 @@ 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); + Jim_GetString(objPtr, NULL); } return objPtr->bytes; } @@ -8089,19 +8100,30 @@ static const Jim_ObjType dictSubstObjType = { JIM_TYPE_NONE, }; -static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) -{ - Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); -} +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); static const Jim_ObjType interpolatedObjType = { "interpolated", FreeInterpolatedInternalRep, - NULL, + DupInterpolatedInternalRep, NULL, JIM_TYPE_NONE, }; +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + + dupPtr->internalRep = srcPtr->internalRep; + + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr); +} + static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); @@ -8168,9 +8190,7 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) objPtr->bytes = JimEmptyStringRep; } else { - objPtr->bytes = Jim_Alloc(len + 1); - memcpy(objPtr->bytes, s, len); - objPtr->bytes[len] = '\0'; + objPtr->bytes = Jim_StrDupLen(s, len); } objPtr->length = len; @@ -8458,8 +8478,6 @@ static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr) int len; const char *str; - SetStringFromAny(interp, strObjPtr); - str = Jim_GetString(strObjPtr, &len); #ifdef JIM_UTF8 @@ -8476,10 +8494,6 @@ static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) const char *str; int len; - if (strObjPtr->typePtr != &stringObjType) { - SetStringFromAny(interp, strObjPtr); - } - str = Jim_GetString(strObjPtr, &len); #ifdef JIM_UTF8 @@ -8498,9 +8512,7 @@ static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr) const char *str; str = Jim_GetString(strObjPtr, &len); - if (len == 0) { - return strObjPtr; - } + #ifdef JIM_UTF8 len *= 2; #endif @@ -8750,9 +8762,7 @@ int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char * return 1; } else { - const char *objStr = Jim_String(objPtr); - - if (strcmp(str, objStr) != 0) + if (strcmp(str, Jim_String(objPtr)) != 0) return 0; if (objPtr->typePtr != &comparedStringObjType) { @@ -8948,7 +8958,7 @@ static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len t->line = line; } -static int JimCountWordTokens(ParseToken *t) +static int JimCountWordTokens(struct ScriptObj *script, ParseToken *t) { int expand = 1; int count = 0; @@ -8960,6 +8970,13 @@ static int JimCountWordTokens(ParseToken *t) expand = -1; t++; } + else { + if (script->missing == ' ') { + + script->missing = '}'; + script->linenr = t[1].line; + } + } } @@ -9031,7 +9048,7 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, i++; } - wordtokens = JimCountWordTokens(tokenlist->list + i); + wordtokens = JimCountWordTokens(script, tokenlist->list + i); if (wordtokens == 0) { @@ -9104,7 +9121,7 @@ int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateChar if (stateCharPtr) { *stateCharPtr = script->missing; } - return (script->missing == ' '); + return script->missing == ' ' || script->missing == '}'; } static int JimParseCheckMissing(Jim_Interp *interp, int ch) @@ -9122,6 +9139,9 @@ static int JimParseCheckMissing(Jim_Interp *interp, int ch) case '{': msg = "missing close-brace"; break; + case '}': + msg = "extra characters after close-brace"; + break; case '"': default: msg = "missing quote"; @@ -9262,7 +9282,6 @@ static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) } } - static void JimVariablesHTValDestructor(void *interp, void *val) { Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr); @@ -9916,15 +9935,12 @@ int Jim_SetGlobalVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objP int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val) { - Jim_Obj *nameObjPtr, *valObjPtr; + Jim_Obj *valObjPtr; int result; - nameObjPtr = Jim_NewStringObj(interp, name, -1); valObjPtr = Jim_NewStringObj(interp, val, -1); - Jim_IncrRefCount(nameObjPtr); Jim_IncrRefCount(valObjPtr); - result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); - Jim_DecrRefCount(interp, nameObjPtr); + result = Jim_SetVariableStr(interp, name, valObjPtr); Jim_DecrRefCount(interp, valObjPtr); return result; } @@ -10237,14 +10253,13 @@ void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); } -void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) { - JIM_NOTUSED(interp); - dupPtr->internalRep.dictSubstValue.varNameObjPtr = - srcPtr->internalRep.dictSubstValue.varNameObjPtr; - dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr; - dupPtr->typePtr = &dictSubstObjType; + dupPtr->internalRep = srcPtr->internalRep; + + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.varNameObjPtr); + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr); } @@ -10296,12 +10311,8 @@ static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr) 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; + if (Jim_EvalExpression(interp, objPtr) == JIM_OK) { + return Jim_GetResult(interp); } return NULL; } @@ -10382,6 +10393,52 @@ static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) return JIM_OK; } +static int JimInvokeDefer(Jim_Interp *interp, int retcode) +{ + Jim_Obj *objPtr; + + + if (Jim_FindHashEntry(&interp->framePtr->vars, "jim::defer") == NULL) { + return retcode; + } + + objPtr = Jim_GetVariableStr(interp, "jim::defer", JIM_NONE); + + if (objPtr) { + int ret = JIM_OK; + int i; + int listLen = Jim_ListLength(interp, objPtr); + Jim_Obj *resultObjPtr; + + Jim_IncrRefCount(objPtr); + + resultObjPtr = Jim_GetResult(interp); + Jim_IncrRefCount(resultObjPtr); + Jim_SetEmptyResult(interp); + + + for (i = listLen; i > 0; i--) { + + Jim_Obj *scriptObjPtr = Jim_ListGetIndex(interp, objPtr, i - 1); + ret = Jim_EvalObj(interp, scriptObjPtr); + if (ret != JIM_OK) { + break; + } + } + + if (ret == JIM_OK || retcode == JIM_ERR) { + + Jim_SetResult(interp, resultObjPtr); + } + else { + retcode = ret; + } + + Jim_DecrRefCount(interp, resultObjPtr); + Jim_DecrRefCount(interp, objPtr); + } + return retcode; +} #define JIM_FCF_FULL 0 #define JIM_FCF_REUSE 1 @@ -10495,6 +10552,8 @@ void Jim_FreeInterp(Jim_Interp *i) for (cf = i->framePtr; cf; cf = cfx) { + + JimInvokeDefer(i, JIM_OK); cfx = cf->parent; JimFreeCallFrame(i, cf, JIM_FCF_FULL); } @@ -10525,6 +10584,7 @@ void Jim_FreeInterp(Jim_Interp *i) printf("Objects still in the free list:\n"); while (objPtr) { const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string"; + Jim_String(objPtr); if (objPtr->bytes && strlen(objPtr->bytes) > 20) { printf("%p (%d) %-10s: '%.20s...'\n", @@ -10945,8 +11005,6 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) jim_wide wideValue; const char *str; - str = Jim_String(objPtr); - #ifdef HAVE_LONG_LONG #define MIN_INT_IN_DOUBLE -(1LL << 53) @@ -10960,8 +11018,9 @@ static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) objPtr->typePtr = &coercedDoubleObjType; return JIM_OK; } - else #endif + str = Jim_String(objPtr); + if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { Jim_FreeIntRep(interp, objPtr); @@ -11554,7 +11613,11 @@ static void ListRemoveDuplicates(Jim_Obj *listObjPtr, int (*comp)(Jim_Obj **lhs, ele[dst] = ele[src]; } - ele[++dst] = ele[src]; + + dst++; + if (dst < listObjPtr->internalRep.listValue.len) { + ele[dst] = ele[src]; + } listObjPtr->internalRep.listValue.len = dst; @@ -12331,7 +12394,7 @@ static const char * const jimReturnCodes[] = { NULL }; -#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes)) +#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes) - 1) static const Jim_ObjType returnCodeObjType = { "return-code", @@ -12384,12 +12447,11 @@ static int JimParseExprIrrational(struct JimParserCtx *pc); static int JimParseExprBoolean(struct JimParserCtx *pc); - - enum { + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, JIM_EXPROP_DIV, JIM_EXPROP_MOD, @@ -12408,28 +12470,10 @@ enum JIM_EXPROP_BITAND, JIM_EXPROP_BITXOR, JIM_EXPROP_BITOR, - - JIM_EXPROP_LOGICAND, - JIM_EXPROP_LOGICAND_LEFT, - JIM_EXPROP_LOGICAND_RIGHT, - - JIM_EXPROP_LOGICOR, - JIM_EXPROP_LOGICOR_LEFT, - JIM_EXPROP_LOGICOR_RIGHT, - - - JIM_EXPROP_TERNARY, - JIM_EXPROP_TERNARY_LEFT, - JIM_EXPROP_TERNARY_RIGHT, - - JIM_EXPROP_COLON, - JIM_EXPROP_COLON_LEFT, - JIM_EXPROP_COLON_RIGHT, - JIM_EXPROP_POW, @@ -12445,8 +12489,7 @@ enum JIM_EXPROP_UNARYPLUS, - JIM_EXPROP_FUNC_FIRST, - JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, + JIM_EXPROP_FUNC_INT, JIM_EXPROP_FUNC_WIDE, JIM_EXPROP_FUNC_ABS, JIM_EXPROP_FUNC_DOUBLE, @@ -12476,46 +12519,44 @@ enum JIM_EXPROP_FUNC_FMOD, }; -struct JimExprState -{ - Jim_Obj **stack; - int stacklen; - int opcode; - int skip; +struct JimExprNode { + int type; + struct Jim_Obj *objPtr; + + struct JimExprNode *left; + struct JimExprNode *right; + struct JimExprNode *ternary; }; typedef struct Jim_ExprOperator { const char *name; - int (*funcop) (Jim_Interp *interp, struct JimExprState * e); + int (*funcop) (Jim_Interp *interp, struct JimExprNode *opnode); unsigned char precedence; unsigned char arity; - unsigned char lazy; + unsigned char attr; unsigned char namelen; } Jim_ExprOperator; -static void ExprPush(struct JimExprState *e, Jim_Obj *obj) -{ - Jim_IncrRefCount(obj); - e->stack[e->stacklen++] = obj; -} +static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr); +static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node); +static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node); -static Jim_Obj *ExprPop(struct JimExprState *e) -{ - return e->stack[--e->stacklen]; -} - -static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprNode *node) { int intresult = 1; - int rc = JIM_OK; - Jim_Obj *A = ExprPop(e); + int rc; double dA, dC = 0; jim_wide wA, wC = 0; + Jim_Obj *A; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_FUNC_INT: case JIM_EXPROP_FUNC_WIDE: case JIM_EXPROP_FUNC_ROUND: @@ -12540,7 +12581,7 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) } } else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_FUNC_INT: case JIM_EXPROP_FUNC_WIDE: wC = dA; @@ -12575,10 +12616,10 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) if (rc == JIM_OK) { if (intresult) { - ExprPush(e, Jim_NewIntObj(interp, wC)); + Jim_SetResultInt(interp, wC); } else { - ExprPush(e, Jim_NewDoubleObj(interp, dC)); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); } } @@ -12595,20 +12636,25 @@ static double JimRandDouble(Jim_Interp *interp) return (double)x / (unsigned long)~0; } -static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprNode *node) { - Jim_Obj *A = ExprPop(e); jim_wide wA; + Jim_Obj *A; + int rc; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } - int rc = Jim_GetWide(interp, A, &wA); + rc = Jim_GetWide(interp, A, &wA); if (rc == JIM_OK) { - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_BITNOT: - ExprPush(e, Jim_NewIntObj(interp, ~wA)); + Jim_SetResultInt(interp, ~wA); break; case JIM_EXPROP_FUNC_SRAND: JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); - ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); break; default: abort(); @@ -12620,25 +12666,29 @@ static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) return rc; } -static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpNone(Jim_Interp *interp, struct JimExprNode *node) { - JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); + JimPanic((node->type != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); - ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); return JIM_OK; } #ifdef JIM_MATH_FUNCTIONS -static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node) { int rc; - Jim_Obj *A = ExprPop(e); double dA, dC; + Jim_Obj *A; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } rc = Jim_GetDouble(interp, A, &dA); if (rc == JIM_OK) { - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_FUNC_SIN: dC = sin(dA); break; @@ -12687,7 +12737,7 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) default: abort(); } - ExprPush(e, Jim_NewDoubleObj(interp, dC)); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); } Jim_DecrRefCount(interp, A); @@ -12697,19 +12747,28 @@ static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) #endif -static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprNode *node) { - Jim_Obj *B = ExprPop(e); - Jim_Obj *A = ExprPop(e); jim_wide wA, wB; - int rc = JIM_ERR; + int rc; + Jim_Obj *A, *B; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } + + rc = JIM_ERR; if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) { jim_wide wC; rc = JIM_OK; - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_LSHIFT: wC = wA << wB; break; @@ -12758,7 +12817,7 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) uB %= S; - if (e->opcode == JIM_EXPROP_ROTR) { + if (node->type == JIM_EXPROP_ROTR) { uB = S - uB; } wC = (unsigned long)(uA << uB) | (uA >> (S - uB)); @@ -12767,8 +12826,7 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) default: abort(); } - ExprPush(e, Jim_NewIntObj(interp, wC)); - + Jim_SetResultInt(interp, wC); } Jim_DecrRefCount(interp, A); @@ -12779,14 +12837,20 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) -static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpBin(Jim_Interp *interp, struct JimExprNode *node) { int rc = JIM_OK; double dA, dB, dC = 0; jim_wide wA, wB, wC = 0; + Jim_Obj *A, *B; - Jim_Obj *B = ExprPop(e); - Jim_Obj *A = ExprPop(e); + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } if ((A->typePtr != &doubleObjType || A->bytes) && (B->typePtr != &doubleObjType || B->bytes) && @@ -12794,7 +12858,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: if (wA == 0 && wB < 0) { @@ -12851,7 +12915,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) } } if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { - switch (e->opcode) { + switch (node->type) { #ifndef JIM_MATH_FUNCTIONS case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: @@ -12923,7 +12987,7 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) int i = Jim_StringCompareObj(interp, A, B, 0); - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_LT: wC = i < 0; goto intresult; @@ -12951,10 +13015,10 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) Jim_DecrRefCount(interp, B); return rc; intresult: - ExprPush(e, Jim_NewIntObj(interp, wC)); + Jim_SetResultInt(interp, wC); goto done; doubleresult: - ExprPush(e, Jim_NewDoubleObj(interp, dC)); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); goto done; } @@ -12972,18 +13036,27 @@ static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valOb return 0; } -static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e) -{ - Jim_Obj *B = ExprPop(e); - Jim_Obj *A = ExprPop(e); + +static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprNode *node) +{ + Jim_Obj *A, *B; jim_wide wC; + int rc; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } - switch (e->opcode) { + switch (node->type) { case JIM_EXPROP_STREQ: case JIM_EXPROP_STRNE: wC = Jim_StringEqObj(A, B); - if (e->opcode == JIM_EXPROP_STRNE) { + if (node->type == JIM_EXPROP_STRNE) { wC = !wC; } break; @@ -12996,12 +13069,12 @@ static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprState *e) default: abort(); } - ExprPush(e, Jim_NewIntObj(interp, wC)); + Jim_SetResultInt(interp, wC); Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); - return JIM_OK; + return rc; } static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) @@ -13009,166 +13082,82 @@ static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) long l; double d; int b; + int ret = -1; + + + Jim_IncrRefCount(obj); if (Jim_GetLong(interp, obj, &l) == JIM_OK) { - return l != 0; + ret = (l != 0); } - if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { - return d != 0; + else if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { + ret = (d != 0); } - if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) { - return b != 0; - } - return -1; -} - -static int JimExprOpAndLeft(Jim_Interp *interp, struct JimExprState *e) -{ - Jim_Obj *skip = ExprPop(e); - Jim_Obj *A = ExprPop(e); - int rc = JIM_OK; - - 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; + else if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) { + ret = (b != 0); } - Jim_DecrRefCount(interp, A); - Jim_DecrRefCount(interp, skip); - return rc; + Jim_DecrRefCount(interp, obj); + return ret; } -static int JimExprOpOrLeft(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpAnd(Jim_Interp *interp, struct JimExprNode *node) { - Jim_Obj *skip = ExprPop(e); - Jim_Obj *A = ExprPop(e); - int rc = JIM_OK; - - switch (ExprBool(interp, A)) { - case 0: - break; - - case 1: - - e->skip = JimWideValue(skip); - ExprPush(e, Jim_NewIntObj(interp, 1)); - break; + int result = JimExprGetTermBoolean(interp, node->left); - case -1: + if (result == 1) { - rc = JIM_ERR; - break; + result = JimExprGetTermBoolean(interp, node->right); } - Jim_DecrRefCount(interp, A); - Jim_DecrRefCount(interp, skip); - - return rc; -} - -static int JimExprOpAndOrRight(Jim_Interp *interp, struct JimExprState *e) -{ - Jim_Obj *A = ExprPop(e); - int rc = JIM_OK; - - switch (ExprBool(interp, A)) { - case 0: - ExprPush(e, Jim_NewIntObj(interp, 0)); - break; - - case 1: - ExprPush(e, Jim_NewIntObj(interp, 1)); - break; - - case -1: - - rc = JIM_ERR; - break; + if (result == -1) { + return JIM_ERR; } - Jim_DecrRefCount(interp, A); - - return rc; + Jim_SetResultInt(interp, result); + return JIM_OK; } -static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpOr(Jim_Interp *interp, struct JimExprNode *node) { - Jim_Obj *skip = ExprPop(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; + int result = JimExprGetTermBoolean(interp, node->left); - case -1: + if (result == 0) { - rc = JIM_ERR; - break; + result = JimExprGetTermBoolean(interp, node->right); } - Jim_DecrRefCount(interp, A); - Jim_DecrRefCount(interp, skip); - - return rc; + if (result == -1) { + return JIM_ERR; + } + Jim_SetResultInt(interp, result); + return JIM_OK; } -static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e) +static int JimExprOpTernary(Jim_Interp *interp, struct JimExprNode *node) { - Jim_Obj *skip = ExprPop(e); - Jim_Obj *B = ExprPop(e); - Jim_Obj *A = ExprPop(e); - - if (ExprBool(interp, A)) { + int result = JimExprGetTermBoolean(interp, node->left); - e->skip = JimWideValue(skip); + if (result == 1) { - ExprPush(e, B); + return JimExprEvalTermNode(interp, node->right); } + else if (result == 0) { - Jim_DecrRefCount(interp, skip); - Jim_DecrRefCount(interp, A); - Jim_DecrRefCount(interp, B); - return JIM_OK; -} + return JimExprEvalTermNode(interp, node->ternary); + } -static int JimExprOpNull(Jim_Interp *interp, struct JimExprState *e) -{ - return JIM_OK; + return JIM_ERR; } enum { - LAZY_NONE, - LAZY_OP, - LAZY_LEFT, - LAZY_RIGHT, - RIGHT_ASSOC, + OP_FUNC = 0x0001, + OP_RIGHT_ASSOC = 0x0002, }; #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) +#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, 0) static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("*", 110, 2, JimExprOpBin), @@ -13196,24 +13185,13 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("^", 49, 2, JimExprOpIntBin), OPRINIT("|", 48, 2, JimExprOpIntBin), - OPRINIT_ATTR("&&", 10, 2, NULL, LAZY_OP), - OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT), - OPRINIT_ATTR(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT), + OPRINIT("&&", 10, 2, JimExprOpAnd), + OPRINIT("||", 9, 2, JimExprOpOr), + OPRINIT_ATTR("?", 5, 3, JimExprOpTernary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(":", 5, 3, NULL, OP_RIGHT_ASSOC), - OPRINIT_ATTR("||", 9, 2, NULL, LAZY_OP), - OPRINIT_ATTR(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT), - OPRINIT_ATTR(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_ATTR(":", 5, 2, JimExprOpNull, LAZY_OP), - OPRINIT_ATTR(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT), - OPRINIT_ATTR(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), - - - OPRINIT_ATTR("**", 120, 2, JimExprOpBin, RIGHT_ASSOC), + OPRINIT_ATTR("**", 120, 2, JimExprOpBin, OP_RIGHT_ASSOC), OPRINIT("eq", 60, 2, JimExprOpStrBin), OPRINIT("ne", 60, 2, JimExprOpStrBin), @@ -13221,45 +13199,45 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("in", 55, 2, JimExprOpStrBin), OPRINIT("ni", 55, 2, JimExprOpStrBin), - OPRINIT("!", 150, 1, JimExprOpNumUnary), - OPRINIT("~", 150, 1, JimExprOpIntUnary), - OPRINIT(NULL, 150, 1, JimExprOpNumUnary), - OPRINIT(NULL, 150, 1, JimExprOpNumUnary), + OPRINIT_ATTR("!", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR("~", 150, 1, JimExprOpIntUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(" -", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(" +", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), - OPRINIT("int", 200, 1, JimExprOpNumUnary), - OPRINIT("wide", 200, 1, JimExprOpNumUnary), - OPRINIT("abs", 200, 1, JimExprOpNumUnary), - OPRINIT("double", 200, 1, JimExprOpNumUnary), - OPRINIT("round", 200, 1, JimExprOpNumUnary), - OPRINIT("rand", 200, 0, JimExprOpNone), - OPRINIT("srand", 200, 1, JimExprOpIntUnary), + OPRINIT_ATTR("int", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("wide", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("abs", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("double", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("round", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("rand", 200, 0, JimExprOpNone, OP_FUNC), + OPRINIT_ATTR("srand", 200, 1, JimExprOpIntUnary, OP_FUNC), #ifdef JIM_MATH_FUNCTIONS - OPRINIT("sin", 200, 1, JimExprOpDoubleUnary), - OPRINIT("cos", 200, 1, JimExprOpDoubleUnary), - OPRINIT("tan", 200, 1, JimExprOpDoubleUnary), - 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), - OPRINIT("ceil", 200, 1, JimExprOpDoubleUnary), - OPRINIT("floor", 200, 1, JimExprOpDoubleUnary), - OPRINIT("exp", 200, 1, JimExprOpDoubleUnary), - OPRINIT("log", 200, 1, JimExprOpDoubleUnary), - 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), + OPRINIT_ATTR("sin", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("cos", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("tan", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("asin", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("acos", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("atan", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("atan2", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("sinh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("cosh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("tanh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("ceil", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("floor", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("exp", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("log", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("log10", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("sqrt", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("pow", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("hypot", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("fmod", 200, 2, JimExprOpBin, OP_FUNC), #endif }; #undef OPRINIT -#undef OPRINIT_LAZY +#undef OPRINIT_ATTR #define JIM_EXPR_OPERATORS_NUM \ (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) @@ -13415,31 +13393,40 @@ static int JimParseExprBoolean(struct JimParserCtx *pc) return JIM_ERR; } +static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) +{ + static Jim_ExprOperator dummy_op; + if (opcode < JIM_TT_EXPR_OP) { + return &dummy_op; + } + return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP]; +} + static int JimParseExprOperator(struct JimParserCtx *pc) { int i; - int bestIdx = -1, bestLen = 0; + const struct Jim_ExprOperator *bestOp = NULL; + int 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; + const struct Jim_ExprOperator *op = &Jim_ExprOperators[i]; - if (opname == NULL || opname[0] != pc->p[0]) { + if (op->name[0] != pc->p[0]) { continue; } - if (oplen > bestLen && strncmp(opname, pc->p, oplen) == 0) { - bestIdx = i + JIM_TT_EXPR_OP; - bestLen = oplen; + if (op->namelen > bestLen && strncmp(op->name, pc->p, op->namelen) == 0) { + bestOp = op; + bestLen = op->namelen; } } - if (bestIdx == -1) { + if (bestOp == NULL) { return JIM_ERR; } - if (bestIdx >= JIM_EXPROP_FUNC_FIRST) { + if (bestOp->attr & OP_FUNC) { const char *p = pc->p + bestLen; int len = pc->len - bestLen; @@ -13455,19 +13442,10 @@ static int JimParseExprOperator(struct JimParserCtx *pc) pc->p += bestLen; pc->len -= bestLen; - pc->tt = bestIdx; + pc->tt = (bestOp - Jim_ExprOperators) + JIM_TT_EXPR_OP; return JIM_OK; } -static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) -{ - static Jim_ExprOperator dummy_op; - if (opcode < JIM_TT_EXPR_OP) { - return &dummy_op; - } - return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP]; -} - const char *jim_tt_name(int type) { static const char * const tt_names[JIM_TT_EXPR_OP] = @@ -13507,34 +13485,41 @@ static const Jim_ObjType exprObjType = { }; -typedef struct ExprByteCode +struct ExprTree { - ScriptToken *token; + struct JimExprNode *expr; + struct JimExprNode *nodes; int len; int inUse; -} ExprByteCode; +}; -static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr) +static void ExprTreeFreeNodes(Jim_Interp *interp, struct JimExprNode *nodes, int num) { int i; - - for (i = 0; i < expr->len; i++) { - Jim_DecrRefCount(interp, expr->token[i].objPtr); + for (i = 0; i < num; i++) { + if (nodes[i].objPtr) { + Jim_DecrRefCount(interp, nodes[i].objPtr); + } } - Jim_Free(expr->token); + Jim_Free(nodes); +} + +static void ExprTreeFree(Jim_Interp *interp, struct ExprTree *expr) +{ + ExprTreeFreeNodes(interp, expr->nodes, expr->len); Jim_Free(expr); } static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) { - ExprByteCode *expr = (void *)objPtr->internalRep.ptr; + struct ExprTree *expr = (void *)objPtr->internalRep.ptr; if (expr) { if (--expr->inUse != 0) { return; } - ExprFreeByteCode(interp, expr); + ExprTreeFree(interp, expr); } } @@ -13547,260 +13532,142 @@ static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dup dupPtr->typePtr = NULL; } -static int ExprCheckCorrectness(Jim_Interp *interp, Jim_Obj *exprObjPtr, ExprByteCode * expr) +struct ExprBuilder { + int parencount; + int level; + ParseToken *token; + ParseToken *first_token; + Jim_Stack stack; + Jim_Obj *exprObjPtr; + Jim_Obj *fileNameObj; + struct JimExprNode *nodes; + struct JimExprNode *next; +}; + +#ifdef DEBUG_SHOW_EXPR +static void JimShowExprNode(struct JimExprNode *node, int level) { 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; - } - if (t->type == JIM_EXPROP_TERNARY || t->type == JIM_EXPROP_TERNARY_LEFT) { - ternary++; - } - else if (t->type == JIM_EXPROP_COLON || t->type == JIM_EXPROP_COLON_LEFT) { - ternary--; - } - - - stacklen++; - } - if (stacklen == 1 && ternary == 0) { - return JIM_OK; + for (i = 0; i < level; i++) { + printf(" "); } - - 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"; + if (TOKEN_IS_EXPR_OP(node->type)) { + printf("%s\n", jim_tt_name(node->type)); + if (node->left) { + JimShowExprNode(node->left, level + 1); } - } - 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"; + if (node->right) { + JimShowExprNode(node->right, level + 1); + } + if (node->ternary) { + JimShowExprNode(node->ternary, level + 1); } } else { - errmsg = "invalid ternary expression"; + printf("[%s] %s\n", jim_tt_name(node->type), Jim_String(node->objPtr)); } - Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": %s", exprObjPtr, errmsg); - return JIM_ERR; } +#endif -static int ExprAddLazyOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) -{ - int i; - - int leftindex, arity, offset; - - - leftindex = expr->len - 1; - - arity = 1; - while (arity) { - ScriptToken *tt = &expr->token[leftindex]; - - if (tt->type >= JIM_TT_EXPR_OP) { - arity += JimExprOperatorInfoByOpcode(tt->type)->arity; - } - arity--; - if (--leftindex < 0) { - return JIM_ERR; - } - } - leftindex++; - - - memmove(&expr->token[leftindex + 2], &expr->token[leftindex], - sizeof(*expr->token) * (expr->len - leftindex)); - expr->len += 2; - offset = (expr->len - leftindex) - 1; - - expr->token[leftindex + 1].type = t->type + 1; - expr->token[leftindex + 1].objPtr = interp->emptyObj; - - 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) { - if (JimWideValue(expr->token[i - 1].objPtr) + i - 1 >= leftindex) { - JimWideValue(expr->token[i - 1].objPtr) += 2; - } - } - } - return JIM_OK; -} +#define EXPR_UNTIL_CLOSE 0x0001 +#define EXPR_FUNC_ARGS 0x0002 +#define EXPR_TERNARY 0x0004 -static int ExprAddOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms) { - struct ScriptToken *token = &expr->token[expr->len]; - const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + int rc; + struct JimExprNode *node; - if (op->lazy == LAZY_OP) { - if (ExprAddLazyOperator(interp, expr, t) != JIM_OK) { - Jim_SetResultFormatted(interp, "Expression has bad operands to %s", op->name); - return JIM_ERR; - } - } - else { - token->objPtr = interp->emptyObj; - token->type = t->type; - expr->len++; - } - return JIM_OK; -} + int exp_stacklen = builder->stack.len + exp_numterms; -static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index) -{ - int ternary_count = 1; + if (builder->level++ > 200) { + Jim_SetResultString(interp, "Expression too complex", -1); + return JIM_ERR; + } - right_index--; + while (builder->token->type != JIM_TT_EOL) { + ParseToken *t = builder->token++; + int prevtt; - while (right_index > 1) { - if (expr->token[right_index].type == JIM_EXPROP_TERNARY_LEFT) { - ternary_count--; - } - else if (expr->token[right_index].type == JIM_EXPROP_COLON_RIGHT) { - ternary_count++; + if (t == builder->first_token) { + prevtt = JIM_TT_NONE; } - else if (expr->token[right_index].type == JIM_EXPROP_COLON_LEFT && ternary_count == 1) { - return right_index; + else { + prevtt = t[-1].type; } - right_index--; - } - - return -1; -} - -static int ExprTernaryGetMoveIndices(ExprByteCode *expr, int right_index, int *prev_right_index, int *prev_left_index) -{ - int i = right_index - 1; - int ternary_count = 1; - - while (i > 1) { - if (expr->token[i].type == JIM_EXPROP_TERNARY_LEFT) { - if (--ternary_count == 0 && expr->token[i - 2].type == JIM_EXPROP_COLON_RIGHT) { - *prev_right_index = i - 2; - *prev_left_index = ExprTernaryGetColonLeftIndex(expr, *prev_right_index); - return 1; + if (t->type == JIM_TT_SUBEXPR_START) { + if (builder->stack.len == exp_stacklen) { + Jim_SetResultFormatted(interp, "unexpected open parenthesis in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; } - } - else if (expr->token[i].type == JIM_EXPROP_COLON_RIGHT) { - if (ternary_count == 0) { - return 0; + builder->parencount++; + rc = ExprTreeBuildTree(interp, builder, 0, EXPR_UNTIL_CLOSE, 1); + if (rc != JIM_OK) { + return rc; } - ternary_count++; - } - i--; - } - return 0; -} - -static void ExprTernaryReorderExpression(Jim_Interp *interp, ExprByteCode *expr) -{ - int i; - for (i = expr->len - 1; i > 1; i--) { - int prev_right_index; - int prev_left_index; - int j; - ScriptToken tmp; - - if (expr->token[i].type != JIM_EXPROP_COLON_RIGHT) { - continue; - } - - - if (ExprTernaryGetMoveIndices(expr, i, &prev_right_index, &prev_left_index) == 0) { - continue; } + else if (t->type == JIM_TT_SUBEXPR_END) { + if (!(flags & EXPR_UNTIL_CLOSE)) { + if (builder->stack.len == exp_stacklen && builder->level > 1) { + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, "unexpected closing parenthesis in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + builder->parencount--; + if (builder->stack.len == exp_stacklen) { - tmp = expr->token[prev_right_index]; - for (j = prev_right_index; j < i; j++) { - expr->token[j] = expr->token[j + 1]; + break; + } } - expr->token[i] = tmp; - - JimWideValue(expr->token[prev_left_index-1].objPtr) += (i - prev_right_index); - - - i++; - } -} - -static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj) -{ - Jim_Stack stack; - ExprByteCode *expr; - int ok = 1; - int i; - int prevtt = JIM_TT_NONE; - int have_ternary = 0; - - - int count = tokenlist->count - 1; - - expr = Jim_Alloc(sizeof(*expr)); - expr->inUse = 1; - expr->len = 0; - - Jim_InitStack(&stack); - - for (i = 0; i < tokenlist->count; i++) { - ParseToken *t = &tokenlist->list[i]; - const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + else if (t->type == JIM_TT_SUBEXPR_COMMA) { + if (!(flags & EXPR_FUNC_ARGS)) { + if (builder->stack.len == exp_stacklen) { - if (op->lazy == LAZY_OP) { - count += 2; - - if (t->type == JIM_EXPROP_TERNARY) { - have_ternary = 1; + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, "unexpected comma in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; } - } - } + else { - expr->token = Jim_Alloc(sizeof(ScriptToken) * count); + if (builder->stack.len > exp_stacklen) { + Jim_SetResultFormatted(interp, "too many arguments to math function"); + return JIM_ERR; + } + } - for (i = 0; i < tokenlist->count && ok; i++) { - ParseToken *t = &tokenlist->list[i]; + } + else if (t->type == JIM_EXPROP_COLON) { + if (!(flags & EXPR_TERNARY)) { + if (builder->level != 1) { + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, ": without ? in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + if (builder->stack.len == exp_stacklen) { - struct ScriptToken *token = &expr->token[expr->len]; + builder->token--; + builder->level--; + return JIM_OK; + } - if (t->type == JIM_TT_EOL) { - break; } - - if (TOKEN_IS_EXPR_OP(t->type)) { + else if (TOKEN_IS_EXPR_OP(t->type)) { const struct Jim_ExprOperator *op; - ParseToken *tt; - if (prevtt == JIM_TT_NONE || prevtt == JIM_TT_SUBEXPR_START || prevtt == JIM_TT_SUBEXPR_COMMA || prevtt >= JIM_TT_EXPR_OP) { + if (TOKEN_IS_EXPR_OP(prevtt) || TOKEN_IS_EXPR_START(prevtt)) { if (t->type == JIM_EXPROP_SUB) { t->type = JIM_EXPROP_UNARYMINUS; } @@ -13811,66 +13678,82 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList op = JimExprOperatorInfoByOpcode(t->type); + if (op->precedence < precedence || (!(op->attr & OP_RIGHT_ASSOC) && op->precedence == precedence)) { - while ((tt = Jim_StackPeek(&stack)) != NULL) { - const struct Jim_ExprOperator *tt_op = - JimExprOperatorInfoByOpcode(tt->type); - - - if (op->arity != 1 && tt_op->precedence >= op->precedence) { + builder->token--; + break; + } - 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 (op->attr & OP_FUNC) { + if (builder->token->type != JIM_TT_SUBEXPR_START) { + Jim_SetResultString(interp, "missing arguments for math function", -1); + return JIM_ERR; } - else { - break; + builder->token++; + if (op->arity == 0) { + if (builder->token->type != JIM_TT_SUBEXPR_END) { + Jim_SetResultString(interp, "too many arguments for math function", -1); + return JIM_ERR; + } + builder->token++; + goto noargs; } + builder->parencount++; + + + rc = ExprTreeBuildTree(interp, builder, 0, EXPR_FUNC_ARGS | EXPR_UNTIL_CLOSE, op->arity); } - 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) { + else if (t->type == JIM_EXPROP_TERNARY) { - ok = 0; - while (Jim_StackLen(&stack)) { - ParseToken *tt = Jim_StackPop(&stack); + rc = ExprTreeBuildTree(interp, builder, op->precedence, EXPR_TERNARY, 2); + } + else { + rc = ExprTreeBuildTree(interp, builder, op->precedence, 0, 1); + } - if (tt->type == JIM_TT_SUBEXPR_START || tt->type == JIM_TT_SUBEXPR_COMMA) { - if (t->type == JIM_TT_SUBEXPR_COMMA) { + if (rc != JIM_OK) { + return rc; + } - Jim_StackPush(&stack, tt); - } - ok = 1; - break; +noargs: + node = builder->next++; + node->type = t->type; + + if (op->arity >= 3) { + node->ternary = Jim_StackPop(&builder->stack); + if (node->ternary == NULL) { + goto missingoperand; } - if (ExprAddOperator(interp, expr, tt) != JIM_OK) { - goto err; + } + if (op->arity >= 2) { + node->right = Jim_StackPop(&builder->stack); + if (node->right == NULL) { + goto missingoperand; } } - if (!ok) { - Jim_SetResultFormatted(interp, "Unexpected close parenthesis in expression: \"%#s\"", exprObjPtr); - goto err; + if (op->arity >= 1) { + node->left = Jim_StackPop(&builder->stack); + if (node->left == NULL) { +missingoperand: + Jim_SetResultFormatted(interp, "missing operand to %s in expression: \"%#s\"", op->name, builder->exprObjPtr); + builder->next--; + return JIM_ERR; + + } } + + + Jim_StackPush(&builder->stack, node); } else { Jim_Obj *objPtr = NULL; - token->type = t->type; if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) { - Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", exprObjPtr); - ok = 0; - goto err; + Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; } @@ -13889,64 +13772,103 @@ static ExprByteCode *ExprCreateByteCode(Jim_Interp *interp, const ParseTokenList } } - if (objPtr) { - token->objPtr = objPtr; - } - else { + if (!objPtr) { - token->objPtr = Jim_NewStringObj(interp, t->token, t->len); + objPtr = Jim_NewStringObj(interp, t->token, t->len); if (t->type == JIM_TT_CMD) { - JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); + JimSetSourceInfo(interp, objPtr, builder->fileNameObj, t->line); } } - expr->len++; + + + node = builder->next++; + node->objPtr = objPtr; + Jim_IncrRefCount(node->objPtr); + node->type = t->type; + Jim_StackPush(&builder->stack, node); } - prevtt = t->type; } + if (builder->stack.len == exp_stacklen) { + builder->level--; + return JIM_OK; + } - while (Jim_StackLen(&stack)) { - ParseToken *tt = Jim_StackPop(&stack); - - if (tt->type == JIM_TT_SUBEXPR_START) { - ok = 0; - Jim_SetResultString(interp, "Missing close parenthesis", -1); - goto err; + if ((flags & EXPR_FUNC_ARGS)) { + Jim_SetResultFormatted(interp, "too %s arguments for math function", (builder->stack.len < exp_stacklen) ? "few" : "many"); + } + else { + if (builder->stack.len < exp_stacklen) { + if (builder->level == 0) { + Jim_SetResultFormatted(interp, "empty expression"); + } + else { + Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": premature end of expression", builder->exprObjPtr); + } } - if (ExprAddOperator(interp, expr, tt) != JIM_OK) { - ok = 0; - goto err; + else { + Jim_SetResultFormatted(interp, "extra terms after expression"); } } - if (have_ternary) { - ExprTernaryReorderExpression(interp, expr); - } + return JIM_ERR; +} - err: +static struct ExprTree *ExprTreeCreateTree(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj) +{ + struct ExprTree *expr; + struct ExprBuilder builder; + int rc; + struct JimExprNode *top = NULL; + + builder.parencount = 0; + builder.level = 0; + builder.token = builder.first_token = tokenlist->list; + builder.exprObjPtr = exprObjPtr; + builder.fileNameObj = fileNameObj; + + builder.nodes = malloc(sizeof(struct JimExprNode) * (tokenlist->count - 1)); + memset(builder.nodes, 0, sizeof(struct JimExprNode) * (tokenlist->count - 1)); + builder.next = builder.nodes; + Jim_InitStack(&builder.stack); - Jim_FreeStack(&stack); + rc = ExprTreeBuildTree(interp, &builder, 0, 0, 1); - for (i = 0; i < expr->len; i++) { - Jim_IncrRefCount(expr->token[i].objPtr); + if (rc == JIM_OK) { + top = Jim_StackPop(&builder.stack); + + if (builder.parencount) { + Jim_SetResultString(interp, "missing close parenthesis", -1); + rc = JIM_ERR; + } } - if (!ok) { - ExprFreeByteCode(interp, expr); + + Jim_FreeStack(&builder.stack); + + if (rc != JIM_OK) { + ExprTreeFreeNodes(interp, builder.nodes, builder.next - builder.nodes); return NULL; } + expr = Jim_Alloc(sizeof(*expr)); + expr->inUse = 1; + expr->expr = top; + expr->nodes = builder.nodes; + expr->len = builder.next - builder.nodes; + + assert(expr->len <= tokenlist->count - 1); + return expr; } - static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) { int exprTextLen; const char *exprText; struct JimParserCtx parser; - struct ExprByteCode *expr; + struct ExprTree *expr; ParseTokenList tokenlist; int line; Jim_Obj *fileNameObj; @@ -13999,7 +13921,7 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) } - expr = ExprCreateByteCode(interp, &tokenlist, objPtr, fileNameObj); + expr = ExprTreeCreateTree(interp, &tokenlist, objPtr, fileNameObj); ScriptTokenListFree(&tokenlist); @@ -14009,26 +13931,10 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) } #ifdef DEBUG_SHOW_EXPR - { - int i; - - printf("==== Expr ====\n"); - for (i = 0; i < expr->len; i++) { - ScriptToken *t = &expr->token[i]; - - printf("[%2d] %s '%s'\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); - } - } + printf("==== Expr ====\n"); + JimShowExprNode(expr->expr, 0); #endif - - if (ExprCheckCorrectness(interp, objPtr, expr) != JIM_OK) { - - ExprFreeByteCode(interp, expr); - expr = NULL; - goto err; - } - rc = JIM_OK; err: @@ -14040,39 +13946,104 @@ static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) return rc; } -static ExprByteCode *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) +static struct ExprTree *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr->typePtr != &exprObjType) { if (SetExprFromAny(interp, objPtr) != JIM_OK) { return NULL; } } - return (ExprByteCode *) Jim_GetIntRepPtr(objPtr); + return (struct ExprTree *) Jim_GetIntRepPtr(objPtr); } #ifdef JIM_OPTIMIZATION -static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, const ScriptToken *token) -{ - if (token->type == JIM_TT_EXPR_INT) - return token->objPtr; - else if (token->type == JIM_TT_VAR) - return Jim_GetVariable(interp, token->objPtr, JIM_NONE); - else if (token->type == JIM_TT_DICTSUGAR) - return JimExpandDictSugar(interp, token->objPtr); +static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, struct JimExprNode *node) +{ + if (node->type == JIM_TT_EXPR_INT) + return node->objPtr; + else if (node->type == JIM_TT_VAR) + return Jim_GetVariable(interp, node->objPtr, JIM_NONE); + else if (node->type == JIM_TT_DICTSUGAR) + return JimExpandDictSugar(interp, node->objPtr); else return NULL; } #endif -#define JIM_EE_STATICSTACK_LEN 10 -int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr) +static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node) { - ExprByteCode *expr; - Jim_Obj *staticStack[JIM_EE_STATICSTACK_LEN]; - int i; + if (TOKEN_IS_EXPR_OP(node->type)) { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(node->type); + return op->funcop(interp, node); + } + else { + Jim_Obj *objPtr; + + + switch (node->type) { + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + case JIM_TT_EXPR_BOOLEAN: + case JIM_TT_STR: + Jim_SetResult(interp, node->objPtr); + return JIM_OK; + + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, node->objPtr, JIM_ERRMSG); + if (objPtr) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, node->objPtr); + if (objPtr) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_ESC: + if (Jim_SubstObj(interp, node->objPtr, &objPtr, JIM_NONE) == JIM_OK) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_CMD: + return Jim_EvalObj(interp, node->objPtr); + + default: + + return JIM_ERR; + } + } +} + +static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr) +{ + int rc = JimExprEvalTermNode(interp, node); + if (rc == JIM_OK) { + *objPtrPtr = Jim_GetResult(interp); + Jim_IncrRefCount(*objPtrPtr); + } + return rc; +} + +static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node) +{ + if (JimExprEvalTermNode(interp, node) == JIM_OK) { + return ExprBool(interp, Jim_GetResult(interp)); + } + return -1; +} + +int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr) +{ + struct ExprTree *expr; int retcode = JIM_OK; - struct JimExprState e; expr = JimGetExpression(interp, exprObjPtr); if (!expr) { @@ -14086,35 +14057,33 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe switch (expr->len) { case 1: - objPtr = JimExprIntValOrVar(interp, &expr->token[0]); + objPtr = JimExprIntValOrVar(interp, expr->expr); if (objPtr) { - Jim_IncrRefCount(objPtr); - *exprResultPtrPtr = objPtr; + Jim_SetResult(interp, objPtr); return JIM_OK; } break; case 2: - if (expr->token[1].type == JIM_EXPROP_NOT) { - objPtr = JimExprIntValOrVar(interp, &expr->token[0]); + if (expr->expr->type == JIM_EXPROP_NOT) { + objPtr = JimExprIntValOrVar(interp, expr->expr->left); if (objPtr && JimIsWide(objPtr)) { - *exprResultPtrPtr = JimWideValue(objPtr) ? interp->falseObj : interp->trueObj; - Jim_IncrRefCount(*exprResultPtrPtr); + Jim_SetResult(interp, JimWideValue(objPtr) ? interp->falseObj : interp->trueObj); return JIM_OK; } } break; case 3: - objPtr = JimExprIntValOrVar(interp, &expr->token[0]); + objPtr = JimExprIntValOrVar(interp, expr->expr->left); if (objPtr && JimIsWide(objPtr)) { - Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, &expr->token[1]); + Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, expr->expr->right); if (objPtr2 && JimIsWide(objPtr2)) { jim_wide wideValueA = JimWideValue(objPtr); jim_wide wideValueB = JimWideValue(objPtr2); int cmpRes; - switch (expr->token[2].type) { + switch (expr->expr->type) { case JIM_EXPROP_LT: cmpRes = wideValueA < wideValueB; break; @@ -14136,8 +14105,7 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe default: goto noopt; } - *exprResultPtrPtr = cmpRes ? interp->trueObj : interp->falseObj; - Jim_IncrRefCount(*exprResultPtrPtr); + Jim_SetResult(interp, cmpRes ? interp->trueObj : interp->falseObj); return JIM_OK; } } @@ -14150,122 +14118,33 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprRe expr->inUse++; - - if (expr->len > JIM_EE_STATICSTACK_LEN) - e.stack = Jim_Alloc(sizeof(Jim_Obj *) * expr->len); - else - e.stack = staticStack; - - 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; - - case JIM_TT_VAR: - objPtr = Jim_GetVariable(interp, expr->token[i].objPtr, JIM_ERRMSG); - if (objPtr) { - ExprPush(&e, objPtr); - } - else { - retcode = JIM_ERR; - } - break; - - case JIM_TT_DICTSUGAR: - objPtr = JimExpandDictSugar(interp, expr->token[i].objPtr); - if (objPtr) { - ExprPush(&e, objPtr); - } - else { - retcode = JIM_ERR; - } - break; - - case JIM_TT_ESC: - retcode = Jim_SubstObj(interp, expr->token[i].objPtr, &objPtr, JIM_NONE); - if (retcode == JIM_OK) { - ExprPush(&e, objPtr); - } - break; - - case JIM_TT_CMD: - retcode = Jim_EvalObj(interp, expr->token[i].objPtr); - if (retcode == JIM_OK) { - ExprPush(&e, Jim_GetResult(interp)); - } - break; - - default:{ - - e.skip = 0; - e.opcode = expr->token[i].type; - - retcode = JimExprOperatorInfoByOpcode(e.opcode)->funcop(interp, &e); - - i += e.skip; - continue; - } - } - } + retcode = JimExprEvalTermNode(interp, expr->expr); expr->inUse--; - if (retcode == JIM_OK) { - *exprResultPtrPtr = ExprPop(&e); - } - else { - for (i = 0; i < e.stacklen; i++) { - Jim_DecrRefCount(interp, e.stack[i]); - } - } - if (e.stack != staticStack) { - Jim_Free(e.stack); - } return retcode; } int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) { - int retcode; - jim_wide wideValue; - double doubleValue; - int booleanValue; - Jim_Obj *exprResultPtr; + int retcode = Jim_EvalExpression(interp, exprObjPtr); - retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr); - if (retcode != JIM_OK) - return retcode; + if (retcode == JIM_OK) { + switch (ExprBool(interp, Jim_GetResult(interp))) { + case 0: + *boolPtr = 0; + break; - if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) { - if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) { - 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); - *boolPtr = doubleValue != 0; - return JIM_OK; + case 1: + *boolPtr = 1; + break; + + case -1: + retcode = JIM_ERR; + break; } } - *boolPtr = wideValue != 0; - - Jim_DecrRefCount(interp, exprResultPtr); - return JIM_OK; + return retcode; } @@ -14273,8 +14152,8 @@ int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) typedef struct ScanFmtPartDescr { - char *arg; - char *prefix; + const char *arg; + const char *prefix; size_t width; int pos; char type; @@ -14336,8 +14215,8 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) ScanFmtStringObj *fmtObj; char *buffer; int maxCount, i, approxSize, lastPos = -1; - const char *fmt = objPtr->bytes; - int maxFmtLen = objPtr->length; + const char *fmt = Jim_String(objPtr); + int maxFmtLen = Jim_Length(objPtr); const char *fmtEnd = fmt + maxFmtLen; int curr; @@ -14422,6 +14301,11 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) return JIM_ERR; } } + if (descr->pos < 0) { + fmtObj->error = + "\"%n$\" conversion specifier is negative"; + return JIM_ERR; + } if (sscanf(fmt, "%d%n", &width, &skip) == 1) { descr->width = width; @@ -14473,9 +14357,14 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) } else { - if (strchr("hlL", *fmt) != 0) + if (fmt < fmtEnd && strchr("hlL", *fmt)) descr->modifier = tolower((int)*fmt++); + if (fmt >= fmtEnd) { + fmtObj->error = "missing scan conversion character"; + return JIM_ERR; + } + descr->type = *fmt; if (strchr("efgcsndoxui", *fmt) == 0) { fmtObj->error = "bad scan conversion character"; @@ -14882,6 +14771,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { int retcode; Jim_Cmd *cmdPtr; + void *prevPrivData; #if 0 printf("invoke"); @@ -14911,6 +14801,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) goto out; } interp->evalDepth++; + prevPrivData = interp->cmdPrivData; Jim_SetEmptyResult(interp); @@ -14921,6 +14812,7 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) interp->cmdPrivData = cmdPtr->u.native.privData; retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); } + interp->cmdPrivData = prevPrivData; interp->evalDepth--; out: @@ -15085,7 +14977,8 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok if (tokens == 1 && intv[0] && intv == sintv) { - Jim_DecrRefCount(interp, intv[0]); + + intv[0]->refCount--; return intv[0]; } @@ -15540,6 +15433,7 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj badargset: + retcode = JimInvokeDefer(interp, retcode); interp->framePtr = interp->framePtr->parent; JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); @@ -15828,7 +15722,7 @@ void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const listObjPtr = Jim_NewListObj(interp, argv, argc); - if (*msg) { + if (msg && *msg) { Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); } Jim_IncrRefCount(listObjPtr); @@ -16068,8 +15962,13 @@ static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, i } if (op == JIM_EXPROP_SUB) res -= wideValue; - else + else { + if (wideValue == 0) { + Jim_SetResultString(interp, "Division by zero", -1); + return JIM_ERR; + } res /= wideValue; + } } Jim_SetResultInt(interp, res); return JIM_OK; @@ -16221,7 +16120,7 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv #ifdef JIM_OPTIMIZATION if (retval == JIM_OK && boolean) { ScriptObj *incrScript; - ExprByteCode *expr; + struct ExprTree *expr; jim_wide stop, currentVal; Jim_Obj *objPtr; int cmpOffset; @@ -16235,47 +16134,53 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv 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)) { + if (incrScript->token[1].type != JIM_TT_ESC) { goto evalstart; } - if (expr->token[2].type == JIM_EXPROP_LT) { + if (expr->expr->type == JIM_EXPROP_LT) { cmpOffset = 0; } - else if (expr->token[2].type == JIM_EXPROP_LTE) { + else if (expr->expr->type == JIM_EXPROP_LTE) { cmpOffset = 1; } else { goto evalstart; } + if (expr->expr->left->type != JIM_TT_VAR) { + goto evalstart; + } + + if (expr->expr->right->type != JIM_TT_VAR && expr->expr->right->type != JIM_TT_EXPR_INT) { + goto evalstart; + } + if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) { goto evalstart; } - if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) { + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->expr->left->objPtr)) { goto evalstart; } - if (expr->token[1].type == JIM_TT_EXPR_INT) { - if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) { + if (expr->expr->right->type == JIM_TT_EXPR_INT) { + if (Jim_GetWide(interp, expr->expr->right->objPtr, &stop) == JIM_ERR) { goto evalstart; } } else { - stopVarNamePtr = expr->token[1].objPtr; + stopVarNamePtr = expr->expr->right->objPtr; Jim_IncrRefCount(stopVarNamePtr); stop = 0; } - varNamePtr = expr->token[0].objPtr; + varNamePtr = expr->expr->left->objPtr; Jim_IncrRefCount(varNamePtr); objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE); @@ -16482,7 +16387,7 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg } if (result != JIM_OK) { Jim_SetResultString(interp, "foreach varlist is empty", -1); - return result; + goto empty_varlist; } if (doMap) { @@ -16545,6 +16450,7 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_SetResult(interp, resultObj); err: Jim_DecrRefCount(interp, resultObj); + empty_varlist: if (numargs > 2) { Jim_Free(iters); } @@ -16671,15 +16577,13 @@ int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patter return eq; } -enum -{ SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD }; - static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { + enum { SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD }; int matchOpt = SWITCH_EXACT, opt = 1, patCount, i; - Jim_Obj *command = 0, *const *caseList = 0, *strObj; - Jim_Obj *script = 0; + Jim_Obj *command = NULL, *scriptObj = NULL, *strObj; + Jim_Obj **caseList; if (argc < 3) { wrongnumargs: @@ -16720,16 +16624,13 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a strObj = argv[opt++]; patCount = argc - opt; if (patCount == 1) { - Jim_Obj **vector; - - JimListGetElements(interp, argv[opt], &patCount, &vector); - caseList = vector; + JimListGetElements(interp, argv[opt], &patCount, &caseList); } else - caseList = &argv[opt]; + caseList = (Jim_Obj **)&argv[opt]; if (patCount == 0 || patCount % 2 != 0) goto wrongnumargs; - for (i = 0; script == 0 && i < patCount; i += 2) { + for (i = 0; scriptObj == NULL && i < patCount; i += 2) { Jim_Obj *patObj = caseList[i]; if (!Jim_CompareStringImmediate(interp, patObj, "default") @@ -16737,11 +16638,11 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a switch (matchOpt) { case SWITCH_EXACT: if (Jim_StringEqObj(strObj, patObj)) - script = caseList[i + 1]; + scriptObj = caseList[i + 1]; break; case SWITCH_GLOB: if (Jim_StringMatchObj(interp, patObj, strObj, 0)) - script = caseList[i + 1]; + scriptObj = caseList[i + 1]; break; case SWITCH_RE: command = Jim_NewStringObj(interp, "regexp", -1); @@ -16750,34 +16651,31 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0); if (argc - opt == 1) { - Jim_Obj **vector; - - JimListGetElements(interp, argv[opt], &patCount, &vector); - caseList = vector; + JimListGetElements(interp, argv[opt], &patCount, &caseList); } if (rc < 0) { return -rc; } if (rc) - script = caseList[i + 1]; + scriptObj = caseList[i + 1]; break; } } } else { - script = caseList[i + 1]; + scriptObj = caseList[i + 1]; } } - for (; i < patCount && Jim_CompareStringImmediate(interp, script, "-"); i += 2) - script = caseList[i + 1]; - if (script && Jim_CompareStringImmediate(interp, script, "-")) { + for (; i < patCount && Jim_CompareStringImmediate(interp, scriptObj, "-"); i += 2) + scriptObj = caseList[i + 1]; + if (scriptObj && Jim_CompareStringImmediate(interp, scriptObj, "-")) { Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]); return JIM_ERR; } Jim_SetEmptyResult(interp); - if (script) { - return Jim_EvalObj(interp, script); + if (scriptObj) { + return Jim_EvalObj(interp, scriptObj); } return JIM_OK; } @@ -17076,18 +16974,8 @@ 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 { - Jim_SetResultString(interp, "list doesn't contain element ", -1); - Jim_AppendObj(interp, Jim_GetResult(interp), argv[2]); - return JIM_ERR; + if (first > len) { + first = len; } @@ -17131,6 +17019,7 @@ static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const arg Jim_Obj *resObj; int i; int retCode; + int shared; struct lsort_info info; @@ -17196,12 +17085,14 @@ static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const arg break; } } - resObj = Jim_DuplicateObj(interp, argv[argc - 1]); + resObj = argv[argc - 1]; + if ((shared = Jim_IsShared(resObj))) + resObj = Jim_DuplicateObj(interp, resObj); retCode = ListSortElements(interp, resObj, &info); if (retCode == JIM_OK) { Jim_SetResult(interp, resObj); } - else { + else if (shared) { Jim_FreeNewObj(interp, resObj); } return retCode; @@ -17249,6 +17140,7 @@ static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a } + static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { #if !defined(JIM_DEBUG_COMMAND) @@ -17329,18 +17221,17 @@ static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_Obj *exprResultPtr; int retcode; if (argc == 2) { - retcode = Jim_EvalExpression(interp, argv[1], &exprResultPtr); + retcode = Jim_EvalExpression(interp, argv[1]); } else if (argc > 2) { Jim_Obj *objPtr; objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); Jim_IncrRefCount(objPtr); - retcode = Jim_EvalExpression(interp, objPtr, &exprResultPtr); + retcode = Jim_EvalExpression(interp, objPtr); Jim_DecrRefCount(interp, objPtr); } else { @@ -17349,8 +17240,6 @@ static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } if (retcode != JIM_OK) return retcode; - Jim_SetResult(interp, exprResultPtr); - Jim_DecrRefCount(interp, exprResultPtr); return JIM_OK; } @@ -19655,6 +19544,14 @@ int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const return JIM_ERR; } +static const Jim_ObjType getEnumObjType = { + "get-enum", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES +}; + int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr, int *indexPtr, const char *name, int flags) { @@ -19663,15 +19560,24 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, int i; int match = -1; int arglen; - const char *arg = Jim_GetString(objPtr, &arglen); + const char *arg; + + if (objPtr->typePtr == &getEnumObjType) { + if (objPtr->internalRep.ptrIntValue.ptr == tablePtr && objPtr->internalRep.ptrIntValue.int1 == flags) { + *indexPtr = objPtr->internalRep.ptrIntValue.int2; + return JIM_OK; + } + } + + arg = Jim_GetString(objPtr, &arglen); *indexPtr = -1; for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { - *indexPtr = i; - return JIM_OK; + match = i; + goto found; } if (flags & JIM_ENUM_ABBREV) { if (strncmp(arg, *entryPtr, arglen) == 0) { @@ -19689,6 +19595,14 @@ int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, if (match >= 0) { + found: + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &getEnumObjType; + objPtr->internalRep.ptrIntValue.ptr = (void *)tablePtr; + objPtr->internalRep.ptrIntValue.int1 = flags; + objPtr->internalRep.ptrIntValue.int2 = match; + *indexPtr = match; return JIM_OK; } @@ -19820,18 +19734,14 @@ static void add_commands(Jim_Interp *interp, const jim_subcmd_type * ct, const c static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type, Jim_Obj *cmd, Jim_Obj *subcmd) { - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type, - " command \"", Jim_String(subcmd), "\": should be ", NULL); + Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be ", cmd, type, subcmd); add_commands(interp, command_table, ", "); } static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, Jim_Obj *const *argv) { - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), - " command ... \", where command is one of: ", NULL); + Jim_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: ", argv[0]); add_commands(interp, command_table, ", "); } @@ -19853,6 +19763,14 @@ static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_t Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); } +static const Jim_ObjType subcmdLookupObjType = { + "subcmd-lookup", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES +}; + const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, Jim_Obj *const *argv) { @@ -19861,22 +19779,25 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type int cmdlen; Jim_Obj *cmd; const char *cmdstr; - const char *cmdname; int help = 0; - cmdname = Jim_String(argv[0]); - if (argc < 2) { - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname, - " command ...\"\n", NULL); - Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL); + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n" + "Use \"%#s -help ?command?\" for help", argv[0], argv[0]); return 0; } cmd = argv[1]; + if (cmd->typePtr == &subcmdLookupObjType) { + if (cmd->internalRep.ptrIntValue.ptr == command_table) { + ct = command_table + cmd->internalRep.ptrIntValue.int1; + goto found; + } + } + + if (Jim_CompareStringImmediate(interp, cmd, "-help")) { if (argc == 2) { @@ -19944,6 +19865,13 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type } + Jim_FreeIntRep(interp, cmd); + cmd->typePtr = &subcmdLookupObjType; + cmd->internalRep.ptrIntValue.ptr = (void *)command_table; + cmd->internalRep.ptrIntValue.int1 = ct - command_table; + +found: + if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { Jim_SetResultString(interp, "wrong # args: should be \"", -1); @@ -20135,7 +20063,8 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ *p++ = ch; format += step; step = utf8_tounicode(format, &ch); - } while (sawFlag); + + } while (sawFlag && (p - spec <= 5)); width = 0; @@ -20334,6 +20263,13 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_ *p = '\0'; + if (width > 10000 || length > 10000 || precision > 10000) { + Jim_SetResultString(interp, "format too long", -1); + goto error; + } + + + if (width > length) { length = width; } @@ -20706,6 +20642,10 @@ static int regpiece(regex_t *preg, int *flagp) if (*end == '}') { max = min; } + else if (*end == '\0') { + preg->err = REG_ERR_UNMATCHED_BRACES; + return 0; + } else { preg->regparse = end; max = strtoul(preg->regparse + 1, &end, 10); @@ -20910,8 +20850,31 @@ static int regatom(regex_t *preg, int *flagp) int start; int end; + enum { + CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER, + CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT, + CC_NUM + }; + int cc; + pattern += reg_utf8_tounicode_case(pattern, &start, nocase); if (start == '\\') { + + switch (*pattern) { + case 's': + pattern++; + cc = CC_SPACE; + goto cc_switch; + case 'd': + pattern++; + cc = CC_DIGIT; + goto cc_switch; + case 'w': + pattern++; + reg_addrange(preg, '_', '_'); + cc = CC_ALNUM; + goto cc_switch; + } pattern += reg_decode_escape(pattern, &start); if (start == 0) { preg->err = REG_ERR_NULL_CHAR; @@ -20938,23 +20901,18 @@ static int regatom(regex_t *preg, int *flagp) ":alpha:", ":alnum:", ":space:", ":blank:", ":upper:", ":lower:", ":digit:", ":xdigit:", ":cntrl:", ":graph:", ":print:", ":punct:", }; - enum { - CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER, - CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT, - CC_NUM - }; - int i; - for (i = 0; i < CC_NUM; i++) { - n = strlen(character_class[i]); - if (strncmp(pattern, character_class[i], n) == 0) { + for (cc = 0; cc < CC_NUM; cc++) { + n = strlen(character_class[cc]); + if (strncmp(pattern, character_class[cc], n) == 0) { pattern += n + 1; break; } } - if (i != CC_NUM) { - switch (i) { + if (cc != CC_NUM) { +cc_switch: + switch (cc) { case CC_ALNUM: reg_addrange(preg, '0', '9'); @@ -21808,6 +21766,219 @@ void regfree(regex_t *preg) free(preg->program); } +#endif +#include + +void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) +{ + Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno())); +} + +#if defined(__MINGW32__) +#include + +int Jim_Errno(void) +{ + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: return ENOENT; + case ERROR_PATH_NOT_FOUND: return ENOENT; + case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; + case ERROR_ACCESS_DENIED: return EACCES; + case ERROR_INVALID_HANDLE: return EBADF; + case ERROR_BAD_ENVIRONMENT: return E2BIG; + case ERROR_BAD_FORMAT: return ENOEXEC; + case ERROR_INVALID_ACCESS: return EACCES; + case ERROR_INVALID_DRIVE: return ENOENT; + case ERROR_CURRENT_DIRECTORY: return EACCES; + case ERROR_NOT_SAME_DEVICE: return EXDEV; + case ERROR_NO_MORE_FILES: return ENOENT; + case ERROR_WRITE_PROTECT: return EROFS; + case ERROR_BAD_UNIT: return ENXIO; + case ERROR_NOT_READY: return EBUSY; + case ERROR_BAD_COMMAND: return EIO; + case ERROR_CRC: return EIO; + case ERROR_BAD_LENGTH: return EIO; + case ERROR_SEEK: return EIO; + case ERROR_WRITE_FAULT: return EIO; + case ERROR_READ_FAULT: return EIO; + case ERROR_GEN_FAILURE: return EIO; + case ERROR_SHARING_VIOLATION: return EACCES; + case ERROR_LOCK_VIOLATION: return EACCES; + case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE; + case ERROR_HANDLE_DISK_FULL: return ENOSPC; + case ERROR_NOT_SUPPORTED: return ENODEV; + case ERROR_REM_NOT_LIST: return EBUSY; + case ERROR_DUP_NAME: return EEXIST; + case ERROR_BAD_NETPATH: return ENOENT; + case ERROR_NETWORK_BUSY: return EBUSY; + case ERROR_DEV_NOT_EXIST: return ENODEV; + case ERROR_TOO_MANY_CMDS: return EAGAIN; + case ERROR_ADAP_HDW_ERR: return EIO; + case ERROR_BAD_NET_RESP: return EIO; + case ERROR_UNEXP_NET_ERR: return EIO; + case ERROR_NETNAME_DELETED: return ENOENT; + case ERROR_NETWORK_ACCESS_DENIED: return EACCES; + case ERROR_BAD_DEV_TYPE: return ENODEV; + case ERROR_BAD_NET_NAME: return ENOENT; + case ERROR_TOO_MANY_NAMES: return ENFILE; + case ERROR_TOO_MANY_SESS: return EIO; + case ERROR_SHARING_PAUSED: return EAGAIN; + case ERROR_REDIR_PAUSED: return EAGAIN; + case ERROR_FILE_EXISTS: return EEXIST; + case ERROR_CANNOT_MAKE: return ENOSPC; + case ERROR_OUT_OF_STRUCTURES: return ENFILE; + case ERROR_ALREADY_ASSIGNED: return EEXIST; + case ERROR_INVALID_PASSWORD: return EPERM; + case ERROR_NET_WRITE_FAULT: return EIO; + case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_DISK_CHANGE: return EXDEV; + case ERROR_BROKEN_PIPE: return EPIPE; + case ERROR_OPEN_FAILED: return ENOENT; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE; + case ERROR_INVALID_TARGET_HANDLE: return EBADF; + case ERROR_INVALID_NAME: return ENOENT; + case ERROR_PROC_NOT_FOUND: return ESRCH; + case ERROR_WAIT_NO_CHILDREN: return ECHILD; + case ERROR_CHILD_NOT_COMPLETE: return ECHILD; + case ERROR_DIRECT_ACCESS_HANDLE: return EBADF; + case ERROR_SEEK_ON_DEVICE: return ESPIPE; + case ERROR_BUSY_DRIVE: return EAGAIN; + case ERROR_DIR_NOT_EMPTY: return EEXIST; + case ERROR_NOT_LOCKED: return EACCES; + case ERROR_BAD_PATHNAME: return ENOENT; + case ERROR_LOCK_FAILED: return EACCES; + case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG; + case ERROR_BAD_PIPE: return EPIPE; + case ERROR_PIPE_BUSY: return EAGAIN; + case ERROR_PIPE_NOT_CONNECTED: return EPIPE; + case ERROR_DIRECTORY: return ENOTDIR; + } + return EINVAL; +} + +pidtype waitpid(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); + *status = ret; + CloseHandle(pid); + return pid; +} + +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) +{ + char name[MAX_PATH]; + HANDLE handle; + + if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, filename_template ? filename_template : "JIM", 0, name)) { + return -1; + } + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | (unlink_file ? FILE_FLAG_DELETE_ON_CLOSE : 0), + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + goto error; + } + + Jim_SetResultString(interp, name, -1); + return _open_osfhandle((int)handle, _O_RDWR | _O_TEXT); + + error: + Jim_SetResultErrno(interp, name); + DeleteFile(name); + return -1; +} + +int Jim_OpenForWrite(const char *filename, int append) +{ + if (strcmp(filename, "/dev/null") == 0) { + filename = "nul:"; + } + int fd = _open(filename, _O_WRONLY | _O_CREAT | _O_TEXT | (append ? _O_APPEND : _O_TRUNC), _S_IREAD | _S_IWRITE); + if (fd >= 0 && append) { + + _lseek(fd, 0L, SEEK_END); + } + return fd; +} + +int Jim_OpenForRead(const char *filename) +{ + if (strcmp(filename, "/dev/null") == 0) { + filename = "nul:"; + } + return _open(filename, _O_RDONLY | _O_TEXT, 0); +} + +#elif defined(HAVE_UNISTD_H) + + + +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) +{ + int fd; + mode_t mask; + Jim_Obj *filenameObj; + + if (filename_template == NULL) { + const char *tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) { + tmpdir = "/tmp/"; + } + filenameObj = Jim_NewStringObj(interp, tmpdir, -1); + if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') { + Jim_AppendString(interp, filenameObj, "/", 1); + } + Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1); + } + else { + filenameObj = Jim_NewStringObj(interp, filename_template, -1); + } + + + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); +#ifdef HAVE_MKSTEMP + fd = mkstemp(filenameObj->bytes); +#else + if (mktemp(filenameObj->bytes) == NULL) { + fd = -1; + } + else { + fd = open(filenameObj->bytes, O_RDWR | O_CREAT | O_TRUNC); + } +#endif + umask(mask); + if (fd < 0) { + Jim_SetResultErrno(interp, Jim_String(filenameObj)); + Jim_FreeNewObj(interp, filenameObj); + return -1; + } + if (unlink_file) { + remove(Jim_String(filenameObj)); + } + + Jim_SetResult(interp, filenameObj); + return fd; +} + +int Jim_OpenForWrite(const char *filename, int append) +{ + return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666); +} + +int Jim_OpenForRead(const char *filename) +{ + return open(filename, O_RDONLY, 0); +} + #endif #if defined(_WIN32) || defined(WIN32) @@ -21927,6 +22098,32 @@ struct dirent *readdir(DIR * dir) } #endif #endif +#include +#include + + + + + + +#ifndef SIGPIPE +#define SIGPIPE 13 +#endif +#ifndef SIGINT +#define SIGINT 2 +#endif + +const char *Jim_SignalId(int sig) +{ + static char buf[10]; + switch (sig) { + case SIGINT: return "SIGINT"; + case SIGPIPE: return "SIGPIPE"; + + } + snprintf(buf, sizeof(buf), "%d", sig); + return buf; +} #ifndef JIM_BOOTSTRAP_LIB_ONLY #include #include @@ -21944,10 +22141,30 @@ struct dirent *readdir(DIR * dir) #define MAX_LINE_LEN 512 #endif -char *Jim_HistoryGetline(const char *prompt) +#ifdef USE_LINENOISE +static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata); +static const char completion_callback_assoc_key[] = "interactive-completion"; +#endif + +char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt) { #ifdef USE_LINENOISE - return linenoise(prompt); + struct JimCompletionInfo *compinfo = Jim_GetAssocData(interp, completion_callback_assoc_key); + char *result; + Jim_Obj *objPtr; + long mlmode = 0; + if (compinfo) { + linenoiseSetCompletionCallback(JimCompletionCallback, compinfo); + } + objPtr = Jim_GetVariableStr(interp, "history::multiline", JIM_NONE); + if (objPtr && Jim_GetLong(interp, objPtr, &mlmode) == JIM_NONE) { + linenoiseSetMultiLine(mlmode); + } + + result = linenoise(prompt); + + linenoiseSetCompletionCallback(NULL, NULL); + return result; #else int len; char *line = malloc(MAX_LINE_LEN); @@ -21991,7 +22208,7 @@ void Jim_HistorySave(const char *filename) #endif linenoiseHistorySave(filename); #ifdef HAVE_UMASK - mask = umask(mask); + umask(mask); #endif #endif } @@ -22015,7 +22232,7 @@ struct JimCompletionInfo { Jim_Obj *command; }; -void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata) +static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata) { struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata; Jim_Obj *objv[2]; @@ -22036,7 +22253,36 @@ void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void } } } + +static void JimHistoryFreeCompletion(Jim_Interp *interp, void *data) +{ + struct JimCompletionInfo *compinfo = data; + + Jim_DecrRefCount(interp, compinfo->command); + + Jim_Free(compinfo); +} +#endif + +void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *commandObj) +{ +#ifdef USE_LINENOISE + if (commandObj) { + + Jim_IncrRefCount(commandObj); + } + + Jim_DeleteAssocData(interp, completion_callback_assoc_key); + + if (commandObj) { + struct JimCompletionInfo *compinfo = Jim_Alloc(sizeof(*compinfo)); + compinfo->interp = interp; + compinfo->command = commandObj; + + Jim_SetAssocData(interp, completion_callback_assoc_key, JimHistoryFreeCompletion, compinfo); + } #endif +} int Jim_InteractivePrompt(Jim_Interp *interp) { @@ -22044,7 +22290,6 @@ int Jim_InteractivePrompt(Jim_Interp *interp) char *history_file = NULL; #ifdef USE_LINENOISE const char *home; - struct JimCompletionInfo compinfo; home = getenv("HOME"); if (home && isatty(STDIN_FILENO)) { @@ -22054,12 +22299,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp) Jim_HistoryLoad(history_file); } - compinfo.interp = interp; - compinfo.command = Jim_NewStringObj(interp, "tcl::autocomplete", -1); - Jim_IncrRefCount(compinfo.command); - - - linenoiseSetCompletionCallback(JimCompletionCallback, &compinfo); + Jim_HistorySetCompletion(interp, Jim_NewStringObj(interp, "tcl::autocomplete", -1)); #endif printf("Welcome to Jim version %d.%d\n", @@ -22092,7 +22332,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp) char state; char *line; - line = Jim_HistoryGetline(prompt); + line = Jim_HistoryGetline(interp, prompt); if (line == NULL) { if (errno == EINTR) { continue; @@ -22142,11 +22382,6 @@ 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; } diff --git a/autosetup/pkg-config.tcl b/autosetup/pkg-config.tcl index d94d20459..d096cabda 100644 --- a/autosetup/pkg-config.tcl +++ b/autosetup/pkg-config.tcl @@ -15,7 +15,7 @@ use cc -module-options { +options { sysroot:dir => "Override compiler sysroot for pkg-config search path" } @@ -73,6 +73,9 @@ proc pkg-config-init {{required 1}} { # XXX: It's possible that these should be set only when invoking pkg-config global env set env(PKG_CONFIG_DIR) "" + # Supposedly setting PKG_CONFIG_LIBDIR means that PKG_CONFIG_PATH is ignored, + # but it doesn't seem to work that way in practice + set env(PKG_CONFIG_PATH) "" # Do we need to try /usr/local as well or instead? set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig set env(PKG_CONFIG_SYSROOT_DIR) $sysroot @@ -95,7 +98,6 @@ proc pkg-config-init {{required 1}} { ## 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_LIBS_STATIC to the required libs (--libs-only-l -static) # # If not found, returns 0. # @@ -109,68 +111,30 @@ proc pkg-config {module args} { return 0 } - if {[catch {exec [get-define PKG_CONFIG] --modversion "$module $args"} version]} { + set pkgconfig [get-define PKG_CONFIG] + + set ret [catch {exec $pkgconfig --modversion "$module $args"} version] + configlog "$pkgconfig --modversion $module $args: $version" + if {$ret} { msg-result "not found" - configlog "pkg-config --modversion $module $args: $version" + return 0 + } + # Sometimes --modversion succeeds but because of dependencies it isn't usable + # This seems to show up with --cflags + set ret [catch {exec $pkgconfig --cflags $module} cflags] + if {$ret} { + msg-result "unusable ($version - see config.log)" + configlog "$pkgconfig --cflags $module" + configlog $cflags return 0 } msg-result $version set prefix [feature-define-name $module PKG_] define HAVE_${prefix} define ${prefix}_VERSION $version - define ${prefix}_LIBS [exec pkg-config --libs-only-l $module] - -# Please enter the commit message for your changes. Lines starting -# with '#' will be ignored, and an empty message aborts the commit. -# -# On branch autosetup -# Your branch is up to date with 'origin/autosetup'. -# -# Changes to be committed: -# modified: auto.def -# -# Untracked files: -# ..travis.yml.un~ -# .Makefile.autosetup.un~ -# .auto.def.un~ -# autosetup/.pkg-config.tcl.un~ -# config.h -# docs/.Makefile.autosetup.un~ -# docs/.Makefile.un~ -# external/libfetch/.Makefile.autosetup.un~ -# external/libfetch/Makefile -# libpkg/.Makefile.autosetup.un~ -# libpkg/.Makefile.un~ -# mk/.common.mk.un~ -# mk/.defs.mk.in.un~ -# mk/.defs.mk.un~ -# mk/.doc.mk.un~ -# mk/doc.mk -# plop.tar.xz -# scripts/.Makefile.autosetup.un~ -# scripts/.Makefile.un~ -# src/.Makefile.autosetup.un~ -# src/.Makefile.un~ -# tests/.Makefile.autosetup.un~ -# tests/Kyuafile -# tests/checksum -# tests/deps_formula -# tests/frontend/Kyuafile -# tests/frontend/add -# tests/frontend/alias -# tests/frontend/annotate -# tests/frontend/autoremove -# tests/frontend/autoupgrade -# tests/frontend/config -# tests/frontend/configmerge -# tests/frontend/conflicts -# tests/frontend/conflicts-multirepo -# tests/frontend/create -# tests/frontend/delete -# tests/frontend/extract -# tests/frontend/fingerprint - define ${prefix}_LDFLAGS [exec pkg-config --libs-only-L $module] - define ${prefix}_CFLAGS [exec pkg-config --cflags $module] + define ${prefix}_CFLAGS $cflags + define ${prefix}_LIBS [exec $pkgconfig --libs-only-l $module] + define ${prefix}_LDFLAGS [exec $pkgconfig --libs-only-L $module] return 1 } @@ -184,3 +148,20 @@ proc pkg-config-get {module name} { set prefix [feature-define-name $module PKG_] get-define ${prefix}_${name} "" } + +# @pkg-config-get-var module variable +# +# Return the value of the given variable from the given pkg-config module. +# The module must already have been successfully detected with pkg-config. +# e.g. +# +## if {[pkg-config harfbuzz >= 2.5]} { +## define harfbuzz_libdir [pkg-config-get-var harfbuzz libdir] +## } +# +# Returns the empty string if the variable isn't defined. +proc pkg-config-get-var {module variable} { + set pkgconfig [get-define PKG_CONFIG] + set prefix [feature-define-name $module HAVE_PKG_] + exec $pkgconfig $module --variable $variable +} diff --git a/autosetup/system.tcl b/autosetup/system.tcl index 56054b4f3..15ab017a0 100644 --- a/autosetup/system.tcl +++ b/autosetup/system.tcl @@ -27,7 +27,7 @@ if {[is-defined defaultprefix]} { options-defaults [list prefix [get-define defaultprefix]] } -module-options [subst -noc -nob { +options { 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 @@ -48,10 +48,11 @@ module-options [subst -noc -nob { sysconfdir: sharedstatedir: localstatedir: + runstatedir: maintainer-mode=0 dependency-tracking=0 silent-rules=0 -}] +} # @check-feature name { script } # @@ -132,6 +133,102 @@ proc write-if-changed {file buf {script {}}} { } } + +# @include-file infile mapping +# +# The core of make-template, called recursively for each @include +# directive found within that template so that this proc's result +# is the fully-expanded template. +# +# The mapping parameter is how we expand @varname@ within the template. +# We do that inline within this step only for @include directives which +# can have variables in the filename arg. A separate substitution pass +# happens when this recursive function returns, expanding the rest of +# the variables. +# +proc include-file {infile mapping} { + # A stack of true/false conditions, one for each nested conditional + # starting with "true" + set condstack {1} + set result {} + set linenum 0 + foreach line [split [readfile $infile] \n] { + incr linenum + if {[regexp {^@(if|else|endif)(\s*)(.*)} $line -> condtype condspace condargs]} { + if {$condtype eq "if"} { + if {[string length $condspace] == 0} { + autosetup-error "$infile:$linenum: Invalid expression: $line" + } + if {[llength $condargs] == 1} { + # ABC => [get-define ABC] ni {0 ""} + # !ABC => [get-define ABC] in {0 ""} + lassign $condargs condvar + if {[regexp {^!(.*)} $condvar -> condvar]} { + set op in + } else { + set op ni + } + set condexpr "\[[list get-define $condvar]\] $op {0 {}}" + } else { + # Translate alphanumeric ABC into [get-define ABC] and leave the + # rest of the expression untouched + regsub -all {([A-Z][[:alnum:]_]*)} $condargs {[get-define \1]} condexpr + } + if {[catch [list expr $condexpr] condval]} { + dputs $condval + autosetup-error "$infile:$linenum: Invalid expression: $line" + } + dputs "@$condtype: $condexpr => $condval" + } + if {$condtype ne "if"} { + if {[llength $condstack] <= 1} { + autosetup-error "$infile:$linenum: Error: @$condtype missing @if" + } elseif {[string length $condargs] && [string index $condargs 0] ne "#"} { + autosetup-error "$infile:$linenum: Error: Extra arguments after @$condtype" + } + } + switch -exact $condtype { + if { + # push condval + lappend condstack $condval + } + else { + # Toggle the last entry + set condval [lpop condstack] + set condval [expr {!$condval}] + lappend condstack $condval + } + endif { + if {[llength $condstack] == 0} { + user-notice "$infile:$linenum: Error: @endif missing @if" + } + lpop condstack + } + } + continue + } elseif {[regexp {^@include\s+(.*)} $line -> filearg]} { + set incfile [string map $mapping $filearg] + if {[file exists $incfile]} { + lappend ::autosetup(deps) [file-normalize $incfile] + lappend result {*}[include-file $incfile $mapping] + } else { + user-error "$infile:$linenum: Include file $incfile is missing" + } + continue + } elseif {[regexp {^@define\s+(\w+)\s+(.*)} $line -> var val]} { + define $var $val + continue + } + # Only output this line if the stack contains all "true" + if {"0" in $condstack} { + continue + } + lappend result $line + } + return $result +} + + # @make-template template ?outfile? # # Reads the input file '/$template' and writes the output file '$outfile' @@ -141,29 +238,32 @@ proc write-if-changed {file buf {script {}}} { # # 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 # path to the source directory from the directory where the output # 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: -## @if name == value +## @if NAME eq "value" ## lines ## @else ## lines ## @endif # -# Where 'name' is a defined variable name and '@else' is optional. +# Where 'NAME' is a defined variable name and '@else' is optional. +# Note that variables names *must* start with an uppercase letter. # If the expression does not match, all lines through '@endif' are ignored. # # The alternative forms may also be used: -## @if name -## @if name != value +## @if NAME (true if the variable is defined, but not empty and not "0") +## @if !NAME (opposite of the form above) +## @if # -# Where the first form is true if the variable is defined, but not empty nor 0. +# In the general Tcl expression, any words beginning with an uppercase letter +# are translated into [get-define NAME] # -# Currently these expressions can't be nested. +# Expressions may be nested # proc make-template {template {out {}}} { set infile [file join $::autosetup(srcdir) $template] @@ -191,42 +291,23 @@ proc make-template {template {out {}}} { define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] define top_srcdir [relative-path $::autosetup(srcdir) $outdir] - set mapping {} - foreach {n v} [array get ::define] { - lappend mapping @$n@ $v - } - set result {} - foreach line [split [readfile $infile] \n] { - if {[info exists cond]} { - set l [string trimright $line] - if {$l eq "@endif"} { - unset cond - continue - } - if {$l eq "@else"} { - set cond [expr {!$cond}] - continue - } - if {$cond} { - lappend result $line - } - continue + # Build map from global defines to their values so they can be + # substituted into @include file names. + proc build-define-mapping {} { + set mapping {} + foreach {n v} [array get ::define] { + lappend mapping @$n@ $v } - if {[regexp {^@if\s+(\w+)(.*)} $line -> name expression]} { - lassign $expression equal value - set varval [get-define $name ""] - if {$equal eq ""} { - set cond [expr {$varval ni {"" 0}}] - } else { - set cond [expr {$varval eq $value}] - if {$equal ne "=="} { - set cond [expr {!$cond}] - } - } - continue - } - lappend result $line + return $mapping } + set mapping [build-define-mapping] + + set result [include-file $infile $mapping] + + # Rebuild the define mapping in case we ran across @define + # directives in the template or a file it @included, then + # apply that mapping to the expanded template. + set mapping [build-define-mapping] write-if-changed $out [string map $mapping [join $result \n]] { msg-result "Created [relative-path $out] from [relative-path $template]" } @@ -301,6 +382,7 @@ if {$prefix ne {/usr}} { define sysconfdir $sysconfdir define localstatedir [opt-str localstatedir o /var] +define runstatedir [opt-str runstatedir o /run] define SHELL [get-env SHELL [find-an-executable sh bash ksh]] diff --git a/autosetup/tmake.tcl b/autosetup/tmake.tcl index a9d721975..3269193aa 100644 --- a/autosetup/tmake.tcl +++ b/autosetup/tmake.tcl @@ -11,7 +11,7 @@ use system -module-options {} +options {} define CONFIGURED diff --git a/configure b/configure index 32c8cfddf..adac37c34 100755 --- a/configure +++ b/configure @@ -1,3 +1,3 @@ #!/bin/sh dir="`dirname "$0"`/autosetup" -WRAPPER="$0"; export WRAPPER; exec "`$dir/autosetup-find-tclsh`" "$dir/autosetup" "$@" +WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@" diff --git a/external/Makefile.autosetup b/external/Makefile.autosetup index 4276b5b4c..f82388f7e 100644 --- a/external/Makefile.autosetup +++ b/external/Makefile.autosetup @@ -1,3 +1,9 @@ include @builddir@/mk/defs.mk -DIRS= blake2 picosat linenoise libfetch sqlite libucl liblua msgpuck yxml @libabidir@ +DIRS= blake2 picosat linenoise libfetch sqlite libucl liblua msgpuck yxml +@if libmachista +DIRS+= libmachista +@endif +@if libelf-internal +DIRS+= libelf +@endif include $(MK)/dir.mk diff --git a/libpkg/Makefile.autosetup b/libpkg/Makefile.autosetup index 899e96232..ae722976c 100644 --- a/libpkg/Makefile.autosetup +++ b/libpkg/Makefile.autosetup @@ -109,7 +109,7 @@ LOCAL_LDFLAGS+= -ldl LOCAL_LDFLAGS+= -lresolv @endif -@if libabidir == libmachista +@if libmachista LOCAL_CFLAGS+= -I$(top_srcdir)/external/libmachista STATIC_LIBS+= $(top_builddir)/external/libmachista/libmachista.a LOCAL_LDFLAGS+= -L$(top_builddir)/external/libmachista -lmachista_pic \ @@ -120,14 +120,13 @@ SRCS+= pkg_elf.c LOCAL_LDFLAGS+= -Wl,--version-script=$(top_builddir)/libpkg/libpkg.ver \ @endif -@if libabidir == libelf +@if libelf-internal LOCAL_CFLAGS+= -I$(top_srcdir)/external/libelf STATIC_LIBS+= $(top_builddir)/external/libelf/libelf.a LOCAL_LDFLAGS+= -L$(top_builddir)/external/libelf -lelf @endif -@if libabidir -@else +@if libelf-external LOCAL_LDFLAGS+= -lelf @endif @@ -149,7 +148,7 @@ $(OBJS) $(SHOBJS): $(top_builddir)/pkg_config.h all: lib$(LIB)_flat.a -@if libabidir == libmachista +@if libmachista lib$(LIB)_flat.a: libtool -static -o lib$(LIB)_flat.a $(STATIC_LIBS) @else diff --git a/mk/defs.mk.in b/mk/defs.mk.in index 156623c77..c524c6a18 100644 --- a/mk/defs.mk.in +++ b/mk/defs.mk.in @@ -1,7 +1,7 @@ RANLIB= @RANLIB@ AR= @AR@ CC= @CC@ -@if coverage == "1" +@if coverage CFLAGS+= @COVERAGE_CFLAGS@ LDFLAGS+= @COVERAGE_LDFLAGS@ @endif diff --git a/src/Makefile.autosetup b/src/Makefile.autosetup index b33f5ac2e..0f8fdf86c 100644 --- a/src/Makefile.autosetup +++ b/src/Makefile.autosetup @@ -65,7 +65,7 @@ OTHER_LIBS+= -ldl OTHER_LIBS+= -lresolv @endif -@if libabidir == libmachista +@if libmachista LOCAL_LDFLAGS= $(LIBPKGFLAT) $(LIBS) $(OTHER_LIBS) -lresolv STATIC_LDFLAGS= $(LIBPKGFLAT) $(LIBS) $(OTHER_LIBS) -lresolv # OSX doesn't support static binaries, sigh diff --git a/tests/Makefile.autosetup b/tests/Makefile.autosetup index 9898ec007..9c73c0e4a 100644 --- a/tests/Makefile.autosetup +++ b/tests/Makefile.autosetup @@ -112,7 +112,7 @@ OTHER_LIBS+= -lresolv @endif # Hack to determine we are on osx -@if libabidir == libmachista +@if libmachista OTHER_LIBS+= -lresolv @endif diff --git a/tests/frontend/test_environment.sh.in b/tests/frontend/test_environment.sh.in index 4e488a79d..4533c23dd 100755 --- a/tests/frontend/test_environment.sh.in +++ b/tests/frontend/test_environment.sh.in @@ -6,7 +6,7 @@ export PATH=$(atf_get_srcdir)/../../src/:${PATH} export INSTALL_AS_USER=yes export PKG_DBDIR=. export NO_TICK=yes -@if coverage == 1 +@if coverage export LLVM_PROFILE_FILE=/tmp/pkg.%p.profraw @endif jailed=$(sysctl -n security.jail.jailed 2>/dev/null || :)