ADDED .dockerignore Index: .dockerignore ================================================================== --- .dockerignore +++ .dockerignore @@ -0,0 +1,26 @@ +_FOSSIL_ +.fslckout +ajax +art +autosetup +bld +compat +debian +fossil +fossil.exe +setup +src +test +tools +win +wbld +win +www +*.a +*.lib +*.log +*.manifest +*.o +*.obj +*.pdb +*.res DELETED .editorconfig Index: .editorconfig ================================================================== --- .editorconfig +++ .editorconfig @@ -1,14 +0,0 @@ -# EditorConfig (https://editorconfig.com) Configuration for Fossil -# -# Following https://fossil-scm.org/fossil/doc/trunk/www/style.wiki -# - -# Defaults for all files -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 2 - -[{Makefile,Makefile.*,*.mk}] -indent_style = tab Index: .fossil-settings/binary-glob ================================================================== --- .fossil-settings/binary-glob +++ .fossil-settings/binary-glob @@ -3,11 +3,9 @@ *.jpg *.odp *.dia *.pdf *.png -*.wav compat/zlib/contrib/blast/test.pk compat/zlib/contrib/dotzlib/DotZLib.chm compat/zlib/contrib/puff/zeros.raw compat/zlib/zlib.3.pdf -extsrc/pikchr.wasm Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -7,14 +7,13 @@ *.res Makefile autosetup/jimsh0 autosetup/jimsh0.exe bld/* -msvcbld/* wbld/* win/*.c win/*.h win/*.exe win/headers win/linkopts autoconfig.h config.log Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -1,9 +1,7 @@ compat/openssl* compat/tcl* -compat/zlib/contrib/ada/* -compat/zlib/doc/* fossil fossil.exe win/fossil.exe *shell-see.* *sqlite3-see.* Index: BUILD.txt ================================================================== --- BUILD.txt +++ BUILD.txt @@ -55,24 +55,24 @@ and runs various tests with the C compiler to create Makefile from the Makefile.in template as well as autoconfig.h * The Makefile just sets up a few macros and then invokes the real makefile in src/main.mk. The src/main.mk makefile is - automatically generated by a TCL script found at tools/makemake.tcl. - Do not edit src/main.mk directly. Update tools/makemake.tcl and + automatically generated by a TCL script found at src/makemake.tcl. + Do not edit src/main.mk directly. Update src/makemake.tcl and then rerun it. * The *.h header files are automatically generated using a program called "makeheaders". Source code to the makeheaders program is - found in tools/makeheaders.c. Documentation is found in - tools/makeheaders.html. + found in src/makeheaders.c. Documentation is found in + src/makeheaders.html. * Most *.c source files are preprocessed using a program called - "translate". The sources to translate are found in tools/translate.c. - A header comment in tools/translate.c explains in detail what it does. + "translate". The sources to translate are found in src/translate.c. + A header comment in src/translate.c explains in detail what it does. -* The tools/mkindex.c program generates some C code that implements +* The src/mkindex.c program generates some C code that implements static lookup tables. See the header comment in the source code for details on what it does. Additional information on the build process is available from -http://fossil-scm.org/home/doc/trunk/www/makefile.wiki +http://www.fossil-scm.org/fossil/doc/trunk/www/makefile.wiki Index: Dockerfile ================================================================== --- Dockerfile +++ Dockerfile @@ -1,90 +1,26 @@ -# syntax=docker/dockerfile:1.3 -# See www/containers.md for documentation on how to use this file. - -## --------------------------------------------------------------------- -## STAGE 1: Build static Fossil binary -## --------------------------------------------------------------------- - -### We aren't pinning to a more stable version of Alpine because we want -### to build with the latest tools and libraries available in case they -### fixed something that matters to us since the last build. Everything -### below depends on this layer, and so, alas, we toss this container's -### cache on Alpine's release schedule, roughly once a month. -FROM alpine:latest AS bld -WORKDIR /fsl - -### Bake the basic Alpine Linux into a base layer so it only changes -### when the upstream image is updated or we change the package set. -RUN set -x \ - && apk update \ - && apk upgrade --no-cache \ - && apk add --no-cache \ - gcc make \ - linux-headers musl-dev \ - openssl-dev openssl-libs-static \ - zlib-dev zlib-static - -### Build Fossil as a separate layer so we don't have to rebuild the -### Alpine environment for each iteration of Fossil's dev cycle. -### -### We must cope with a bizarre ADD misfeature here: it unpacks tarballs -### automatically when you give it a local file name but not if you give -### it a /tarball URL! It matters because we default to a URL in case -### you're building outside a Fossil checkout, but when building via the -### container-image target, we avoid a costly hit on fossil-scm.org -### by leveraging its DVCS nature via the "tarball" command and passing -### the resulting file's name in. -ARG FSLCFG="" -ARG FSLVER="trunk" -ARG FSLURL="https://fossil-scm.org/home/tarball/src?r=${FSLVER}" -ENV FSLSTB=/fsl/src.tar.gz -ADD $FSLURL $FSLSTB -RUN set -x \ - && if [ -d $FSLSTB ] ; \ - then mv $FSLSTB/src . ; \ - else tar -xf src.tar.gz ; fi \ - && src/configure --static CFLAGS='-Os -s' $FSLCFG && make -j16 - - -## --------------------------------------------------------------------- -## STAGE 2: Pare that back to the bare essentials. -## --------------------------------------------------------------------- - -FROM busybox AS os -ARG UID=499 - -### Set up that base OS for our specific use without tying it to -### anything likely to change often. So long as the user leaves -### UID alone, this layer will be durable. -RUN set -x \ - && mkdir e log museum \ - && echo "root:x:0:0:Admin:/:/false" > /e/passwd \ - && echo "root:x:0:root" > /e/group \ - && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /e/passwd \ - && echo "fossil:x:${UID}:fossil" >> /e/group - - -## --------------------------------------------------------------------- -## STAGE 3: Drop BusyBox, too, now that we're done with its /bin/sh &c -## --------------------------------------------------------------------- - -FROM scratch AS run -COPY --from=bld --chmod=755 /fsl/fossil /bin/ -COPY --from=os --chmod=600 /e/* /etc/ -COPY --from=os --chmod=1777 /tmp /tmp/ -COPY --from=os --chown=fossil:fossil /log /log/ -COPY --from=os --chown=fossil:fossil /museum /museum/ - - -## --------------------------------------------------------------------- -## RUN! -## --------------------------------------------------------------------- - -ENV PATH "/bin" -EXPOSE 8080/tcp -USER fossil -ENTRYPOINT [ "fossil", "server", "museum/repo.fossil" ] -CMD [ \ - "--create", \ - "--jsmode", "bundled", \ - "--user", "admin" ] +### +# Dockerfile for Fossil +### +FROM fedora:28 + +### Now install some additional parts we will need for the build +RUN dnf update -y && dnf install -y gcc make tcl tcl-devel zlib-devel openssl-devel tar && dnf clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil + +### If you want to build "trunk", change the next line accordingly. +ENV FOSSIL_INSTALL_VERSION release + +RUN curl "https://www.fossil-scm.org/index.html/tarball/fossil-src.tar.gz?name=fossil-src&uuid=${FOSSIL_INSTALL_VERSION}" | tar zx +RUN cd fossil-src && ./configure --disable-fusefs --json --with-th1-docs --with-th1-hooks --with-tcl=1 --with-tcl-stubs --with-tcl-private-stubs +RUN cd fossil-src/src && mv main.c main.c.orig && sed s/\"now\"/0/ main.c +RUN cd fossil-src && make && strip fossil && cp fossil /usr/bin && cd .. && rm -rf fossil-src && chmod a+rx /usr/bin/fossil && mkdir -p /opt/fossil && chown fossil:fossil /opt/fossil + +### Build is done, remove modules no longer needed +RUN dnf remove -y gcc make zlib-devel tcl-devel openssl-devel tar && dnf clean all + +USER fossil + +ENV HOME /opt/fossil + +EXPOSE 8080 + +CMD ["/usr/bin/fossil", "server", "--create", "--user", "admin", "/opt/fossil/repository.fossil"] Index: Makefile.classic ================================================================== --- Makefile.classic +++ Makefile.classic @@ -7,16 +7,10 @@ #### The toplevel directory of the source tree. Fossil can be built # in a directory that is separate from the source tree. Just change # the following to point from the build directory to the src/ folder. # SRCDIR = ./src -#### Upstream source files included directly in this repository. -# -SRCDIR_extsrc = ./extsrc -#### In-tree tools such as code generators and translators: -# -SRCDIR_tools = ./tools #### The directory into which object code files should be written. # # OBJDIR = ./bld @@ -42,13 +36,20 @@ # #TCC = gcc -O6 #TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage TCC = gcc -g -Os -Wall +# To use the included miniz library +# FOSSIL_ENABLE_MINIZ = 1 +# TCC += -DFOSSIL_ENABLE_MINIZ + # To add support for HTTPS TCC += -DFOSSIL_ENABLE_SSL +# To enable legacy mv/rm support +TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 + #### We sometimes add the -static option here so that we can build a # static executable that will run in a chroot jail. #LIB = -static TCC += -DFOSSIL_DYNAMIC_BUILD=1 @@ -60,16 +61,19 @@ # ifdef'd out elsewhere for that platform. Note that this is a make # flag handled in src/main.mk, not a C preprocessor flag. USE_LINENOISE := 1 #### Extra arguments for linking the finished binary. Fossil needs -# to link against the Z-Lib compression library. There are no -# other required dependencies. -ZLIB_LIB = -lz +# to link against the Z-Lib compression library unless the miniz +# library in the source tree is being used. There are no other +# required dependencies. +ZLIB_LIB.0 = -lz +ZLIB_LIB.1 = +ZLIB_LIB. = $(ZLIB_LIB.0) # If using zlib: -LIB += $(ZLIB_LIB) $(LDFLAGS) +LIB += $(ZLIB_LIB.$(FOSSIL_ENABLE_MINIZ)) $(LDFLAGS) # If using HTTPS: LIB += -lcrypto -lssl # Many platforms put cos() needed by src/piechart.c in libm, rather than @@ -79,18 +83,10 @@ #### Tcl shell for use in running the fossil testsuite. If you do not # care about testing the end result, this can be blank. # TCLSH = tclsh - -CFLAGS += -fPIE -CPPFLAGS += -I. -I$(SRCDIR_extsrc) -I$(SRCDIR) -LIB = -lm -lz -lssl -INSTALLDIR = $(DESTDIR)$(prefix)/bin -SQLITE3_ORIGINAL = 0 -USE_LINENOISE = 1 - # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. @@ -104,8 +100,6 @@ TCC.FreeBSD += -DUSE_PREAD TCC.NetBSD += -DUSE_PREAD TCC.OpenBSD += -DUSE_PREAD TCC += $(TCC.$(HOST_OS)) -APPNAME = fossil$(E) -.PHONY: all tags include $(SRCDIR)/main.mk Index: Makefile.in ================================================================== --- Makefile.in +++ Makefile.in @@ -7,16 +7,10 @@ #### The toplevel directory of the source tree. Fossil can be built # in a directory that is separate from the source tree. Just change # the following to point from the build directory to the src/ folder. # SRCDIR = @srcdir@/src -#### Upstream source files included directly in this repository. -# -SRCDIR_extsrc = @srcdir@/extsrc -#### In-tree tools such as code generators and translators: -# -SRCDIR_tools = @srcdir@/tools #### The directory into which object code files should be written. # Having a "./" prefix in the value of this variable breaks our use of the # "makeheaders" tool when running make on the MinGW platform, apparently # due to some command line argument manipulation performed automatically @@ -43,66 +37,28 @@ # care about testing the end result, this can be blank. # TCLSH = @TCLSH@ CFLAGS = @CFLAGS@ -CFLAGS_INCLUDE = @CFLAGS_INCLUDE@ LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ BCCFLAGS = @CPPFLAGS@ $(CFLAGS) -TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -# -# Fuzzing may be enable by appending -fsanitize=fuzzer -DFOSSIL_FUZZ -# to the TCCFLAGS variable. -# For more thorouth (but also slower) investigation -# -fsanitize=fuzzer,undefined,address -# might be more useful. - +TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H INSTALLDIR = $(DESTDIR)@prefix@/bin USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ -SQLITE3_SRC.2 = @SQLITE3_SRC.2@ -SQLITE3_OBJ.2 = @SQLITE3_OBJ.2@ -SQLITE3_SHELL_SRC.2 = @SQLITE3_SHELL_SRC.2@ -SQLITE3_ORIGIN = @SQLITE3_ORIGIN@ -# SQLITE3_ORIGIN changes... -# SQLITE3_SRC: -# 0=src/sqlite3.c, 1=src/sqlite3-see.c, 2=$(SQLITE3_SRC.2) -# SQLITE3_SHELL_SRC: -# 0=src/shell.c, 1=src/shell-see.c, 2=$(SQLITE3_SHELL_SRC.2) USE_LINENOISE = @USE_LINENOISE@ USE_MMAN_H = @USE_MMAN_H@ USE_SEE = @USE_SEE@ -APPNAME = fossil -# -# APPNAME = fossil-fuzz -# may be more appropriate for fuzzing. - -#### Emscripten stuff for optionally doing in-tree builds -# of any WASM components. We store precompiled WASM in the the SCM, so -# this is only useful for people who actively work on WASM -# components. EMSDK_ENV refers to the "environment" script which comes -# with the Emscripten SDK package: -# https://emscripten.org/docs/getting_started/downloads.html -EMSDK_HOME = @EMSDK_HOME@ -EMSDK_ENV = @EMSDK_ENV@ -EMCC_OPT = @EMCC_OPT@ -EMCC_WRAPPER = $(SRCDIR_tools)/emcc.sh - -.PHONY: all tags +FOSSIL_ENABLE_MINIZ = @FOSSIL_ENABLE_MINIZ@ include $(SRCDIR)/main.mk distclean: clean -rm -f autoconfig.h config.log Makefile - -rm -f cscope.out tags reconfig: @AUTOREMAKE@ -tags: - ctags -R @srcdir@/src - @COLLECT_CSCOPE_DATA@ - # Automatically reconfigure whenever an autosetup file or one of the # make source files change. # # The "touch" is necessary to avoid a make loop due to a new upstream # feature in autosetup (GH 0a71e3c3b7) which rewrites *.in outputs only @@ -116,53 +72,5 @@ # of delegating to it with "$(MAKE) reconfig": having children running # around interfering makes this failure mode even worse. Makefile: @srcdir@/Makefile.in $(SRCDIR)/main.mk @AUTODEPS@ @AUTOREMAKE@ touch @builddir@/Makefile - -# Container stuff -SRCTB := src-@FOSSIL_CI_PFX@.tar.gz -IMGVER := fossil:@FOSSIL_CI_PFX@ -CNTVER := fossil-@FOSSIL_CI_PFX@ -CENGINE := docker -container: - $(CENGINE) image inspect $(IMGVER) > /dev/null 2>&1 || \ - $(MAKE) container-image - $(CENGINE) container inspect $(CNTVER) > /dev/null 2>&1 || \ - $(CENGINE) create \ - --name $(CNTVER) \ - --cap-drop AUDIT_WRITE \ - --cap-drop CHOWN \ - --cap-drop FSETID \ - --cap-drop KILL \ - --cap-drop MKNOD \ - --cap-drop NET_BIND_SERVICE \ - --cap-drop NET_RAW \ - --cap-drop SETFCAP \ - --cap-drop SETPCAP \ - --publish 8080:8080 \ - $(DCFLAGS) $(IMGVER) $(DCCMD) - -container-clean: - -$(CENGINE) container kill $(CNTVER) - -$(CENGINE) container rm $(CNTVER) - -$(CENGINE) image rm $(IMGVER) - -container-image: - $(APPNAME) tarball --name src @FOSSIL_CI_PFX@ $(SRCTB) - $(CENGINE) buildx build \ - --load \ - --tag $(IMGVER) \ - --build-arg FSLURL=$(SRCTB) \ - $(DBFLAGS) @srcdir@ - rm -f $(SRCTB) - -container-run container-start: container - $(CENGINE) start $(DSFLAGS) $(CNTVER) - @sleep 1 # decrease likelihood of logging race condition - $(CENGINE) container logs $(CNTVER) - -container-stop: - $(CENGINE) stop $(CNTVER) - -container-version: - @echo $(CNTVER) Index: Makefile.osx-jaguar ================================================================== --- Makefile.osx-jaguar +++ Makefile.osx-jaguar @@ -38,11 +38,11 @@ BCCFLAGS = $(CFLAGS) #### The suffix to add to final executable file. When cross-compiling # to windows, make this ".exe". Otherwise leave it blank. # -E = +E = TCC = cc TCCFLAGS = $(CFLAGS) #### Tcl shell for use in running the fossil testsuite. If you do not @@ -57,15 +57,17 @@ TCC += -DSQLITE_WITHOUT_ZONEMALLOC TCC += -D_BSD_SOURCE=1 TCC += -DWITHOUT_ICONV TCC += -Dsocklen_t=int TCC += -DSQLITE_MAX_MMAP_SIZE=0 +TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 INSTALLDIR = $(DESTDIR)/usr/local/bin -USE_SYSTEM_SQLITE = +USE_SYSTEM_SQLITE = USE_LINENOISE = 1 # FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@ FOSSIL_ENABLE_TCL = 0 +FOSSIL_ENABLE_MINIZ = 0 include $(SRCDIR)/main.mk distclean: clean rm -f autoconfig.h config.log Makefile DELETED README.md Index: README.md ================================================================== --- README.md +++ README.md @@ -1,15 +0,0 @@ -# About Fossil - -Fossil is a distributed version control system that has been widely -used since 2007. Fossil was originally designed to support the -[SQLite](https://sqlite.org) project but has been adopted by many other -projects as well. - -Fossil is self-hosting at . - -If you are reading this on GitHub, then you are looking at a Git mirror -of the self-hosting Fossil repository. The purpose of that mirror is to -test and exercise Fossil's ability to export a Git mirror. Nobody much -uses the GitHub mirror, except to verify that the mirror logic works. If -you want to know more about Fossil, visit the official self-hosting site -linked above. Index: VERSION ================================================================== --- VERSION +++ VERSION @@ -1,1 +1,1 @@ -2.23 +2.7 ADDED ajax/README Index: ajax/README ================================================================== --- ajax/README +++ ajax/README @@ -0,0 +1,38 @@ +This is the README for how to set up the Fossil/JSON test web page +under Apache on Unix systems. This is only intended only for +Fossil/JSON developers/tinkerers: + +First, copy cgi-bin/fossil-json.cgi.example to +cgi-bin/fossil-json.cgi. Edit it and correct the paths to the fossil +binary and the repo you want to serve. Make it executable. + +MAKE SURE that the fossil repo you use is world-writable OR that your +Web/CGI server is set up to run as the user ID of the owner of the +fossil file. ALSO: the DIRECTORY CONTAINING the repo file must be +writable by the CGI process. + +Next, set up an apache vhost entry. Mine looks like: + + + ServerAlias fjson + ScriptAlias /cgi-bin/ /home/stephan/cvs/fossil/fossil-json/ajax/cgi-bin/ + DocumentRoot /home/stephan/cvs/fossil/fossil-json/ajax + + +Now add your preferred vhost name (fjson in the above example) to /etc/hosts: + + 127.0.0.1 ...other aliases... fjson + +Restart your Apache. + +Now visit: http://fjson/ + +that will show the test/demo page. If it doesn't, edit index.html and +make sure that: + + WhAjaj.Connector.options.ajax.url = ...; + +points to your CGI script. In theory you can also do this over fossil +standalone server mode, but i haven't yet tested that particular test +page in that mode. + ADDED ajax/cgi-bin/fossil-json.cgi.example Index: ajax/cgi-bin/fossil-json.cgi.example ================================================================== --- ajax/cgi-bin/fossil-json.cgi.example +++ ajax/cgi-bin/fossil-json.cgi.example @@ -0,0 +1,2 @@ +#!/path/to/fossil/binary +repository: /path/to/repo.fsl ADDED ajax/i-test/rhino-shell.js Index: ajax/i-test/rhino-shell.js ================================================================== --- ajax/i-test/rhino-shell.js +++ ajax/i-test/rhino-shell.js @@ -0,0 +1,208 @@ +var FShell = { + serverUrl: + 'http://localhost:8080' + //'http://fjson/cgi-bin/fossil-json.cgi' + //'http://192.168.1.62:8080' + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' + , + verbose:false, + prompt:"fossil shell > ", + wiki:{}, + consol:java.lang.System.console(), + v:function(msg){ + if(this.verbose){ + print("VERBOSE: "+msg); + } + } +}; +(function bootstrap() { + var srcdir = '../js/'; + var includes = [srcdir+'json2.js', + srcdir+'whajaj.js', + srcdir+'fossil-ajaj.js' + ]; + for( var i in includes ) { + load(includes[i]); + } + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; + FShell.fossil = new FossilAjaj({ + asynchronous:false, /* rhino-based impl doesn't support async. */ + timeout:10000, + url:FShell.serverUrl + }); + print("Server: "+FShell.serverUrl); + var cb = FShell.fossil.ajaj.callbacks; + cb.beforeSend = function(req,opt){ + if(!FShell.verbose) return; + print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); + if(req) print("Request envelope="+WhAjaj.stringify(req)); + }; + cb.afterSend = function(req,opt){ + //if(!FShell.verbose) return; + //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); + //if(req) print("Request="+WhAjaj.stringify(req)); + }; + cb.onError = function(req,opt){ + //if(!FShell.verbose) return; + print("ERROR: "+WhAjaj.stringify(opt)); + }; + cb.onResponse = function(resp,req){ + if(!FShell.verbose) return; + if(resp && resp.resultCode){ + print("Response contains error info: "+resp.resultCode+": "+resp.resultText); + } + print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); + }; + FShell.fossil.HAI({ + onResponse:function(resp,opt){ + assertResponseOK(resp); + } + }); +})(); + +/** + Throws an exception of cond is a falsy value. +*/ +function assert(cond, descr){ + descr = descr || "Undescribed condition."; + if(!cond){ + throw new Error("Assertion failed: "+descr); + }else{ + //print("Assertion OK: "+descr); + } +} + +/** + Convenience form of FShell.fossil.sendCommand(command,payload,ajajOpt). +*/ +function send(command,payload, ajajOpt){ + FShell.fossil.sendCommand(command,payload,ajajOpt); +} + +/** + Asserts that resp is-a Object, resp.fossil is-a string, and + !resp.resultCode. +*/ +function assertResponseOK(resp){ + assert('object' === typeof resp,'Response is-a object.'); + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); + assert( !resp.resultCode, 'resp.resultCode='+resp.resultCode); +} +/** + Asserts that resp is-a Object, resp.fossil is-a string, and + resp.resultCode is a truthy value. If expectCode is set then + it also asserts that (resp.resultCode=='FOSSIL-'+expectCode). +*/ +function assertResponseError(resp,expectCode){ + assert('object' === typeof resp,'Response is-a object.'); + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); + assert( resp.resultCode, 'resp.resultCode='+resp.resultCode); + if(expectCode){ + assert( 'FOSSIL-'+expectCode == resp.resultCode, 'Expecting result code '+expectCode ); + } +} + +FShell.readline = (typeof readline === 'function') ? (readline) : (function() { + importPackage(java.io); + importPackage(java.lang); + var stdin = new BufferedReader(new InputStreamReader(System['in'])); + var self = this; + return function(prompt) { + if(prompt) print(prompt); + var x = stdin.readLine(); + return null===x ? x : String(x) /*convert to JS string!*/; + }; +}()); + +FShell.dispatchLine = function(line){ + var av = line.split(' '); // FIXME: to shell-like tokenization. Too tired! + var cmd = av[0]; + var key, h; + if('/' == cmd[0]) key = '/'; + else key = this.commandAliases[cmd]; + if(!key) key = cmd; + h = this.commandHandlers[key]; + if(!h){ + print("Command not known: "+cmd +" ("+key+")"); + }else if(!WhAjaj.isFunction(h)){ + print("Not a function: "+key); + } + else{ + print("Sending ["+key+"] command... "); + try{h(av);} + catch(e){ print("EXCEPTION: "+e); } + } +}; + +FShell.onResponseDefault = function(callback){ + return function(resp,req){ + assertResponseOK(resp); + print("Payload: "+(resp.payload ? WhAjaj.stringify(resp.payload) : "none")); + if(WhAjaj.isFunction(callback)){ + callback(resp,req); + } + }; +}; +FShell.commandHandlers = { + "?":function(args){ + var k; + print("Available commands...\n"); + var o = FShell.commandHandlers; + for(k in o){ + if(! o.hasOwnProperty(k)) continue; + print("\t"+k); + } + }, + "/":function(args){ + FShell.fossil.sendCommand('/json'+args[0],undefined,{ + beforeSend:function(req,opt){ + print("Sending to: "+opt.url); + }, + onResponse:FShell.onResponseDefault() + }); + }, + "eval":function(args){ + eval(args.join(' ')); + }, + "login":function(args){ + FShell.fossil.login(args[1], args[2], { + onResponse:FShell.onResponseDefault() + }); + }, + "whoami":function(args){ + FShell.fossil.whoami({ + onResponse:FShell.onResponseDefault() + }); + }, + "HAI":function(args){ + FShell.fossil.HAI({ + onResponse:FShell.onResponseDefault() + }); + } + +}; +FShell.commandAliases = { + "li":"login", + "lo":"logout", + "who":"whoami", + "hi":"HAI", + "tci":"/timeline/ci?limit=3" +}; +FShell.mainLoop = function(){ + var line; + var check = /\S/; + //var isJavaNull = /java\.lang\.null/; + //print(typeof java.lang['null']); + while( null != (line=this.readline(this.prompt)) ){ + if(null===line) break /*EOF*/; + else if( "" === line ) continue; + //print("Got line: "+line); + else if(!check.test(line)) continue; + print('typeof line = '+typeof line); + this.dispatchLine(line); + print(""); + } + print("Bye!"); +}; + +FShell.mainLoop(); ADDED ajax/i-test/rhino-test.js Index: ajax/i-test/rhino-test.js ================================================================== --- ajax/i-test/rhino-test.js +++ ajax/i-test/rhino-test.js @@ -0,0 +1,279 @@ +var TestApp = { + serverUrl: + 'http://localhost:8080' + //'http://fjson/cgi-bin/fossil-json.cgi' + //'http://192.168.1.62:8080' + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' + , + verbose:true, + fossilBinary:'fossil', + wiki:{} +}; +(function bootstrap() { + var srcdir = '../js/'; + var includes = [srcdir+'json2.js', + srcdir+'whajaj.js', + srcdir+'fossil-ajaj.js' + ]; + for( var i in includes ) { + load(includes[i]); + } + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; + TestApp.fossil = new FossilAjaj({ + asynchronous:false, /* rhino-based impl doesn't support async or timeout. */ + timeout:0, + url:TestApp.serverUrl, + fossilBinary:TestApp.fossilBinary + }); + var cb = TestApp.fossil.ajaj.callbacks; + cb.beforeSend = function(req,opt){ + if(!TestApp.verbose) return; + print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); + if(req) print("Request envelope="+WhAjaj.stringify(req)); + }; + cb.afterSend = function(req,opt){ + //if(!TestApp.verbose) return; + //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); + //if(req) print("Request="+WhAjaj.stringify(req)); + }; + cb.onError = function(req,opt){ + if(!TestApp.verbose) return; + print("ERROR: "+WhAjaj.stringify(opt)); + }; + cb.onResponse = function(resp,req){ + if(!TestApp.verbose) return; + print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); + }; + +})(); + +/** + Throws an exception of cond is a falsy value. +*/ +function assert(cond, descr){ + descr = descr || "Undescribed condition."; + if(!cond){ + print("Assertion FAILED: "+descr); + throw new Error("Assertion failed: "+descr); + // aarrgghh. Exceptions are of course swallowed by + // the AJAX layer, to keep from killing a browser's + // script environment. + }else{ + if(TestApp.verbose) print("Assertion OK: "+descr); + } +} + +/** + Calls func() in a try/catch block and throws an exception if + func() does NOT throw. +*/ +function assertThrows(func, descr){ + descr = descr || "Undescribed condition failed."; + var ex; + try{ + func(); + }catch(e){ + ex = e; + } + if(!ex){ + throw new Error("Function did not throw (as expected): "+descr); + }else{ + if(TestApp.verbose) print("Function threw (as expected): "+descr+": "+ex); + } +} + +/** + Convenience form of TestApp.fossil.sendCommand(command,payload,ajajOpt). +*/ +function send(command,payload, ajajOpt){ + TestApp.fossil.sendCommand(command,payload,ajajOpt); +} + +/** + Asserts that resp is-a Object, resp.fossil is-a string, and + !resp.resultCode. +*/ +function assertResponseOK(resp){ + assert('object' === typeof resp,'Response is-a object.'); + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); + assert( undefined === resp.resultCode, 'resp.resultCode is not set'); +} +/** + Asserts that resp is-a Object, resp.fossil is-a string, and + resp.resultCode is a truthy value. If expectCode is set then + it also asserts that (resp.resultCode=='FOSSIL-'+expectCode). +*/ +function assertResponseError(resp,expectCode){ + assert('object' === typeof resp,'Response is-a object.'); + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); + assert( !!resp.resultCode, 'resp.resultCode='+resp.resultCode); + if(expectCode){ + assert( 'FOSSIL-'+expectCode == resp.resultCode, 'Expecting result code '+expectCode ); + } +} + +function testHAI(){ + var rs; + TestApp.fossil.HAI({ + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseOK(rs); + TestApp.serverVersion = rs.fossil; + assert( 'string' === typeof TestApp.serverVersion, 'server version = '+TestApp.serverVersion); +} +testHAI.description = 'Get server version info.'; + +function testIAmNobody(){ + TestApp.fossil.whoami('/json/whoami'); + assert('nobody' === TestApp.fossil.auth.name, 'User == nobody.' ); + assert(!TestApp.fossil.auth.authToken, 'authToken is not set.' ); + +} +testIAmNobody.description = 'Ensure that current user is "nobody".'; + + +function testAnonymousLogin(){ + TestApp.fossil.login(); + assert('string' === typeof TestApp.fossil.auth.authToken, 'authToken = '+TestApp.fossil.auth.authToken); + assert( 'string' === typeof TestApp.fossil.auth.name, 'User name = '+TestApp.fossil.auth.name); + TestApp.fossil.userName = null; + TestApp.fossil.whoami('/json/whoami'); + assert( 'string' === typeof TestApp.fossil.auth.name, 'User name = '+TestApp.fossil.auth.name); +} +testAnonymousLogin.description = 'Perform anonymous login.'; + +function testAnonWiki(){ + var rs; + TestApp.fossil.sendCommand('/json/wiki/list',undefined,{ + beforeSend:function(req,opt){ + assert( req && (req.authToken==TestApp.fossil.auth.authToken), 'Request envelope contains expected authToken.' ); + }, + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseOK(rs); + assert( (typeof [] === typeof rs.payload) && rs.payload.length, + "Wiki list seems to be okay."); + TestApp.wiki.list = rs.payload; + + TestApp.fossil.sendCommand('/json/wiki/get',{ + name:TestApp.wiki.list[0] + },{ + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseOK(rs); + assert(rs.payload.name == TestApp.wiki.list[0], "Fetched page name matches expectations."); + print("Got first wiki page: "+WhAjaj.stringify(rs.payload)); + +} +testAnonWiki.description = 'Fetch wiki list as anonymous user.'; + +function testFetchCheckinArtifact(){ + var art = '18dd383e5e7684ece'; + var rs; + TestApp.fossil.sendCommand('/json/artifact',{ + 'name': art + }, + { + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseOK(rs); + assert(3 == rs.payload.parents.length, 'Got 3 parent artifacts.'); +} +testFetchCheckinArtifact.description = '/json/artifact/CHECKIN'; + +function testAnonLogout(){ + var rs; + TestApp.fossil.logout({ + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseOK(rs); + print("Ensure that second logout attempt fails..."); + TestApp.fossil.logout({ + onResponse:function(resp,req){ + rs = resp; + } + }); + assertResponseError(rs); +} +testAnonLogout.description = 'Log out anonymous user.'; + +function testExternalProcess(){ + + var req = { command:"HAI", requestId:'testExternalProcess()' }; + var args = [TestApp.fossilBinary, 'json', '--json-input', '-']; + var p = java.lang.Runtime.getRuntime().exec(args); + var outs = p.getOutputStream(); + var osr = new java.io.OutputStreamWriter(outs); + var osb = new java.io.BufferedWriter(osr); + var json = JSON.stringify(req); + osb.write(json,0, json.length); + osb.close(); + req = json = outs = osr = osb = undefined; + var ins = p.getInputStream(); + var isr = new java.io.InputStreamReader(ins); + var br = new java.io.BufferedReader(isr); + var line; + + while( null !== (line=br.readLine())){ + print(line); + } + br.close(); + isr.close(); + ins.close(); + p.waitFor(); +} +testExternalProcess.description = 'Run fossil as external process.'; + +function testExternalProcessHandler(){ + var aj = TestApp.fossil.ajaj; + var oldImpl = aj.sendImpl; + aj.sendImpl = FossilAjaj.rhinoLocalBinarySendImpl; + var rs; + TestApp.fossil.sendCommand('/json/HAI',undefined,{ + onResponse:function(resp,opt){ + rs = resp; + } + }); + aj.sendImpl = oldImpl; + assertResponseOK(rs); + print("Using local fossil binary via AJAX interface, we fetched: "+ + WhAjaj.stringify(rs)); +} +testExternalProcessHandler.description = 'Try local fossil binary via AJAX interface.'; + +(function runAllTests(){ + var testList = [ + testHAI, + testIAmNobody, + testAnonymousLogin, + testAnonWiki, + testFetchCheckinArtifact, + testAnonLogout, + testExternalProcess, + testExternalProcessHandler + ]; + var i, f; + for( i = 0; i < testList.length; ++i ){ + f = testList[i]; + try{ + print("Running test #"+(i+1)+": "+(f.description || "no description.")); + f(); + }catch(e){ + print("Test #"+(i+1)+" failed: "+e); + throw e; + } + } + +})(); + +print("Done! If you don't see an exception message in the last few lines, you win!"); ADDED ajax/index.html Index: ajax/index.html ================================================================== --- ajax/index.html +++ ajax/index.html @@ -0,0 +1,332 @@ + + + + + Fossil/JSON raw request sending + + + + + + + + + + + + + +
+

You know, for sending raw JSON requests to Fossil...

+ +If you're actually using this page, then you know what you're doing and don't +need help text, hoverhelp, and a snazzy interface. + +

+ + +JSON API docs: https://docs.google.com/document/d/1fXViveNhDbiXgCuE7QDXQOKeFzf2qNUkBEgiUvoqFN4/edit + +
+See also: prototype wiki editor. + +

Request...

+ +Path: +
+If the POST textarea is not empty then it will be posted with the request. +
+Quick-posts:
+ + + + + + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+Login: +
+ + +
+name: +pw: + + +
+ + +
+ +
+ + + + + + + + + + + + + + + + +
POST dataRequest AJAJ options
+ + + +
Response
+ +
+
+
+
+ + ADDED ajax/js/fossil-ajaj.js Index: ajax/js/fossil-ajaj.js ================================================================== --- ajax/js/fossil-ajaj.js +++ ajax/js/fossil-ajaj.js @@ -0,0 +1,274 @@ +/** + This file contains a WhAjaj extension for use with Fossil/JSON. + + Author: Stephan Beal (sgbeal@googlemail.com) + + License: Public Domain +*/ + +/** + Constructor for a new Fossil AJAJ client. ajajOpt may be an optional + object suitable for passing to the WhAjaj.Connector() constructor. + + On returning, this.ajaj is-a WhAjaj.Connector instance which can + be used to send requests to the back-end (though the convenience + functions of this class are the preferred way to do it). Clients + are encouraged to use FossilAjaj.sendCommand() (and friends) instead + of the underlying WhAjaj.Connector API, since this class' API + contains Fossil-specific request-calling handling (e.g. of authentication + info) whereas WhAjaj is more generic. +*/ +function FossilAjaj(ajajOpt) +{ + this.ajaj = new WhAjaj.Connector(ajajOpt); + return this; +} + +FossilAjaj.prototype.generateRequestId = function() { + return this.ajaj.generateRequestId(); +}; + +/** + Proxy for this.ajaj.sendRequest(). +*/ +FossilAjaj.prototype.sendRequest = function(req,opt) { + return this.ajaj.sendRequest(req,opt); +}; + +/** + Sends a command to the fossil back-end. Command should be the + path part of the URL, e.g. /json/stat, payload is a request-specific + value type (may often be null/undefined). ajajOpt is an optional object + holding WhAjaj.sendRequest()-compatible options. + + This function constructs a Fossil/JSON request envelope based + on the given arguments and adds this.auth.authToken and a requestId + to it. +*/ +FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { + var req; + ajajOpt = ajajOpt || {}; + if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { + req = { + payload:payload, + requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, + authToken:(this.auth ? this.auth.authToken : undefined), + jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined + }; + } + ajajOpt.method = req ? 'POST' : 'GET'; + // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; + if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; + this.ajaj.sendRequest(req,ajajOpt); +}; + +/** + Sends a login request to the back-end. + + ajajOpt is an optional configuration object suitable for passing + to sendCommand(). + + After the response returns, this.auth will be + set to the response payload. + + If name === 'anonymous' (the default if none is passed in) then this + function ignores the pw argument and must make two requests - the first + one gets the captcha code and the second one submits it. + ajajOpt.onResponse() (if set) is only called for the actual login + response (the 2nd one), as opposed to being called for both requests. + However, this.ajaj.callbacks.onResponse() _is_ called for both (because + it happens at a lower level). + + If this object has an onLogin() function it is called (with + no arguments) before the onResponse() handler of the login is called + (that is the 2nd request for anonymous logins) and any exceptions + it throws are ignored. + +*/ +FossilAjaj.prototype.login = function(name,pw,ajajOpt) { + name = name || 'anonymous'; + var self = this; + var loginReq = { + name:name, + password:pw + }; + ajajOpt = this.ajaj.normalizeAjaxParameters( ajajOpt || {} ); + var oldOnResponse = ajajOpt.onResponse; + ajajOpt.onResponse = function(resp,req) { + var thisOpt = this; + //alert('login response:\n'+WhAjaj.stringify(resp)); + if( resp && resp.payload ) { + //self.userName = resp.payload.name; + //self.capabilities = resp.payload.capabilities; + self.auth = resp.payload; + } + if( WhAjaj.isFunction( self.onLogin ) ){ + try{ self.onLogin(); } + catch(e){} + } + if( WhAjaj.isFunction(oldOnResponse) ) { + oldOnResponse.apply(thisOpt,[resp,req]); + } + }; + function doLogin(){ + //alert("Sending login request..."+WhAjaj.stringify(loginReq)); + self.sendCommand('/json/login', loginReq, ajajOpt); + } + if( 'anonymous' === name ){ + this.sendCommand('/json/anonymousPassword',undefined,{ + onResponse:function(resp,req){ +/* + if( WhAjaj.isFunction(oldOnResponse) ){ + oldOnResponse.apply(this, [resp,req]); + }; +*/ + if(resp && !resp.resultCode){ + //alert("Got PW. Trying to log in..."+WhAjaj.stringify(resp)); + loginReq.anonymousSeed = resp.payload.seed; + loginReq.password = resp.payload.password; + doLogin(); + } + } + }); + } + else doLogin(); +}; + +/** + Logs out of fossil, invaliding this login token. + + ajajOpt is an optional configuration object suitable for passing + to sendCommand(). + + If this object has an onLogout() function it is called (with + no arguments) before the onResponse() handler is called. + IFF the response succeeds then this.auth is unset. +*/ +FossilAjaj.prototype.logout = function(ajajOpt) { + var self = this; + ajajOpt = this.ajaj.normalizeAjaxParameters( ajajOpt || {} ); + var oldOnResponse = ajajOpt.onResponse; + ajajOpt.onResponse = function(resp,req) { + var thisOpt = this; + self.auth = undefined; + if( WhAjaj.isFunction( self.onLogout ) ){ + try{ self.onLogout(); } + catch(e){} + } + if( WhAjaj.isFunction(oldOnResponse) ) { + oldOnResponse.apply(thisOpt,[resp,req]); + } + }; + this.sendCommand('/json/logout', undefined, ajajOpt ); +}; + +/** + Sends a HAI request to the server. /json/HAI is an alias /json/version. + + ajajOpt is an optional configuration object suitable for passing + to sendCommand(). +*/ +FossilAjaj.prototype.HAI = function(ajajOpt) { + this.sendCommand('/json/HAI', undefined, ajajOpt); +}; + + +/** + Sends a /json/whoami request. Updates this.auth to contain + the login info, removing them if the response does not contain + that data. +*/ +FossilAjaj.prototype.whoami = function(ajajOpt) { + var self = this; + ajajOpt = this.ajaj.normalizeAjaxParameters( ajajOpt || {} ); + var oldOnResponse = ajajOpt.onResponse; + ajajOpt.onResponse = function(resp,req) { + var thisOpt = this; + if( resp && resp.payload ){ + if(!self.auth || (self.auth.authToken!==resp.payload.authToken)){ + self.auth = resp.payload; + if( WhAjaj.isFunction(self.onLogin) ){ + self.onLogin(); + } + } + } + else { delete self.auth; } + if( WhAjaj.isFunction(oldOnResponse) ) { + oldOnResponse.apply(thisOpt,[resp,req]); + } + }; + self.sendCommand('/json/whoami', undefined, ajajOpt); +}; + +/** + EXPERIMENTAL concrete WhAjaj.Connector.sendImpl() implementation which + uses Rhino to connect to a local fossil binary for input and output. Its + signature and semantics are as described for + WhAjaj.Connector.prototype.sendImpl(), with a few exceptions and + additions: + + - It does not support timeouts or asynchronous mode. + + - The args.fossilBinary property must point to the local fossil binary + (it need not be a complete path if fossil is in the $PATH). This + function throws (without calling any request callbacks) if + args.fossilBinary is not set. fossilBinary may be set on + WhAjaj.Connector.options.ajax, in the FossilAjaj constructor call, as + the ajax options parameter to any of the FossilAjaj.sendCommand() family + of functions, or by setting + aFossilAjajInstance.ajaj.options.fossilBinary on a specific + FossilAjaj instance. + + - It uses the args.url field to create the "command" property of the + request, constructs a request envelope, spawns a fossil process in JSON + mode, feeds it the request envelope, and returns the response envelope + via the same mechanisms defined for the HTTP-based implementations. + + The interface is otherwise compatible with the "normal" + FossilAjaj.sendCommand() front-end (it is, however, fossil-specific, and + not back-end agnostic like the WhAjaj.sendImpl() interface intends). + + +*/ +FossilAjaj.rhinoLocalBinarySendImpl = function(request,args){ + var self = this; + request = request || {}; + if(!args.fossilBinary){ + throw new Error("fossilBinary is not set on AJAX options!"); + } + var url = args.url.split('?')[0].split(/\/+/); + if(url.length>1){ + // 3x shift(): protocol, host, 'json' part of path + request.command = (url.shift(),url.shift(),url.shift(), url.join('/')); + } + delete args.url; + //print("rhinoLocalBinarySendImpl SENDING: "+WhAjaj.stringify(request)); + var json; + try{ + var pargs = [args.fossilBinary, 'json', '--json-input', '-']; + var p = java.lang.Runtime.getRuntime().exec(pargs); + var outs = p.getOutputStream(); + var osr = new java.io.OutputStreamWriter(outs); + var osb = new java.io.BufferedWriter(osr); + + json = JSON.stringify(request); + osb.write(json,0, json.length); + osb.close(); + var ins = p.getInputStream(); + var isr = new java.io.InputStreamReader(ins); + var br = new java.io.BufferedReader(isr); + var line; + json = []; + while( null !== (line=br.readLine())){ + json.push(line); + } + ins.close(); + }catch(e){ + args.errorMessage = e.toString(); + WhAjaj.Connector.sendHelper.onSendError.apply( self, [request, args] ); + return undefined; + } + json = json.join(''); + //print("READ IN JSON: "+json); + WhAjaj.Connector.sendHelper.onSendSuccess.apply( self, [request, json, args] ); +}/*rhinoLocalBinary*/ ADDED ajax/js/json2.js Index: ajax/js/json2.js ================================================================== --- ajax/js/json2.js +++ ajax/js/json2.js @@ -0,0 +1,476 @@ +/* + http://www.JSON.org/json2.js + 2009-06-29 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the object holding the key. + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. +*/ + +/*jslint evil: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +var JSON = JSON || {}; + +(function () { + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/. +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); ADDED ajax/js/whajaj.js Index: ajax/js/whajaj.js ================================================================== --- ajax/js/whajaj.js +++ ajax/js/whajaj.js @@ -0,0 +1,1221 @@ +/** + This file provides a JS interface into the core functionality of + JSON-centric back-ends. It sends GET or JSON POST requests to + a back-end and expects JSON responses. The exact semantics of + the underlying back-end and overlying front-end are not its concern, + and it leaves the interpretation of the data up to the client/server + insofar as possible. + + All functionality is part of a class named WhAjaj, and that class + acts as namespace for this framework. + + Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) + + License: Public Domain + + This framework is directly derived from code originally found in + http://code.google.com/p/jsonmessage, and later in + http://whiki.wanderinghorse.net, where it contained quite a bit + of application-specific logic. It was eventually (the 3rd time i + needed it) split off into its own library to simplify inclusion + into my many mini-projects. +*/ + + +/** + The WhAjaj function is primarily a namespace, and not intended + to called or instantiated via the 'new' operator. +*/ +function WhAjaj() +{ +} + +/** Returns a millisecond Unix Epoch timestamp. */ +WhAjaj.msTimestamp = function() +{ + return (new Date()).getTime(); +}; + +/** Returns a Unix Epoch timestamp (in seconds) in integer format. + + Reminder to self: (1.1 %1.2) evaluates to a floating-point value + in JS, and thus this implementation is less than optimal. +*/ +WhAjaj.unixTimestamp = function() +{ + var ts = (new Date()).getTime(); + return parseInt( ""+((ts / 1000) % ts) ); +}; + +/** + Returns true if v is-a Array instance. +*/ +WhAjaj.isArray = function( v ) +{ + return (v && + (v instanceof Array) || + (Object.prototype.toString.call(v) === "[object Array]") + ); + /* Reminders to self: + typeof [] == "object" + toString.call([]) == "[object Array]" + ([]).toString() == empty + */ +}; + +/** + Returns true if v is-a Object instance. +*/ +WhAjaj.isObject = function( v ) +{ + return v && + (v instanceof Object) && + ('[object Object]' === Object.prototype.toString.apply(v) ); +}; + +/** + Returns true if v is-a Function instance. +*/ +WhAjaj.isFunction = function(obj) +{ + return obj + && ( + (obj instanceof Function) + || ('function' === typeof obj) + || ("[object Function]" === Object.prototype.toString.call(obj)) + ) + ; +}; + +/** + Parses window.location.search-style string into an object + containing key/value pairs of URL arguments (already urldecoded). + + If the str argument is not passed (arguments.length==0) then + window.location.search.substring(1) is used by default. If + neither str is passed in nor window exists then false is returned. + + On success it returns an Object containing the key/value pairs + parsed from the string. Keys which have no value are treated + has having the boolean true value. + + FIXME: for keys in the form "name[]", build an array of results, + like PHP does. + +*/ +WhAjaj.processUrlArgs = function(str) { + if( 0 === arguments.length ) { + if( ('undefined' === typeof window) || + !window.location || + !window.location.search ) return false; + else str = (''+window.location.search).substring(1); + } + if( ! str ) return false; + str = (''+str).split(/#/,2)[0]; // remove #... to avoid it being added as part of the last value. + var args = {}; + var sp = str.split(/&+/); + var rx = /^([^=]+)(=(.+))?/; + var i, m; + for( i in sp ) { + m = rx.exec( sp[i] ); + if( ! m ) continue; + args[decodeURIComponent(m[1])] = (m[3] ? decodeURIComponent(m[3]) : true); + } + return args; +}; + +/** + A simple wrapper around JSON.stringify(), using my own personal + preferred values for the 2nd and 3rd parameters. To globally + set its indentation level, assign WhAjaj.stringify.indent to + an integer value (0 for no intendation). + + This function is intended only for human-readable output, not + generic over-the-wire JSON output (where JSON.stringify(val) will + produce smaller results). +*/ +WhAjaj.stringify = function(val) { + if( ! arguments.callee.indent ) arguments.callee.indent = 4; + return JSON.stringify(val,0,arguments.callee.indent); +}; + +/** + Each instance of this class holds state information for making + AJAJ requests to a back-end system. While clients may use one + "requester" object per connection attempt, for connections to the + same back-end, using an instance configured for that back-end + can simplify usage. This class is designed so that the actual + connection-related details (i.e. _how_ it connects to the + back-end) may be re-implemented to use a client's preferred + connection mechanism (e.g. jQuery). + + The optional opt parameter may be an object with any (or all) of + the properties documented for WhAjaj.Connector.options.ajax. + Properties set here (or later via modification of the "options" + property of this object) will be used in calls to + WhAjaj.Connector.sendRequest(), and these override (normally) any + options set in WhAjaj.Connector.options.ajax. Note that + WhAjaj.Connector.sendRequest() _also_ takes an options object, + and ones passed there will override, for purposes of that one + request, any options passed in here or defined in + WhAjaj.Connector.options.ajax. See WhAjaj.Connector.options.ajax + and WhAjaj.Connector.prototype.sendRequest() for more details + about the precedence of options. + + Sample usage: + + @code + // Set up common connection-level options: + var cgi = new WhAjaj.Connector({ + url: '/cgi-bin/my.cgi', + timeout:10000, + onResponse(resp,req) { alert(JSON.stringify(resp,0.4)); }, + onError(req,opt) { + alert(opt.errorMessage); + } + }); + // Any of those options may optionally be set globally in + // WhAjaj.Connector.options.ajax (onError(), beforeSend(), and afterSend() + // are often easiest/most useful to set globally). + + // Get list of pages... + cgi.sendRequest( null, { + onResponse(resp,req){ alert(WhAjaj.stringify(resp)); } + }); + @endcode + + For common request types, clients can add functions to this + object which act as wrappers for backend-specific functionality. As + a simple example: + + @code + cgi.login = function(name,pw,ajajOpt) { + this.sendRequest( + {command:"json/login", + name:name, + password:pw + }, ajajOpt ); + }; + @endcode + + TODOs: + + - Caching of page-load requests, with a configurable lifetime. + + - Use-cases like the above login() function are a tiny bit + problematic to implement when each request has a different URL + path (i know this from the whiki and fossil implementations). + This is partly a side-effect of design descisions made back in + the very first days of this code's life. i need to go through + and see where i can bend those conventions a bit (where it won't + break my other apps unduly). +*/ +WhAjaj.Connector = function(opt) +{ + if(WhAjaj.isObject(opt)) this.options = opt; + //TODO?: this.$cache = {}; +}; + +/** + The core options used by WhAjaj.Connector instances for performing + network operations. These options can (and some _should_) + be changed by a client application. They can also be changed + on specific instances of WhAjaj.Connector, but for most applications + it is simpler to set them here and not have to bother with configuring + each WhAjaj.Connector instance. Apps which use multiple back-ends at one time, + however, will need to customize each instance for a given back-end. +*/ +WhAjaj.Connector.options = { + /** + A (meaningless) prefix to apply to WhAjaj.Connector-generated + request IDs. + */ + requestIdPrefix:'WhAjaj.Connector-', + /** + Default options for WhAjaj.Connector.sendRequest() connection + parameters. This object holds only connection-related + options and callbacks (all optional), and not options + related to the required JSON structure of any given request. + i.e. the page name used in a get-page request are not set + here but are specified as part of the request object. + + These connection options are a "normalized form" of options + often found in various AJAX libraries like jQuery, + Prototype, dojo, etc. This approach allows us to swap out + the real connection-related parts by writing a simple proxy + which transforms our "normalized" form to the + backend-specific form. For examples, see the various + implementations stored in WhAjaj.Connector.sendImpls. + + The following callback options are, in practice, almost + always set globally to some app-wide defaults: + + - onError() to report errors using a common mechanism. + - beforeSend() to start a visual activity notification + - afterSend() to disable the visual activity notification + + However, be aware that if any given WhAjaj.Connector instance is + given its own before/afterSend callback then those will + override these. Mixing shared/global and per-instance + callbacks can potentially lead to confusing results if, e.g., + the beforeSend() and afterSend() functions have side-effects + but are not used with their proper before/after partner. + + TODO: rename this to 'ajaj' (the name is historical). The + problem with renaming it is is that the word 'ajax' is + pretty prevelant in the source tree, so i can't globally + swap it out. + */ + ajax: { + /** + URL of the back-end server/CGI. + */ + url: '/some/path', + + /** + Connection method. Some connection-related functions might + override any client-defined setting. + + Must be one of 'GET' or 'POST'. For custom connection + implementation, it may optionally be some + implementation-specified value. + + Normally the API can derive this value automatically - if the + request uses JSON data it is POSTed, else it is GETted. + */ + method:'GET', + + /** + A hint whether to run the operation asynchronously or + not. Not all concrete WhAjaj.Connector.sendImpl() + implementations can support this. Interestingly, at + least one popular AJAX toolkit does not document + supporting _synchronous_ AJAX operations. All common + browser-side implementations support async operation, but + non-browser implementations might not. + */ + asynchronous:true, + + /** + A HTTP authentication login name for the AJAX + connection. Not all concrete WhAjaj.Connector.sendImpl() + implementations can support this. + */ + loginName:undefined, + + /** + An HTTP authentication login password for the AJAJ + connection. Not all concrete WhAjaj.Connector.sendImpl() + implementations can support this. + */ + loginPassword:undefined, + + /** + A connection timeout, in milliseconds, for establishing + an AJAJ connection. Not all concrete + WhAjaj.Connector.sendImpl() implementations can support this. + */ + timeout:10000, + + /** + If an AJAJ request receives JSON data from the back-end, + that data is passed as a plain Object as the response + parameter (exception: in jsonp mode it is passed a + string (why???)). The initiating request object is + passed as the second parameter, but clients can normally + ignore it (only those which need a way to map specific + requests to responses will need it). The 3rd parameter + is the same as the 'this' object for the context of the + callback, but is provided because the instance-level + callbacks (set in (WhAjaj.Connector instance).callbacks, + require it in some cases (because their 'this' is + different!). + + Note that the response might contain error information + which comes from the back-end. The difference between + this error info and the info passed to the onError() + callback is that this data indicates an + application-level error, whereas onError() is used to + report connection-level problems or when the backend + produces non-JSON data (which, when not in jsonp mode, + is unexpected and is as fatal to the request as a + connection error). + */ + onResponse: function(response, request, opt){}, + + /** + If an AJAX request fails to establish a connection or it + receives non-JSON data from the back-end, this function + is called (e.g. timeout error or host name not + resolvable). It is passed the originating request and the + "normalized" connection parameters used for that + request. The connectOpt object "should" (or "might") + have an "errorMessage" property which describes the + nature of the problem. + + Clients will almost always want to replace the default + implementation with something which integrates into + their application. + */ + onError: function(request, connectOpt) + { + alert('AJAJ request failed:\n' + +'Connection information:\n' + +JSON.stringify(connectOpt,0,4) + ); + }, + + /** + Called before each connection attempt is made. Clients + can use this to, e.g., enable a visual "network activity + notification" for the user. It is passed the original + request object and the normalized connection parameters + for the request. If this function changes opt, those + changes _are_ applied to the subsequent request. If this + function throws, neither the onError() nor afterSend() + callbacks are triggered and WhAjaj.Connector.sendImpl() + propagates the exception back to the caller. + */ + beforeSend: function(request,opt){}, + + /** + Called after an AJAJ connection attempt completes, + regardless of success or failure. Passed the same + parameters as beforeSend() (see that function for + details). + + Here's an example of setting up a visual notification on + ajax operations using jQuery (but it's also easy to do + without jQuery as well): + + @code + function startAjaxNotif(req,opt) { + var me = arguments.callee; + var c = ++me.ajaxCount; + me.element.text( c + " pending AJAX operation(s)..." ); + if( 1 == c ) me.element.stop().fadeIn(); + } + startAjaxNotif.ajaxCount = 0. + startAjaxNotif.element = jQuery('#whikiAjaxNotification'); + + function endAjaxNotif() { + var c = --startAjaxNotif.ajaxCount; + startAjaxNotif.element.text( c+" pending AJAX operation(s)..." ); + if( 0 == c ) startAjaxNotif.element.stop().fadeOut(); + } + @endcode + + Set the beforeSend/afterSend properties to those + functions to enable the notifications by default. + */ + afterSend: function(request,opt){}, + + /** + If jsonp is a string then the WhAjaj-internal response + handling code ASSUMES that the response contains a JSONP-style + construct and eval()s it after afterSend() but before onResponse(). + In this case, onResponse() will get a string value for the response + instead of a response object parsed from JSON. + */ + jsonp:undefined, + /** + Don't use yet. Planned future option. + */ + propagateExceptions:false + } +}; + + +/** + WhAjaj.Connector.prototype.callbacks defines callbacks analog + to the onXXX callbacks defined in WhAjaj.Connector.options.ajax, + with two notable differences: + + 1) these callbacks, if set, are called in addition to any + request-specific callback. The intention is to allow a framework to set + "framework-level" callbacks which should be called independently of the + request-specific callbacks (without interfering with them, e.g. + requiring special re-forwarding features). + + 2) The 'this' object in these callbacks is the Connector instance + associated with the callback, whereas the "other" onXXX form has its + "ajax options" object as its this. + + When this API says that an onXXX callback will be called for a request, + both the request's onXXX (if set) and this one (if set) will be called. +*/ +WhAjaj.Connector.prototype.callbacks = {}; +/** + Instance-specific values for AJAJ-level properties (as opposed to + application-level request properties). Options set here "override" those + specified in WhAjaj.Connector.options.ajax and are "overridden" by + options passed to sendRequest(). +*/ +WhAjaj.Connector.prototype.options = {}; + + +/** + Tries to find the given key in any of the following, returning + the first match found: opt, this.options, WhAjaj.Connector.options.ajax. + + Returns undefined if key is not found. +*/ +WhAjaj.Connector.prototype.derivedOption = function(key,opt) { + var v = opt ? opt[key] : undefined; + if( undefined !== v ) return v; + else v = this.options[key]; + if( undefined !== v ) return v; + else v = WhAjaj.Connector.options.ajax[key]; + return v; +}; + +/** + Returns a unique string on each call containing a generic + reandom request identifier string. This is not used by the core + API but can be used by client code to generate unique IDs for + each request (if needed). + + The exact format is unspecified and may change in the future. + + Request IDs can be used by clients to "match up" responses to + specific requests if needed. In practice, however, they are + seldom, if ever, needed. When passing several concurrent + requests through the same response callback, it might be useful + for some clients to be able to distinguish, possibly re-routing + them through other handlers based on the originating request type. + + If this.options.requestIdPrefix or + WhAjaj.Connector.options.requestIdPrefix is set then that text + is prefixed to the returned string. +*/ +WhAjaj.Connector.prototype.generateRequestId = function() +{ + if( undefined === arguments.callee.sequence ) + { + arguments.callee.sequence = 0; + } + var pref = this.options.requestIdPrefix || WhAjaj.Connector.options.requestIdPrefix || ''; + return pref + + WhAjaj.msTimestamp() + + '/'+(Math.round( Math.random() * 100000000) )+ + ':'+(++arguments.callee.sequence); +}; + +/** + Copies (SHALLOWLY) all properties in opt to this.options. +*/ +WhAjaj.Connector.prototype.addOptions = function(opt) { + var k, v; + for( k in opt ) { + if( ! opt.hasOwnProperty(k) ) continue /* proactive Prototype kludge! */; + this.options[k] = opt[k]; + } + return this.options; +}; + +/** + An internal helper object which holds several functions intended + to simplify the creation of concrete communication channel + implementations for WhAjaj.Connector.sendImpl(). These operations + take care of some of the more error-prone parts of ensuring that + onResponse(), onError(), etc. callbacks are called consistently + using the same rules. +*/ +WhAjaj.Connector.sendHelper = { + /** + opt is assumed to be a normalized set of + WhAjaj.Connector.sendRequest() options. This function + creates a url by concatenating opt.url and some form of + opt.urlParam. + + If opt.urlParam is an object or string then it is appended + to the url. An object is assumed to be a one-dimensional set + of simple (urlencodable) key/value pairs, and not larger + data structures. A string value is assumed to be a + well-formed, urlencoded set of key/value pairs separated by + '&' characters. + + The new/normalized URL is returned (opt is not modified). If + opt.urlParam is not set then opt.url is returned (or an + empty string if opt.url is itself a false value). + + TODO: if opt is-a Object and any key points to an array, + build up a list of keys in the form "keyname[]". We could + arguably encode sub-objects like "keyname[subkey]=...", but + i don't know if that's conventions-compatible with other + frameworks. + */ + normalizeURL: function(opt) { + var u = opt.url || ''; + if( opt.urlParam ) { + var addQ = (u.indexOf('?') >= 0) ? false : true; + var addA = addQ ? false : ((u.indexOf('&')>=0) ? true : false); + var tail = ''; + if( WhAjaj.isObject(opt.urlParam) ) { + var li = [], k; + for( k in opt.urlParam) { + li.push( k+'='+encodeURIComponent( opt.urlParam[k] ) ); + } + tail = li.join('&'); + } + else if( 'string' === typeof opt.urlParam ) { + tail = opt.urlParam; + } + u = u + (addQ ? '?' : '') + (addA ? '&' : '') + tail; + } + return u; + }, + /** + Should be called by WhAjaj.Connector.sendImpl() + implementations after a response has come back. This + function takes care of most of ensuring that framework-level + conventions involving WhAjaj.Connector.options.ajax + properties are followed. + + The request argument must be the original request passed to + the sendImpl() function. It may legally be null for GET requests. + + The opt object should be the normalized AJAX options used + for the connection. + + The resp argument may be either a plain Object or a string + (in which case it is assumed to be JSON). + + The 'this' object for this call MUST be a WhAjaj.Connector + instance in order for callback processing to work properly. + + This function takes care of the following: + + - Calling opt.afterSend() + + - If resp is a string, de-JSON-izing it to an object. + + - Calling opt.onResponse() + + - Calling opt.onError() in several common (potential) error + cases. + + - If resp is-a String and opt.jsonp then resp is assumed to be + a JSONP-form construct and is eval()d BEFORE opt.onResponse() + is called. It is arguable to eval() it first, but the logic + integrates better with the non-jsonp handler. + + The sendImpl() should return immediately after calling this. + + The sendImpl() must call only one of onSendSuccess() or + onSendError(). It must call one of them or it must implement + its own response/error handling, which is not recommended + because getting the documented semantics of the + onError/onResponse/afterSend handling correct can be tedious. + */ + onSendSuccess:function(request,resp,opt) { + var cb = this.callbacks || {}; + if( WhAjaj.isFunction(cb.afterSend) ) { + try {cb.afterSend( request, opt );} + catch(e){} + } + if( WhAjaj.isFunction(opt.afterSend) ) { + try {opt.afterSend( request, opt );} + catch(e){} + } + function doErr(){ + if( WhAjaj.isFunction(cb.onError) ) { + try {cb.onError( request, opt );} + catch(e){} + } + if( WhAjaj.isFunction(opt.onError) ) { + try {opt.onError( request, opt );} + catch(e){} + } + } + if( ! resp ) { + opt.errorMessage = "Sending of request succeeded but returned no data!"; + doErr(); + return false; + } + + if( 'string' === typeof resp ) { + try { + resp = opt.jsonp ? eval(resp) : JSON.parse(resp); + } catch(e) { + opt.errorMessage = e.toString(); + doErr(); + return; + } + } + try { + if( WhAjaj.isFunction( cb.onResponse ) ) { + cb.onResponse( resp, request, opt ); + } + if( WhAjaj.isFunction( opt.onResponse ) ) { + opt.onResponse( resp, request, opt ); + } + return true; + } + catch(e) { + opt.errorMessage = "Exception while handling inbound JSON response:\n" + + e + +"\nOriginal response data:\n"+JSON.stringify(resp,0,2) + ; + ; + doErr(); + return false; + } + }, + /** + Should be called by sendImpl() implementations after a response + has failed to connect (e.g. could not resolve host or timeout + reached). This function takes care of most of ensuring that + framework-level conventions involving WhAjaj.Connector.options.ajax + properties are followed. + + The request argument must be the original request passed to + the sendImpl() function. It may legally be null for GET + requests. + + The 'this' object for this call MUST be a WhAjaj.Connector + instance in order for callback processing to work properly. + + The opt object should be the normalized AJAX options used + for the connection. By convention, the caller of this + function "should" set opt.errorMessage to contain a + human-readable description of the error. + + The sendImpl() should return immediately after calling this. The + return value from this function is unspecified. + */ + onSendError: function(request,opt) { + var cb = this.callbacks || {}; + if( WhAjaj.isFunction(cb.afterSend) ) { + try {cb.afterSend( request, opt );} + catch(e){} + } + if( WhAjaj.isFunction(opt.afterSend) ) { + try {opt.afterSend( request, opt );} + catch(e){} + } + if( WhAjaj.isFunction( cb.onError ) ) { + try {cb.onError( request, opt );} + catch(e) {/*ignore*/} + } + if( WhAjaj.isFunction( opt.onError ) ) { + try {opt.onError( request, opt );} + catch(e) {/*ignore*/} + } + } +}; + +/** + WhAjaj.Connector.sendImpls holds several concrete + implementations of WhAjaj.Connector.prototype.sendImpl(). To use + a specific implementation by default assign + WhAjaj.Connector.prototype.sendImpl to one of these functions. + + The functions defined here require that the 'this' object be-a + WhAjaj.Connector instance. + + Historical notes: + + a) We once had an implementation based on Prototype, but that + library just pisses me off (they change base-most types' + prototypes, introducing side-effects in client code which + doesn't even use Prototype). The Prototype version at the time + had a serious toJSON() bug which caused empty arrays to + serialize as the string "[]", which broke a bunch of my code. + (That has been fixed in the mean time, but i don't use + Prototype.) + + b) We once had an implementation for the dojo library, + + If/when the time comes to add Prototype/dojo support, we simply + need to port: + + http://code.google.com/p/jsonmessage/source/browse/trunk/lib/JSONMessage/JSONMessage.inc.js + + (search that file for "dojo" and "Prototype") to this tree. That + code is this code's generic grandfather and they are still very + similar, so a port is trivial. + +*/ +WhAjaj.Connector.sendImpls = { + /** + This is a concrete implementation of + WhAjaj.Connector.prototype.sendImpl() which uses the + environment's native XMLHttpRequest class to send whiki + requests and fetch the responses. + + The only argument must be a connection properties object, as + constructed by WhAjaj.Connector.normalizeAjaxParameters(). + + If window.firebug is set then window.firebug.watchXHR() is + called to enable monitoring of the XMLHttpRequest object. + + This implementation honors the loginName and loginPassword + connection parameters. + + Returns the XMLHttpRequest object. + + This implementation requires that the 'this' object be-a + WhAjaj.Connector. + + This implementation uses setTimeout() to implement the + timeout support, and thus the JS engine must provide that + functionality. + */ + XMLHttpRequest: function(request, args) + { + var json = WhAjaj.isObject(request) ? JSON.stringify(request) : request; + var xhr = new XMLHttpRequest(); + var startTime = (new Date()).getTime(); + var timeout = args.timeout || 10000/*arbitrary!*/; + var hitTimeout = false; + var done = false; + var tmid /* setTimeout() ID */; + var whself = this; + function handleTimeout() + { + hitTimeout = true; + if( ! done ) + { + var now = (new Date()).getTime(); + try { xhr.abort(); } catch(e) {/*ignore*/} + // see: http://www.w3.org/TR/XMLHttpRequest/#the-abort-method + args.errorMessage = "Timeout of "+timeout+"ms reached after "+(now-startTime)+"ms during AJAX request."; + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + } + return; + } + function onStateChange() + { // reminder to self: apparently 'this' is-not-a XHR :/ + if( hitTimeout ) + { /* we're too late - the error was already triggered. */ + return; + } + + if( 4 == xhr.readyState ) + { + done = true; + if( tmid ) + { + clearTimeout( tmid ); + tmid = null; + } + if( (xhr.status >= 200) && (xhr.status < 300) ) + { + WhAjaj.Connector.sendHelper.onSendSuccess.apply( whself, [request, xhr.responseText, args] ); + return; + } + else + { + if( undefined === args.errorMessage ) + { + args.errorMessage = "Error sending a '"+args.method+"' AJAX request to " + +"["+args.url+"]: " + +"Status text=["+xhr.statusText+"]" + ; + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + } + else { /*maybe it was was set by the timeout handler. */ } + return; + } + } + }; + + xhr.onreadystatechange = onStateChange; + if( ('undefined'!==(typeof window)) && ('firebug' in window) && ('watchXHR' in window.firebug) ) + { /* plug in to firebug lite's XHR monitor... */ + window.firebug.watchXHR( xhr ); + } + try + { + //alert( JSON.stringify( args )); + function xhrOpen() + { + if( ('loginName' in args) && args.loginName ) + { + xhr.open( args.method, args.url, args.asynchronous, args.loginName, args.loginPassword ); + } + else + { + xhr.open( args.method, args.url, args.asynchronous ); + } + } + if( json && ('POST' === args.method.toUpperCase()) ) + { + xhrOpen(); + xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8"); + // Google Chrome warns that it refuses to set these + // "unsafe" headers (his words, not mine): + // xhr.setRequestHeader("Content-length", json.length); + // xhr.setRequestHeader("Connection", "close"); + xhr.send( json ); + } + else /* assume GET */ + { + xhrOpen(); + xhr.send(null); + } + tmid = setTimeout( handleTimeout, timeout ); + return xhr; + } + catch(e) + { + args.errorMessage = e.toString(); + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + return undefined; + } + }/*XMLHttpRequest()*/, + /** + This is a concrete implementation of + WhAjaj.Connector.prototype.sendImpl() which uses the jQuery + AJAX API to send requests and fetch the responses. + + The first argument may be either null/false, an Object + containing toJSON-able data to post to the back-end, or such an + object in JSON string form. + + The second argument must be a connection properties object, as + constructed by WhAjaj.Connector.normalizeAjaxParameters(). + + If window.firebug is set then window.firebug.watchXHR() is + called to enable monitoring of the XMLHttpRequest object. + + This implementation honors the loginName and loginPassword + connection parameters. + + Returns the XMLHttpRequest object. + + This implementation requires that the 'this' object be-a + WhAjaj.Connector. + */ + jQuery:function(request,args) + { + var data = request || undefined; + var whself = this; + if( data ) { + if('string'!==typeof data) { + try { + data = JSON.stringify(data); + } + catch(e) { + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + return; + } + } + } + var ajopt = { + url: args.url, + data: data, + type: args.method, + async: args.asynchronous, + password: (undefined !== args.loginPassword) ? args.loginPassword : undefined, + username: (undefined !== args.loginName) ? args.loginName : undefined, + contentType: 'application/json; charset=utf-8', + error: function(xhr, textStatus, errorThrown) + { + //this === the options for this ajax request + args.errorMessage = "Error sending a '"+ajopt.type+"' request to ["+ajopt.url+"]: " + +"Status text=["+textStatus+"]" + +(errorThrown ? ("Error=["+errorThrown+"]") : "") + ; + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + }, + success: function(data) + { + WhAjaj.Connector.sendHelper.onSendSuccess.apply( whself, [request, data, args] ); + }, + /* Set dataType=text instead of json to keep jQuery from doing our carefully + written response handling for us. + */ + dataType: 'text' + }; + if( undefined !== args.timeout ) + { + ajopt.timeout = args.timeout; + } + try + { + return jQuery.ajax(ajopt); + } + catch(e) + { + args.errorMessage = e.toString(); + WhAjaj.Connector.sendHelper.onSendError.apply( whself, [request, args] ); + return undefined; + } + }/*jQuery()*/, + /** + This is a concrete implementation of + WhAjaj.Connector.prototype.sendImpl() which uses the rhino + Java API to send requests and fetch the responses. + + Limitations vis-a-vis the interface: + + - timeouts are not supported. + + - asynchronous mode is not supported because implementing it + requires the ability to kill a running thread (which is deprecated + in the Java API). + + TODOs: + + - add socket timeouts. + + - support HTTP proxy. + + The Java APIs support this, it just hasn't been added here yet. + */ + rhino:function(request,args) + { + var self = this; + var data = request || undefined; + if( data ) { + if('string'!==typeof data) { + try { + data = JSON.stringify(data); + } + catch(e) { + WhAjaj.Connector.sendHelper.onSendError.apply( self, [request, args] ); + return; + } + } + } + var url; + var con; + var IO = new JavaImporter(java.io); + var wr; + var rd, ln, json = []; + function setIncomingCookies(list){ + if(!list || !list.length) return; + if( !self.cookies ) self.cookies = {}; + var k, v, i; + for( i = 0; i < list.length; ++i ){ + v = list[i].split('=',2); + k = decodeURIComponent(v[0]) + v = v[0] ? decodeURIComponent(v[0].split(';',2)[0]) : null; + //print("RECEIVED COOKIE: "+k+"="+v); + if(!v) { + delete self.cookies[k]; + continue; + }else{ + self.cookies[k] = v; + } + } + }; + function setOutboundCookies(conn){ + if(!self.cookies) return; + var k, v; + for( k in self.cookies ){ + if(!self.cookies.hasOwnProperty(k)) continue /*kludge for broken JS libs*/; + v = self.cookies[k]; + conn.addRequestProperty("Cookie", encodeURIComponent(k)+'='+encodeURIComponent(v)); + //print("SENDING COOKIE: "+k+"="+v); + } + }; + try{ + url = new java.net.URL( args.url ) + con = url.openConnection(/*FIXME: add proxy support!*/); + con.setRequestProperty("Accept-Charset","utf-8"); + setOutboundCookies(con); + if(data){ + con.setRequestProperty("Content-Type","application/json; charset=utf-8"); + con.setDoOutput( true ); + wr = new IO.OutputStreamWriter(con.getOutputStream()) + wr.write(data); + wr.flush(); + wr.close(); + wr = null; + //print("POSTED: "+data); + } + rd = new IO.BufferedReader(new IO.InputStreamReader(con.getInputStream())); + //var skippedHeaders = false; + while ((line = rd.readLine()) !== null) { + //print("LINE: "+line); + //if(!line.length && !skippedHeaders){ + // skippedHeaders = true; + // json = []; + // continue; + //} + json.push(line); + } + setIncomingCookies(con.getHeaderFields().get("Set-Cookie")); + }catch(e){ + args.errorMessage = e.toString(); + WhAjaj.Connector.sendHelper.onSendError.apply( self, [request, args] ); + return undefined; + } + try { if(wr) wr.close(); } catch(e) { /*ignore*/} + try { if(rd) rd.close(); } catch(e) { /*ignore*/} + json = json.join(''); + //print("READ IN JSON: "+json); + WhAjaj.Connector.sendHelper.onSendSuccess.apply( self, [request, json, args] ); + }/*rhino*/ +}; + +/** + An internal function which takes an object containing properties + for a WhAjaj.Connector network request. This function creates a new + object containing a superset of the properties from: + + a) opt + b) this.options + c) WhAjaj.Connector.options.ajax + + in that order, using the first one it finds. + + All non-function properties are _deeply_ copied via JSON cloning + in order to prevent accidental "cross-request pollenation" (been + there, done that). Functions cannot be cloned and are simply + copied by reference. + + This function throws if JSON-copying one of the options fails + (e.g. due to cyclic data structures). + + Reminder to self: this function does not "normalize" opt.urlParam + by encoding it into opt.url, mainly for historical reasons, but + also because that behaviour was specifically undesirable in this + code's genetic father. +*/ +WhAjaj.Connector.prototype.normalizeAjaxParameters = function (opt) +{ + var rc = {}; + function merge(k,v) + { + if( rc.hasOwnProperty(k) ) return; + else if( WhAjaj.isFunction(v) ) {} + else if( WhAjaj.isObject(v) ) v = JSON.parse( JSON.stringify(v) ); + rc[k]=v; + } + function cp(obj) { + if( ! WhAjaj.isObject(obj) ) return; + var k; + for( k in obj ) { + if( ! obj.hasOwnProperty(k) ) continue /* i will always hate the Prototype designers for this. */; + merge(k, obj[k]); + } + } + cp( opt ); + cp( this.options ); + cp( WhAjaj.Connector.options.ajax ); + // no, not here: rc.url = WhAjaj.Connector.sendHelper.normalizeURL(rc); + return rc; +}; + +/** + This is the generic interface for making calls to a back-end + JSON-producing request handler. It is a simple wrapper around + WhAjaj.Connector.prototype.sendImpl(), which just normalizes the + connection options for sendImpl() and makes sure that + opt.beforeSend() is (possibly) called. + + The request parameter must either be false/null/empty or a + fully-populated JSON-able request object (which will be sent as + unencoded application/json text), depending on the type of + request being made. It is never semantically legal (in this API) + for request to be a string/number/true/array value. As a rule, + only POST requests use the request data. GET requests should + encode their data in opt.url or opt.urlParam (see below). + + opt must contain the network-related parameters for the request. + Paramters _not_ set in opt are pulled from this.options or + WhAjaj.Connector.options.ajax (in that order, using the first + value it finds). Thus the set of connection-level options used + for the request are a superset of those various sources. + + The "normalized" (or "superimposed") opt object's URL may be + modified before the request is sent, as follows: + + if opt.urlParam is a string then it is assumed to be properly + URL-encoded parameters and is appended to the opt.url. If it is + an Object then it is assumed to be a one-dimensional set of + key/value pairs with simple values (numbers, strings, booleans, + null, and NOT objects/arrays). The keys/values are URL-encoded + and appended to the URL. + + The beforeSend() callback (see below) can modify the options + object before the request attempt is made. + + The callbacks in the normalized opt object will be triggered as + follows (if they are set to Function values): + + - beforeSend(request,opt) will be called before any network + processing starts. If beforeSend() throws then no other + callbacks are triggered and this function propagates the + exception. This function is passed normalized connection options + as its second parameter, and changes this function makes to that + object _will_ be used for the pending connection attempt. + + - onError(request,opt) will be called if a connection to the + back-end cannot be established. It will be passed the original + request object (which might be null, depending on the request + type) and the normalized options object. In the error case, the + opt object passed to onError() "should" have a property called + "errorMessage" which contains a description of the problem. + + - onError(request,opt) will also be called if connection + succeeds but the response is not JSON data. + + - onResponse(response,request) will be called if the response + returns JSON data. That data might hold an error response code - + clients need to check for that. It is passed the response object + (a plain object) and the original request object. + + - afterSend(request,opt) will be called directly after the + AJAX request is finished, before onError() or onResonse() are + called. Possible TODO: we explicitly do NOT pass the response to + this function in order to keep the line between the responsibilities + of the various callback clear (otherwise this could be used the same + as onResponse()). In practice it would sometimes be useful have the + response passed to this function, mainly for logging/debugging + purposes. + + The return value from this function is meaningless because + AJAX operations tend to take place asynchronously. + +*/ +WhAjaj.Connector.prototype.sendRequest = function(request,opt) +{ + if( !WhAjaj.isFunction(this.sendImpl) ) + { + throw new Error("This object has no sendImpl() member function! I don't know how to send the request!"); + } + var ex = false; + var av = Array.prototype.slice.apply( arguments, [0] ); + + /** + FIXME: how to handle the error, vis-a-vis- the callbacks, if + normalizeAjaxParameters() throws? It can throw if + (de)JSON-izing fails. + */ + var norm = this.normalizeAjaxParameters( WhAjaj.isObject(opt) ? opt : {} ); + norm.url = WhAjaj.Connector.sendHelper.normalizeURL(norm); + if( ! request ) norm.method = 'GET'; + var cb = this.callbacks || {}; + if( this.callbacks && WhAjaj.isFunction(this.callbacks.beforeSend) ) { + this.callbacks.beforeSend( request, norm ); + } + if( WhAjaj.isFunction(norm.beforeSend) ){ + norm.beforeSend( request, norm ); + } + //alert( WhAjaj.stringify(request)+'\n'+WhAjaj.stringify(norm)); + try { this.sendImpl( request, norm ); } + catch(e) { ex = e; } + if(ex) throw ex; +}; + +/** + sendImpl() holds a concrete back-end connection implementation. It + can be replaced with a custom implementation if one follows the rules + described throughout this API. See WhAjaj.Connector.sendImpls for + the concrete implementations included with this API. +*/ +//WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.XMLHttpRequest; +//WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; +//WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.jQuery; + +if( 'undefined' !== typeof jQuery ){ + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.jQuery; +} +else { + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.XMLHttpRequest; +} ADDED ajax/wiki-editor.html Index: ajax/wiki-editor.html ================================================================== --- ajax/wiki-editor.html +++ ajax/wiki-editor.html @@ -0,0 +1,381 @@ + + + + + Fossil/JSON Wiki Editor Prototype + + + + + + + + + + + + + +

PROTOTYPE JSON-based Fossil Wiki Editor

+ +See also: main test page. + +
+Login: +
+ +or: +name: +pw: + + + +
+ + +
+Quick-posts:
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
Page ListContent
+
+
+
+
+ +
Response
+ +
+
+
+
+ + ADDED art/CollRev1.dia Index: art/CollRev1.dia ================================================================== --- art/CollRev1.dia +++ art/CollRev1.dia @@ -0,0 +1,793 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #File# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Project# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Meta# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Symbol# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #has# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #(Line of Development / Branch)# + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/CollRev2.dia Index: art/CollRev2.dia ================================================================== --- art/CollRev2.dia +++ art/CollRev2.dia @@ -0,0 +1,576 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision' (Child)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #File# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Line of +Development# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # parent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #branch parent symbol + (NULL)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # child# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/CollRev3.dia Index: art/CollRev3.dia ================================================================== --- art/CollRev3.dia +++ art/CollRev3.dia @@ -0,0 +1,980 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Line of +Development# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Line' of +Development# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision'' +(Branch Start)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #File# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision' +(Child)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # branch + parent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # parent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # child# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + parent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # belongs to# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #=/=# + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/CollRev4.dia Index: art/CollRev4.dia ================================================================== --- art/CollRev4.dia +++ art/CollRev4.dia @@ -0,0 +1,640 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision' +(Child NTDB)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision +(NTDB)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision'' +(Child NTDB)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Revision"" +(non-NTDB)# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + parent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # +child# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # +child# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + dbparent# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # dbchild# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + parent# + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/branching.odp Index: art/branching.odp ================================================================== --- art/branching.odp +++ art/branching.odp cannot compute difference between binary files ADDED art/concept1.dia Index: art/concept1.dia ================================================================== --- art/concept1.dia +++ art/concept1.dia cannot compute difference between binary files ADDED art/concept2.dia Index: art/concept2.dia ================================================================== --- art/concept2.dia +++ art/concept2.dia cannot compute difference between binary files ADDED art/delta1.dia Index: art/delta1.dia ================================================================== --- art/delta1.dia +++ art/delta1.dia @@ -0,0 +1,234 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Header# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Segments# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Trailer# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/delta2.dia Index: art/delta2.dia ================================================================== --- art/delta2.dia +++ art/delta2.dia @@ -0,0 +1,352 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Copy Range# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Insert Literal# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #***# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/delta3.dia Index: art/delta3.dia ================================================================== --- art/delta3.dia +++ art/delta3.dia @@ -0,0 +1,289 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Length# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #"@"# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Offset# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #","# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/delta4.dia Index: art/delta4.dia ================================================================== --- art/delta4.dia +++ art/delta4.dia @@ -0,0 +1,234 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Length# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Bytes# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #":"# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/delta5.dia Index: art/delta5.dia ================================================================== --- art/delta5.dia +++ art/delta5.dia @@ -0,0 +1,179 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #";"# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Checksum# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/delta6.dia Index: art/delta6.dia ================================================================== --- art/delta6.dia +++ art/delta6.dia @@ -0,0 +1,179 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Size# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #"\n"# + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/encode1.tex Index: art/encode1.tex ================================================================== --- art/encode1.tex +++ art/encode1.tex @@ -0,0 +1,2 @@ +\LARGE A = (\sum_{i=0}^{NHASH-1} z_i) \bmod 2^{16} + ADDED art/encode10.dia Index: art/encode10.dia ================================================================== --- art/encode10.dia +++ art/encode10.dia @@ -0,0 +1,657 @@ + + + + + + + + + + + + + #Letter# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Gap => Insert# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Processed# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Common => Copy# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Window# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Signature# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Base# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Slide# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Target# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Origin# + + + + + + + + + + + + + + + + + + + + + + + + + ADDED art/encode2.tex Index: art/encode2.tex ================================================================== --- art/encode2.tex +++ art/encode2.tex @@ -0,0 +1,1 @@ +\LARGE B = (\sum_{i=0}^{NHASH-1} (NHASH-i)z_i) \bmod 2^{16} ADDED art/encode3.tex Index: art/encode3.tex ================================================================== --- art/encode3.tex +++ art/encode3.tex @@ -0,0 +1,1 @@ +\LARGE V = 2^{16}B + A ADDED art/encode4.tex Index: art/encode4.tex ================================================================== --- art/encode4.tex +++ art/encode4.tex @@ -0,0 +1,1 @@ +\LARGE z_0 ADDED art/encode5.tex Index: art/encode5.tex ================================================================== --- art/encode5.tex +++ art/encode5.tex @@ -0,0 +1,1 @@ +\LARGE z_{new} ADDED art/encode6.tex Index: art/encode6.tex ================================================================== --- art/encode6.tex +++ art/encode6.tex @@ -0,0 +1,1 @@ +\LARGE A_{new} = (A - z_0 + z_{new}) \bmod 2^{16} ADDED art/encode7.tex Index: art/encode7.tex ================================================================== --- art/encode7.tex +++ art/encode7.tex @@ -0,0 +1,1 @@ +\LARGE B_{new} = (B - z_0 NHASH + A_{new}) \bmod 2^{16} ADDED art/encode8.tex Index: art/encode8.tex ================================================================== --- art/encode8.tex +++ art/encode8.tex @@ -0,0 +1,1 @@ +\LARGE V_{new} = 2^{16}B_{new} + A_{new} ADDED art/encode9.tex Index: art/encode9.tex ================================================================== --- art/encode9.tex +++ art/encode9.tex @@ -0,0 +1,1 @@ +\LARGE A_{new} Index: auto.def ================================================================== --- auto.def +++ auto.def @@ -1,50 +1,32 @@ # System autoconfiguration. Try: ./configure --help -# This must be above "options" below because it implicitly brings in the -# default Autosetup options, things like --prefix. use cc cc-lib options { with-openssl:path|auto|tree|none => {Look for OpenSSL in the given path, automatically, in the source tree, or none} + with-miniz=0 => {Use miniz from the source tree} with-zlib:path|auto|tree => {Look for zlib in the given path, automatically, or in the source tree} - with-sqlite:path|auto|tree - => {Look for sqlite in the given path, automatically, or in the source tree.} with-exec-rel-paths=0 => {Enable relative paths for external diff/gdiff} - with-sanitizer: => {Build with C compiler's -fsanitize=LIST; e.g. address,enum,null,undefined} + with-legacy-mv-rm=1 => {Enable legacy behavior for mv/rm (skip checkout files)} with-th1-docs=0 => {Enable TH1 for embedded documentation pages} with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages} with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism} with-tcl-private-stubs=0 => {Enable Tcl integration via private stubs mechanism} with-mman=0 => {Enable use of POSIX memory APIs from "sys/mman.h"} with-see=0 => {Enable the SQLite Encryption Extension (SEE)} - print-minimum-sqlite-version=0 - => {print the minimum SQLite version number required, and exit} internal-sqlite=1 => {Don't use the internal SQLite, use the system one} static=0 => {Link a static executable} fusefs=1 => {Disable the Fuse Filesystem} fossil-debug=0 => {Build with fossil debugging enabled} no-opt=0 => {Build without optimization} json=0 => {Build with fossil JSON API enabled} - with-emsdk:path => {Directory containing the Emscripten SDK} -} - -# Update the minimum required SQLite version number here, and also -# in src/main.c near the sqlite3_libversion_number() call. Take care -# that both places agree! -define MINIMUM_SQLITE_VERSION "3.38.0" - -# This is useful for people wanting Fossil to use an external SQLite library -# to compare the one they have against the minimum required -if {[opt-bool print-minimum-sqlite-version]} { - puts [get-define MINIMUM_SQLITE_VERSION] - exit 0 } # sqlite wants these types if possible cc-with {-includes {stdint.h inttypes.h}} { cc-check-types uint32_t uint16_t int16_t uint8_t @@ -51,17 +33,10 @@ } # Use pread/pwrite system calls in place of seek + read/write if possible define USE_PREAD [cc-check-functions pread] -# If we have cscope here, we'll use it in the "tags" target -if {[cc-check-progs cscope]} { - define COLLECT_CSCOPE_DATA "cscope -bR $::autosetup(srcdir)/src/*.\[ch\]" -} else { - define COLLECT_CSCOPE_DATA "" -} - # Find tclsh for the test suite. # # We can't use jimsh for this: the test suite uses features of Tcl that # Jim doesn't support, either statically or due to the way it's built by # autosetup. For example, Jim supports `file normalize`, but only if @@ -75,11 +50,11 @@ set hbtd /usr/local/Cellar/tcl-tk if {[string equal false [get-define TCLSH]]} { msg-result "WARNING: 'make test' will not run here." } else { set v [exec /bin/sh -c "echo 'puts \$tcl_version' | tclsh"] - if {[expr {$v >= 8.6}]} { + if {[expr $v >= 8.6]} { msg-result "Found Tclsh version $v in the PATH." define TCLSH tclsh } elseif {[file isdirectory $hbtd]} { # This is a macOS system with the Homebrew version of Tcl/Tk # installed. Select the newest version. It won't normally be @@ -100,21 +75,13 @@ define EXTRA_CFLAGS "-Wall" define EXTRA_LDFLAGS "" define USE_SYSTEM_SQLITE 0 define USE_LINENOISE 0 +define FOSSIL_ENABLE_MINIZ 0 define USE_MMAN_H 0 define USE_SEE 0 -define SQLITE3_ORIGIN 0 -# SQLITE3_ORIGIN 0 = src/sqlite3, 1=src/sqlite3-see.c, 2=client-provided - -# Maintain the C89/C90-style order of variable declarations before statements. -# Check if the compiler supports the respective warning flag. -if {[cctest -cflags -Wdeclaration-after-statement]} { - define-append EXTRA_CFLAGS -Wdeclaration-after-statement -} - # This procedure is a customized version of "cc-check-function-in-lib", # that does not modify the LIBS variable. Its use prevents prematurely # pulling in libraries that will be added later anyhow (e.g. "-ldl"). proc check-function-in-lib {function libs {otherlibs {}}} { @@ -149,25 +116,29 @@ } return $found } if {![opt-bool internal-sqlite]} { - proc find_system_sqlite {} { + proc find_internal_sqlite {} { # On some systems (slackware), libsqlite3 requires -ldl to link. So # search for the system SQLite once with -ldl, and once without. If # the library can only be found with $extralibs set to -ldl, then # the code below will append -ldl to LIBS. # foreach extralibs {{} {-ldl}} { # Locate the system SQLite by searching for sqlite3_open(). Then check - # if sqlite3_stmt_isexplain can be found as well. If we can find open() but - # not stmt_isexplain(), then the system SQLite is too old to link against + # if sqlite3_create_window_function can be found as well. If we can find open() but + # not create_window_function(), then the system SQLite is too old to link against # fossil. # if {[check-function-in-lib sqlite3_open sqlite3 $extralibs]} { + if {![check-function-in-lib sqlite3_create_window_function sqlite3 $extralibs]} { + user-error "system sqlite3 too old (require >= 3.25.0)" + } + # Success. Update symbols and return. # define USE_SYSTEM_SQLITE 1 define-append LIBS -lsqlite3 define-append LIBS $extralibs @@ -175,50 +146,11 @@ } } user-error "system sqlite3 not found" } - find_system_sqlite - - proc test_system_sqlite {} { - # Check compatibility of the system SQLite library by running the sqlcompttest.c - # program in the source tree - # passes MINIMUM_SQLITE_VERSION set at the top of this file to sqlcompttest.c - # - set cmdline {} - lappend cmdline {*}[get-define CCACHE] - lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS] - lappend cmdline $::autosetup(dir)/../tools/sqlcompattest.c -o conftest__ - lappend cmdline {*}[get-define LDFLAGS] - lappend cmdline {*}[get-define LIBS] - set sqlite-version [string cat "-D MINIMUM_SQLITE_VERSION=" [get-define MINIMUM_SQLITE_VERSION]] - lappend cmdline {*}[set sqlite-version] - set ok 1 - set err [catch {exec-with-stderr {*}$cmdline} result errinfo] - if {$err} { - configlog "Failed: [join $cmdline]" - if {[string length $result]>0} {configlog $result} - configlog "============" - set ok 0 - } elseif {$::autosetup(debug)} { - configlog "Compiled OK: [join $cmdline]" - configlog "============" - } - if {!$ok} { - user-error "unable to compile SQLite compatibility test program" - } - set err [catch {exec-with-stderr ./conftest__} result errinfo] - if {[get-define build] eq [get-define host]} { - set err [catch {exec-with-stderr ./conftest__} result errinfo] - if {$err} { - user-error $result - } - } - file delete ./conftest__ - } - test_system_sqlite - + find_internal_sqlite } proc is_mingw {} { return [string match *mingw* [get-define host]] } @@ -233,11 +165,11 @@ # define USE_LINENOISE 1 } if {[string match *-solaris* [get-define host]]} { - define-append EXTRA_CFLAGS {-D__EXTENSIONS__} + define-append EXTRA_CFLAGS {-D_XOPEN_SOURCE=500 -D__EXTENSIONS__} } if {[opt-bool fossil-debug]} { define CFLAGS {-g -O0 -Wall} define-append CFLAGS -DFOSSIL_DEBUG @@ -245,13 +177,10 @@ } if {[opt-bool no-opt]} { define CFLAGS {-g -O0 -Wall} msg-result "Builting without compiler optimization" - if {[opt-bool fossil-debug]} { - define-append CFLAGS -DFOSSIL_DEBUG - } } if {[opt-bool with-mman]} { define-append EXTRA_CFLAGS -DUSE_MMAN_H define USE_MMAN_H 1 @@ -259,11 +188,10 @@ } if {[opt-bool with-see]} { define-append EXTRA_CFLAGS -DUSE_SEE define USE_SEE 1 - define SQLITE3_ORIGIN 1 msg-result "Enabling encryption support" } if {[opt-bool json]} { # Reminder/FIXME (stephan): FOSSIL_ENABLE_JSON @@ -272,10 +200,16 @@ # reading config.h first. define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON define FOSSIL_ENABLE_JSON msg-result "JSON support enabled" } + +if {[opt-bool with-legacy-mv-rm]} { + define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_LEGACY_MV_RM=1 + define FOSSIL_ENABLE_LEGACY_MV_RM + msg-result "Legacy mv/rm support enabled" +} if {[opt-bool with-exec-rel-paths]} { define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_EXEC_REL_PATHS define FOSSIL_ENABLE_EXEC_REL_PATHS msg-result "Relative paths in external diff/gdiff enabled" @@ -309,11 +243,11 @@ # Check for libraries that need to be sorted out early cc-check-function-in-lib iconv iconv # Helper for OpenSSL checking -proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} { +proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto}}} { msg-checking "Checking for $msg..." set rc 0 if {[is_mingw]} { lappend libs -lgdi32 -lwsock32 -lcrypt32 } @@ -343,49 +277,55 @@ msg-result "no" return 0 } } -# Check for zlib, using the given location if specified -set zlibpath [opt-val with-zlib] -if {$zlibpath eq "tree"} { - set zlibdir [file dirname $autosetup(dir)]/compat/zlib - if {![file isdirectory $zlibdir]} { - user-error "The zlib in source tree directory does not exist" - } elseif { ([llength [glob -nocomplain -directory $zlibdir libz*]] == 0) } { - user-error "With --with-zlib=tree, $zlibdir must be configured and built first." - } - cc-with [list -cflags "-I$zlibdir -L$zlibdir"] - define-append EXTRA_CFLAGS -I$zlibdir - define-append LIBS $zlibdir/libz.a - set ::zlib_lib $zlibdir/libz.a - msg-result "Using zlib in source tree" +if {[opt-bool with-miniz]} { + define FOSSIL_ENABLE_MINIZ 1 + msg-result "Using miniz for compression" } else { - if {$zlibpath ni {auto ""}} { - cc-with [list -cflags "-I$zlibpath -L$zlibpath"] - define-append EXTRA_CFLAGS -I$zlibpath - define-append EXTRA_LDFLAGS -L$zlibpath - msg-result "Using zlib from $zlibpath" - } - if {![cc-check-includes zlib.h] || ![check-function-in-lib inflateEnd z]} { - user-error "zlib not found please install it or specify the location with --with-zlib" - } - set ::zlib_lib -lz + # Check for zlib, using the given location if specified + set zlibpath [opt-val with-zlib] + if {$zlibpath eq "tree"} { + set zlibdir [file dirname $autosetup(dir)]/compat/zlib + if {![file isdirectory $zlibdir]} { + user-error "The zlib in source tree directory does not exist" + } + cc-with [list -cflags "-I$zlibdir -L$zlibdir"] + define-append EXTRA_CFLAGS -I$zlibdir + define-append LIBS $zlibdir/libz.a + set ::zlib_lib $zlibdir/libz.a + msg-result "Using zlib in source tree" + } else { + if {$zlibpath ni {auto ""}} { + cc-with [list -cflags "-I$zlibpath -L$zlibpath"] + define-append EXTRA_CFLAGS -I$zlibpath + define-append EXTRA_LDFLAGS -L$zlibpath + msg-result "Using zlib from $zlibpath" + } + if {![cc-check-includes zlib.h] || ![check-function-in-lib inflateEnd z]} { + user-error "zlib not found please install it or specify the location with --with-zlib" + } + set ::zlib_lib -lz + } } set ssldirs [opt-val with-openssl] if {$ssldirs ne "none"} { + if {[opt-bool with-miniz]} { + user-error "The --with-miniz option is incompatible with OpenSSL" + } set found 0 if {$ssldirs eq "tree"} { set ssldir [file dirname $autosetup(dir)]/compat/openssl if {![file isdirectory $ssldir]} { user-error "The OpenSSL in source tree directory does not exist" } set msg "ssl in $ssldir" set cflags "-I$ssldir/include" set ldflags "-L$ssldir" - set ssllibs "$ssldir/libssl.a $ssldir/libcrypto.a -lpthread" + set ssllibs "$ssldir/libssl.a $ssldir/libcrypto.a" set found [check-for-openssl "ssl in source tree" "$cflags $ldflags" $ssllibs] } else { if {$ssldirs in {auto ""}} { catch { set cflags [exec pkg-config openssl --cflags-only-I] @@ -392,12 +332,11 @@ set ldflags [exec pkg-config openssl --libs-only-L] set found [check-for-openssl "ssl via pkg-config" "$cflags $ldflags"] } msg if {!$found} { set ssldirs "{} /usr/sfw /usr/local/ssl /usr/lib/ssl /usr/ssl \ - /usr/pkg /usr/local /usr /usr/local/opt/openssl \ - /opt/homebrew/opt/openssl" + /usr/pkg /usr/local /usr /usr/local/opt/openssl" } } if {!$found} { foreach dir $ssldirs { if {$dir eq ""} { @@ -446,80 +385,10 @@ if {[info exists ::zlib_lib]} { define-append LIBS $::zlib_lib } } - - -######################################################################## -# --with-sqlite=PATH checks for the first it finds of the following... -# - PATH/sqlite3.c and PATH/sqlite3.h -# - PATH/sqlite3.o (and assumes sqlite3.h is with it) -# - PATH/lib/libsqlite3* and PATH/include/sqlite3.h -define CFLAGS_INCLUDE {} -# ^^^ CFLAGS_INCLUDE is ONLY for -I... flags and their order is -# significant so that --with-sqlite=PATH's header can shadow our -# own. One caveat with this is that we cannot point --with-sqlite=PATH -# to the root of sqlite3's own build tree because that dir has a -# config.h which ends up shadowing src/config.h, breaking our build. -set sq3path [opt-val with-sqlite] -define SQLITE3_SRC.2 {} -define SQLITE3_OBJ.2 {} -define SQLITE3_SHELL_SRC.2 {$(SQLITE3_SHELL_SRC.0)} -if {$sq3path in {tree ""}} { - msg-result "Using sqlite3.c from this source tree." -} else { - # SQLITE3_ORIGIN: - # 0 = local source tree - # 1 = use external lib or sqlite3.o - # 2 = use external sqlite3.c and (if found) shell.c - define USE_SYSTEM_SQLITE 1 - define SQLITE3_ORIGIN 2 - if {$sq3path != "auto"} { - if {([file exists $sq3path/sqlite3.c]) && \ - ([file exists $sq3path/sqlite3.h]) } { - # Prefer sqlite3.[ch] if found. - define SQLITE3_SRC.2 $sq3path/sqlite3.c - define SQLITE3_OBJ.2 {$(SQLITE3_OBJ.0)} - define USE_SYSTEM_SQLITE 2 - define SQLITE3_ORIGIN 2 - if {[file exists $sq3path/shell.c]} { - define SQLITE3_SHELL_SRC.2 $sq3path/shell.c - } - define-append CFLAGS_INCLUDE -I$sq3path - define-append EXTRA_LDFLAGS -lpthread - # ^^^ additional -lXXX flags are conservative estimates - msg-result "Using sqlite3.c and sqlite3.h from $sq3path" - } elseif {[file exists $sq3path/sqlite3.o]} { - # Use sqlite3.o if found. - define SQLITE3_OBJ.2 $sq3path/sqlite3.o - define-append CFLAGS_INCLUDE -I$sq3path - define-append EXTRA_LDFLAGS $sq3path/sqlite3.o -lpthread - # ^^^ additional -lXXX flags are conservative estimates - msg-result "Using sqlite3.o from $sq3path" - } elseif { ([llength [glob -nocomplain -directory $sq3path/lib libsqlite3*]] != 0) \ - && ([file exists $sq3path/include/sqlite3.h]) } { - # e.g. --with-sqlite=/usr/local. Try $sq3path/lib/libsqlite3* - # and $sq3path/include/sqlite3.h - define-append CFLAGS_INCLUDE -I$sq3path/include - define-append EXTRA_LDFLAGS -L$sq3path/lib -lsqlite3 -lpthread - # ^^^ additional -lXXX flags are conservative estimates - msg-result "Using -lsqlite3 from $sq3path" - } else { - # Assume $sq3path holds both the lib and header - cc-with [list -cflags "-I$sq3path -L$sq3path"] - define-append CFLAGS_INCLUDE -I$sq3path - define-append EXTRA_LDFLAGS -L$sq3path -lsqlite3 -lpthread - # ^^^ additional -lXXX flags are conservative estimates - msg-result "Using -lsqlite3 from $sq3path" - } - } elseif {![cc-check-includes sqlite3.h] || ![check-function-in-lib sqlite3_open_v2 sqlite3]} { - user-error "libsqlite3 not found please install it or specify the location with --with-sqlite" - } -} -define-append CFLAGS_INCLUDE {-I. -I$(SRCDIR) -I$(SRCDIR_extsrc)} - set tclpath [opt-val with-tcl] if {$tclpath ne ""} { set tclprivatestubs [opt-bool with-tcl-private-stubs] # Note parse-tclconfig-sh is in autosetup/local.tcl if {$tclpath eq "1"} { @@ -636,37 +505,10 @@ $tclconfig(TCL_LD_FLAGS)] define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS) define FOSSIL_ENABLE_TCL } -# Emscripten is a purely optional component used only for doing -# in-tree builds of WASM stuff, as opposed to WASM binaries we import -# from other places. This is only set up for Unix-style OSes and is -# untested anywhere but Linux. -set emsdkHome [opt-val with-emsdk] -define EMSDK_HOME "" -define EMSDK_ENV "" -define EMCC_OPT "-Oz" -if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} { - # Fall back to checking the environment. $EMSDK gets set - # by sourcing emsdk_env.sh. - set emsdkHome $::env(EMSDK) -} -if {$emsdkHome ne ""} { - define EMSDK_HOME $emsdkHome - set emsdkEnv "$emsdkHome/emsdk_env.sh" - if {[file exists $emsdkEnv]} { - puts "Using Emscripten SDK environment from $emsdkEnv." - define EMSDK_ENV $emsdkEnv - if {[info exists ::env(EMCC_OPT)]} { - define EMCC_OPT $::env(EMCC_OPT) - } - } else { - puts "emsdk_env.sh not found. Assuming emcc is in the PATH." - } -} - # Network functions require libraries on some systems cc-check-function-in-lib gethostbyname nsl if {![cc-check-function-in-lib socket {socket network}]} { # Last resort, may be Windows if {[is_mingw]} { @@ -696,18 +538,10 @@ cc-check-functions usleep cc-check-functions strchrnul cc-check-functions pledge cc-check-functions backtrace -# Termux on Android adds "getpass(char *)" to unistd.h, so check this so we -# guard against including it again; use cctest as cc-check-functions and -# cctest_function check for "getpass()" with no args and fail -if {[cctest -link 1 -includes {unistd.h} -code "getpass(0);"]} { - define FOSSIL_HAVE_GETPASS 1 - msg-result "Found getpass() with unistd.h" -} - # Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE if {![cc-check-functions getloadavg]} { define FOSSIL_OMIT_LOAD_AVERAGE 1 msg-result "Load average support unavailable" } @@ -719,62 +553,23 @@ } cc-check-function-in-lib sin m # Check for the FuseFS library if {[opt-bool fusefs]} { - if {[opt-bool static]} { - msg-result "FuseFS support disabled due to -static" - } elseif {[cc-check-function-in-lib fuse_mount fuse]} { + if {[cc-check-function-in-lib fuse_mount fuse]} { define-append EXTRA_CFLAGS -DFOSSIL_HAVE_FUSEFS define FOSSIL_HAVE_FUSEFS 1 define-append LIBS -lfuse msg-result "FuseFS support enabled" } } -# Add -fsanitize compile and link options late: we don't want the C -# checks above to run with those sanitizers enabled. It can not only -# be pointless, it can actually break correct tests. -set fsan [opt-val with-sanitizer] -if {[string length $fsan]} { - define-append EXTRA_CFLAGS -fsanitize=$fsan - define-append EXTRA_LDFLAGS -fsanitize=$fsan - if {[string first "undefined" $fsan] != -1} { - # We need to link with libubsan if we're compiling under - # GCC with -fsanitize=undefined. - cc-check-function-in-lib __ubsan_handle_add_overflow ubsan - } -} - -# Finally, append libraries that must be last. This matters more on some -# OSes than others, but is most broadly required for static linking. +# Finally, append -ldl to make sure it's the last in the list. +# The library order matters in case of static linking. if {[check-function-in-lib dlopen dl]} { # Some platforms (*BSD) have the dl functions already in libc and no libdl. # In such case we can link directly without -ldl. define-append LIBS [get-define lib_dlopen] } -if {[opt-bool static]} { - # Linux can only infer the dependency on pthread from OpenSSL when - # doing dynamic linkage. - define-append LIBS -lpthread -} - -if {[get-define EMSDK_HOME] ne ""} { - define EMCC_WRAPPER $::autosetup(dir)/../tools/emcc.sh - make-template tools/emcc.sh.in - catch {exec chmod u+x tools/emcc.sh} -} else { - define EMCC_WRAPPER "" - catch {exec rm -f tools/emcc.sh} -} - -# Tag container builds with a prefix of the checkin ID of the version -# of Fossil each one contains. This not only allows multiple images -# to coexist and multiple containers to be created unamgiguosly from -# them, it also changes the URL we fetch the source tarball from, so -# repeated builds of a given version generate and fetch the source -# tarball once only, keeping it in the local Docker/Podman cache. -set ci [readfile "$::autosetup(srcdir)/manifest.uuid"] -define FOSSIL_CI_PFX [string range $ci 0 11] make-template Makefile.in make-config-header autoconfig.h -auto {USE_* FOSSIL_*} Index: autosetup/README.autosetup ================================================================== --- autosetup/README.autosetup +++ autosetup/README.autosetup @@ -1,11 +1,1 @@ -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. - -*.tcl files in this directory are optional modules which -can be loaded with the 'use' directive. - -*.auto files in this directory are auto-loaded. - -For more information, see http://msteveb.github.com/autosetup/ +This is autosetup v0.6.6. See http://msteveb.github.com/autosetup/ Index: autosetup/autosetup ================================================================== --- autosetup/autosetup +++ autosetup/autosetup @@ -1,17 +1,16 @@ #!/bin/sh # Copyright (c) 2006-2011 WorkWare Systems http://www.workware.net.au/ # All rights reserved # vim:se syntax=tcl: # \ -dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@" +dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@" -# Note that the version has a trailing + on unreleased versions -set autosetup(version) 0.6.9 +set autosetup(version) 0.6.6 # Can be set to 1 to debug early-init problems -set autosetup(debug) [expr {"--debug" in $argv}] +set autosetup(debug) 0 ################################################################## # # Main flow of control, option handling # @@ -73,19 +72,15 @@ set autosetup(cmdline) {} # options is a list of known options set autosetup(options) {} # optset is a dictionary of option values set by the user based on getopt set autosetup(optset) {} - # optdefault is a dictionary of default values + # optdefault is a dictionary of default values for options set autosetup(optdefault) {} - # options-defaults is a dictionary of overrides for default values for options - set autosetup(options-defaults) {} set autosetup(optionhelp) {} set autosetup(showhelp) 0 - use util - # Parse options use getopt # At the is point we don't know what is a valid option # We simply parse anything that looks like an option @@ -92,28 +87,15 @@ set autosetup(getopt) [getopt argv] #"=Core Options:" options-add { help:=local => "display help and options. Optionally specify a module name, such as --help=system" - licence license => "display the autosetup license" version => "display the version of autosetup" ref:=text manual:=text reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" debug => "display debugging output as autosetup runs" - install:=. => "install autosetup to the current or given directory" - } - if {$autosetup(installed)} { - # hidden options so we can produce a nice error - options-add { - sysinstall:path - } - } else { - options-add { - sysinstall:path => "install standalone autosetup to the given directory (e.g.: /usr/local)" - } - } - options-add { + install:=. => "install autosetup to the current or given directory (in the 'autosetup/' subdirectory)" force init:=help => "create initial auto.def, etc. Use --init=help for known types" # Undocumented options option-checking=1 nopager quiet @@ -125,12 +107,12 @@ puts $autosetup(version) exit 0 } # autosetup --conf=alternate-auto.def - if {[opt-str conf o]} { - set autosetup(autodef) $o + if {[opt-val conf] ne ""} { + set autosetup(autodef) [opt-val conf] } # Debugging output (set this early) incr autosetup(debug) [opt-bool debug] incr autosetup(force) [opt-bool force] @@ -142,51 +124,42 @@ if {[file exists $autosetup(libdir)/local.tcl]} { use local } # Now any auto-load modules - autosetup_load_auto_modules + foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { + automf_load source $file + } - if {[opt-str help o]} { + if {[opt-val help] ne ""} { incr autosetup(showhelp) use help - autosetup_help $o - } - - if {[opt-bool licence license]} { - use help - autosetup_show_license - exit 0 - } - - if {[opt-str {manual ref reference} o]} { - use help - autosetup_reference $o + autosetup_help [opt-val help] + } + + if {[opt-val {manual ref reference}] ne ""} { + use help + autosetup_reference [opt-val {manual ref reference}] } # Allow combining --install and --init set earlyexit 0 - if {[opt-str install o]} { + if {[opt-val install] ne ""} { use install - autosetup_install $o + autosetup_install [opt-val install] incr earlyexit } - if {[opt-str init o]} { + if {[opt-val init] ne ""} { use init - autosetup_init $o + autosetup_init [opt-val init] incr earlyexit } if {$earlyexit} { exit 0 } - if {[opt-str sysinstall o]} { - use install - autosetup_install $o 1 - exit 0 - } if {![file exists $autosetup(autodef)]} { # Check for invalid option first options {} user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)" @@ -212,11 +185,10 @@ 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) # Could warn here if options {} was not specified @@ -238,14 +210,14 @@ # # Check each of the named, boolean options and if any have been explicitly enabled # or disabled by the user, return 1 or 0 accordingly. # # If the option was specified more than once, the last value wins. -# e.g. With '--enable-foo --disable-foo', '[opt-bool foo]' will return 0 +# e.g. With --enable-foo --disable-foo, [opt-bool foo] will return 0 # # If no value was specified by the user, returns the default value for the -# first option. If '-nodefault' is given, this behaviour changes and +# first option. If -nodefault is given, this behaviour changes and # -1 is returned instead. # proc opt-bool {args} { set nodefault 0 if {[lindex $args 0] eq "-nodefault"} { @@ -265,19 +237,20 @@ } # Default value is the default for the first option return [dict get $::autosetup(optdefault) [lindex $args 0]] } -# @opt-val optionlist ?default=""? +# @opt-val option-list ?default=""? # -# Returns a list containing all the values given for the non-boolean options in '$optionlist'. +# Returns a list containing all the values given for the non-boolean options in 'option-list'. # There will be one entry in the list for each option given by the user, including if the # same option was used multiple times. +# If only a single value is required, use something like: # -# If no options were set, '$default' is returned (exactly, not as a list). +## lindex [opt-val $names] end # -# Note: For most use cases, 'opt-str' should be preferred. +# If no options were set, $default is returned (exactly, not as a list). # proc opt-val {names {default ""}} { option-check-names {*}$names foreach opt $names { @@ -289,83 +262,10 @@ return $result } return $default } -# @opt-str optionlist varname ?default? -# -# Sets '$varname' in the callers scope to the value for one of the given options. -# -# For the list of options given in '$optionlist', if any value is set for any option, -# the option value is taken to be the *last* value of the last option (in the order given). -# -# If no option was given, and a default was specified with 'options-defaults', -# that value is used. -# -# If no 'options-defaults' value was given and '$default' was given, it is used. -# -# If none of the above provided a value, no value is set. -# -# The return value depends on whether '$default' was specified. -# If it was, the option value is returned. -# If it was not, 1 is returns if a value was set, or 0 if not. -# -# Typical usage is as follows: -# -## if {[opt-str {myopt altname} o]} { -## do something with $o -## } -# -# Or: -## define myname [opt-str {myopt altname} o "/usr/local"] -# -proc opt-str {names varname args} { - global autosetup - - option-check-names {*}$names - upvar $varname value - - if {[llength $args]} { - # A default was given, so always return the string value of the option - set default [lindex $args 0] - set retopt 1 - } else { - # No default, so return 0 or 1 to indicate if a value was found - set retopt 0 - } - - foreach opt $names { - if {[dict exists $::autosetup(optset) $opt]} { - set result [lindex [dict get $::autosetup(optset) $opt] end] - } - } - - 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 {[info exists result]} { - set value $result - if {$retopt} { - return $value - } - return 1 - } - - if {$retopt} { - set value $default - return $value - } - - return 0 -} - proc option-check-names {args} { foreach o $args { if {$o ni $::autosetup(options)} { autosetup-error "Request for undeclared option --$o" } @@ -393,11 +293,10 @@ # This is a special heading lappend autosetup(optionhelp) $opt "" set header {} continue } - unset -nocomplain defaultvalue equal value #puts "i=$i, opt=$opt" regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value if {$name in $autosetup(options)} { autosetup-error "Option $name already specified" @@ -412,16 +311,10 @@ set opthelp $opt } elseif {$colon eq ""} { # Boolean option lappend autosetup(options) $name - # Check for override - if {[dict exists $autosetup(options-defaults) $name]} { - # A default was specified with options-defaults, so use it - set value [dict get $autosetup(options-defaults) $name] - } - if {$value eq "1"} { set opthelp "--disable-$name" } else { set opthelp "--$name" } @@ -428,12 +321,11 @@ # Set the default if {$value eq ""} { set value 0 } - set defaultvalue $value - dict set autosetup(optdefault) $name $defaultvalue + dict set autosetup(optdefault) $name $value if {[dict exists $autosetup(getopt) $name]} { # The option was specified by the user. Look at the last value. lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue if {$type eq "str"} { @@ -451,38 +343,18 @@ } } else { # String option. lappend autosetup(options) $name - if {$colon eq ":"} { - # Was ":name=default" given? - # 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]} { - dict set autosetup(optdefault) $name $defaultvalue - } - } - - # Maybe override the default value - if {[dict exists $autosetup(options-defaults) $name]} { - # A default was specified with options-defaults, so use it - set defaultvalue [dict get $autosetup(options-defaults) $name] - dict set autosetup(optdefault) $name $defaultvalue - } elseif {![info exists defaultvalue]} { - # For backward compatibility, 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 - set defaultvalue $value - } - if {$equal eq "="} { # String option with optional value set opthelp "--$name?=$value?" } else { # String option with required value set opthelp "--$name=$value" } + dict set autosetup(optdefault) $name $value # Get the values specified by the user if {[dict exists $autosetup(getopt) $name]} { set listvalue {} @@ -491,11 +363,11 @@ if {$type eq "bool" && $setvalue} { if {$equal ne "="} { user-error "Option --$name requires a value" } # If given as a boolean, use the default value - set setvalue $defaultvalue + set setvalue $value } lappend listvalue $setvalue } #puts "Found string option --$name=$listvalue" @@ -504,13 +376,10 @@ } # Now create the help for this option if appropriate if {[lindex $opts $i+1] eq "=>"} { set desc [lindex $opts $i+2] - 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 "" } @@ -594,39 +463,35 @@ options-wrap-desc [string trim $desc] $cols " " $indent [expr $max + 2] } } } -# @options optionspec +# @options options-spec # # Specifies configuration-time options which may be selected by the user -# and checked with 'opt-str' and 'opt-bool'. '$optionspec' contains a series -# of options specifications separated by newlines, as follows: +# and checked with opt-val and opt-bool. The format of options-spec follows. # # A boolean option is of the form: # ## name[=0|1] => "Description of this boolean option" # -# The default is 'name=0', meaning that the option is disabled by default. -# If 'name=1' is used to make the option enabled by default, the description should reflect +# The default is name=0, meaning that the option is disabled by default. +# If name=1 is used to make the option enabled by default, the description should reflect # that with text like "Disable support for ...". # # An argument option (one which takes a parameter) is of the form: # ## name:[=]value => "Description of this option" # -# If the 'name:value' form is used, the value must be provided with the option (as '--name=myvalue'). -# If the 'name:=value' form is used, the value is optional and the given value is used as the default +# If the name:value form is used, the value must be provided with the option (as --name=myvalue). +# If the name:=value form is used, the value is optional and the given value is used as the default # if it is not provided. # -# The description may contain '@default@', in which case it will be replaced with the default -# value for the option (taking into account defaults specified with 'options-defaults'. +# Undocumented options are also supported by omitting the "=> description. +# These options are not displayed with --help and can be useful for internal options or as aliases. # -# Undocumented options are also supported by omitting the '=> description'. -# These options are not displayed with '--help' and can be useful for internal options or as aliases. -# -# For example, '--disable-lfs' is an alias for '--disable=largefile': +# For example, --disable-lfs is an alias for --disable=largefile: # ## lfs=1 largefile=1 => "Disable large file support" # proc options {optlist} { # Allow options as a list or args @@ -645,36 +510,26 @@ } } } } -# @options-defaults dictionary -# -# Specifies a dictionary of options and a new default value for each of those options. -# Use before any 'use' statements in 'auto.def' to change the defaults for -# subsequently included modules. -proc options-defaults {dict} { - foreach {n v} $dict { - dict set ::autosetup(options-defaults) $n $v - } -} - proc config_guess {} { - if {[file-isexec $::autosetup(dir)/autosetup-config.guess]} { - if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.guess} alias]} { + if {[file-isexec $::autosetup(dir)/config.guess]} { + exec-with-stderr sh $::autosetup(dir)/config.guess + if {[catch {exec-with-stderr sh $::autosetup(dir)/config.guess} alias]} { user-error $alias } return $alias } else { - configlog "No autosetup-config.guess, so using uname" + configlog "No config.guess, so using uname" string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r] } } proc config_sub {alias} { - if {[file-isexec $::autosetup(dir)/autosetup-config.sub]} { - if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.sub $alias} alias]} { + if {[file-isexec $::autosetup(dir)/config.sub]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/config.sub $alias} alias]} { user-error $alias } } return $alias } @@ -681,48 +536,39 @@ # @define name ?value=1? # # Defines the named variable to the given value. # These (name, value) pairs represent the results of the configuration check -# and are available to be subsequently checked, modified and substituted. +# and are available to be checked, modified and substituted. # proc define {name {value 1}} { set ::define($name) $value #dputs "$name <= $value" } # @undefine name # -# Undefine the named variable. +# Undefine the named variable # proc undefine {name} { unset -nocomplain ::define($name) #dputs "$name <= " } # @define-append name value ... # -# Appends the given value(s) to the given "defined" variable. -# If the variable is not defined or empty, it is set to '$value'. +# Appends the given value(s) to the given 'defined' variable. +# If the variable is not defined or empty, it is set to $value. # Otherwise the value is appended, separated by a space. # Any extra values are similarly appended. # If any value is already contained in the variable (as a substring) it is omitted. # proc define-append {name args} { if {[get-define $name ""] ne ""} { - # Avoid duplicates + # Make a token attempt to avoid duplicates foreach arg $args { - if {$arg eq ""} { - continue - } - set found 0 - foreach str [split $::define($name) " "] { - if {$str eq $arg} { - incr found - } - } - if {!$found} { + if {[string first $arg $::define($name)] == -1} { append ::define($name) " " $arg } } } else { set ::define($name) [join $args] @@ -730,11 +576,11 @@ #dputs "$name += [join $args] => $::define($name)" } # @get-define name ?default=0? # -# Returns the current value of the "defined" variable, or '$default' +# Returns the current value of the 'defined' variable, or $default # if not set. # proc get-define {name {default 0}} { if {[info exists ::define($name)]} { #dputs "$name => $::define($name)" @@ -750,25 +596,13 @@ # 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. +# Returns a dictionary (name value list) of all defined variables. # # This is suitable for use with 'dict', 'array set' or 'foreach' # and allows for arbitrary processing of the defined variables. # proc all-defines {} { @@ -776,13 +610,13 @@ } # @get-env name default # -# If '$name' was specified on the command line, return it. -# Otherwise if '$name' was set in the environment, return it. -# Otherwise return '$default'. +# If $name was specified on the command line, return it. +# If $name was set in the environment, return it. +# Otherwise return $default. # proc get-env {name default} { if {[dict exists $::autosetup(cmdline) $name]} { return [dict get $::autosetup(cmdline) $name] } @@ -789,11 +623,11 @@ getenv $name $default } # @env-is-set name # -# Returns 1 if '$name' was specified on the command line or in the environment. +# Returns 1 if the $name was specified on the command line or in the environment. # Note that an empty environment variable is not considered to be set. # proc env-is-set {name} { if {[dict exists $::autosetup(cmdline) $name]} { return 1 @@ -805,11 +639,11 @@ } # @readfile filename ?default=""? # # Return the contents of the file, without the trailing newline. -# If the file doesn't exist or can't be read, returns '$default'. +# If the file doesn't exist or can't be read, returns $default. # proc readfile {filename {default_value ""}} { set result $default_value catch { set f [open $filename] @@ -819,11 +653,11 @@ return $result } # @writefile filename value # -# Creates the given file containing '$value'. +# Creates the given file containing $value. # Does not add an extra newline. # proc writefile {filename value} { set f [open $filename w] puts -nonewline $f $value @@ -843,60 +677,63 @@ lappend args [quote-if-needed $arg] } join $args } -# @list-non-empty list +# @suffix suf list +# +# Takes a list and returns a new list with $suf appended +# to each element +# +## suffix .c {a b c} => {a.c b.c c.c} # -# Returns a copy of the given list with empty elements removed -proc list-non-empty {list} { +proc suffix {suf list} { set result {} foreach p $list { - if {$p ne ""} { - lappend result $p - } + lappend result $p$suf } return $result } -# @find-executable-path name -# -# Searches the path for an executable with the given name. -# Note that the name may include some parameters, e.g. 'cc -mbig-endian', -# in which case the parameters are ignored. -# The full path to the executable if found, or "" if not found. -# Returns 1 if found, or 0 if not. -# -proc find-executable-path {name} { - # Ignore any parameters - set name [lindex $name 0] - # The empty string is never a valid executable - if {$name ne ""} { - foreach p [split-path] { - dputs "Looking for $name in $p" - set exec [file join $p $name] - if {[file-isexec $exec]} { - dputs "Found $name -> $exec" - return $exec - } - } - } - return {} +# @prefix pre list +# +# Takes a list and returns a new list with $pre prepended +# to each element +# +## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} +# +proc prefix {pre list} { + set result {} + foreach p $list { + lappend result $pre$p + } + return $result } # @find-executable name # # Searches the path for an executable with the given name. -# Note that the name may include some parameters, e.g. 'cc -mbig-endian', +# Note that the name may include some parameters, e.g. "cc -mbig-endian", # in which case the parameters are ignored. # Returns 1 if found, or 0 if not. # proc find-executable {name} { - if {[find-executable-path $name] eq {}} { + # Ignore any parameters + set name [lindex $name 0] + if {$name eq ""} { + # The empty string is never a valid executable return 0 } - return 1 + foreach p [split-path] { + dputs "Looking for $name in $p" + set exec [file join $p $name] + if {[file-isexec $exec]} { + dputs "Found $name -> $exec" + return 1 + } + } + return 0 } # @find-an-executable ?-required? name ... # # Given a list of possible executable names, @@ -927,11 +764,11 @@ return "" } # @configlog msg # -# Writes the given message to the configuration log, 'config.log'. +# Writes the given message to the configuration log, config.log # proc configlog {msg} { if {![info exists ::autosetup(logfh)]} { set ::autosetup(logfh) [open config.log w] } @@ -963,12 +800,12 @@ } } # @msg-quiet command ... # -# 'msg-quiet' evaluates it's arguments as a command with output -# from 'msg-checking' and 'msg-result' suppressed. +# msg-quiet evaluates it's arguments as a command with output +# from msg-checking and msg-result suppressed. # # This is useful if a check needs to run a subcheck which isn't # of interest to the user. proc msg-quiet {args} { incr ::autosetup(msg-quiet) @@ -1004,11 +841,11 @@ # @user-error msg # # Indicate incorrect usage to the user, including if required components # or features are not found. -# 'autosetup' exits with a non-zero return code. +# autosetup exits with a non-zero return code. # proc user-error {msg} { show-notices puts stderr "Error: $msg" puts stderr "Try: '[file tail $::autosetup(exe)] --help' for options" @@ -1051,21 +888,10 @@ if {$::autosetup(msg-timing) && $::autosetup(msg-checking) == 0} { puts -nonewline [format {[%6.2f] } [expr {([clock millis] - $::autosetup(start)) % 10000 / 1000.0}]] } } -# @autosetup-require-version required -# -# Checks the current version of 'autosetup' against '$required'. -# A fatal error is generated if the current version is less than that required. -# -proc autosetup-require-version {required} { - if {[compare-versions $::autosetup(version) $required] < 0} { - user-error "autosetup version $required is required, but this is $::autosetup(version)" - } -} - proc autosetup_version {} { return "autosetup v$::autosetup(version)" } ################################################################## @@ -1160,35 +986,23 @@ # The latter form is useful for a complex module which requires additional # support file. In this form, '$::usedir' is set to the module directory # when it is loaded. # proc use {args} { - global autosetup libmodule modsource - - set dirs [list $autosetup(libdir)] - if {[info exists autosetup(srcdir)]} { - lappend dirs $autosetup(srcdir)/autosetup - } foreach m $args { - if {[info exists libmodule($m)]} { + if {[info exists ::libmodule($m)]} { continue } - set libmodule($m) 1 - if {[info exists modsource(${m}.tcl)]} { - automf_load eval $modsource(${m}.tcl) + set ::libmodule($m) 1 + if {[info exists ::modsource($m)]} { + automf_load eval $::modsource($m) } else { - set locs [list ${m}.tcl ${m}/init.tcl] + set sources [list $::autosetup(libdir)/${m}.tcl $::autosetup(libdir)/${m}/init.tcl] set found 0 - foreach dir $dirs { - foreach loc $locs { - set source $dir/$loc - if {[file exists $source]} { - incr found - break - } - } - if {$found} { + foreach source $sources { + if {[file exists $source]} { + incr found break } } if {$found} { # For the convenience of the "use" source, point to the directory @@ -1201,22 +1015,10 @@ } } } } -proc autosetup_load_auto_modules {} { - global autosetup modsource - # First load any embedded auto modules - foreach mod [array names modsource *.auto] { - automf_load eval $modsource($mod) - } - # Now any external auto modules - foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { - automf_load source $file - } -} - # Load module source in the global scope by executing the given command proc automf_load {args} { if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] } @@ -1225,21 +1027,18 @@ # Initial settings set autosetup(exe) $::argv0 set autosetup(istcl) 1 set autosetup(start) [clock millis] set autosetup(installed) 0 -set autosetup(sysinstall) 0 set autosetup(msg-checking) 0 set autosetup(msg-quiet) 0 -set autosetup(inittypes) {} # Embedded modules are inserted below here set autosetup(installed) 1 -set autosetup(sysinstall) 0 -# ----- @module asciidoc-formatting.tcl ----- +# ----- module asciidoc-formatting ----- -set modsource(asciidoc-formatting.tcl) { +set modsource(asciidoc-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # asciidoc format @@ -1303,19 +1102,19 @@ regsub -all "\n\n" $defn "\n ::\n" defn puts $defn } } -# ----- @module formatting.tcl ----- +# ----- module formatting ----- -set modsource(formatting.tcl) { +set modsource(formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides common text formatting -# This is designed for documentation which looks like: +# This is designed for documenation which looks like: # code {...} # or # code { # ... # ... @@ -1360,13 +1159,13 @@ # Return the result return $lines } } -# ----- @module getopt.tcl ----- +# ----- module getopt ----- -set modsource(getopt.tcl) { +set modsource(getopt) { # Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Simple getopt module @@ -1398,11 +1197,11 @@ if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} { # --name=value dict lappend opts $name [list str $value] } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} { - if {$prefix in {enable- ""}} { + if {$prefix in {enable- with- ""}} { set value 1 } else { set value 0 } dict lappend opts $name [list bool $value] @@ -1419,13 +1218,13 @@ return $opts } } -# ----- @module help.tcl ----- +# ----- module help ----- -set modsource(help.tcl) { +set modsource(help) { # Copyright (c) 2010 WorkWare Systems http://workware.net.au/ # All rights reserved # Module which provides usage, help and the command reference @@ -1453,28 +1252,10 @@ } } exit 0 } -proc autosetup_show_license {} { - global modsource autosetup - use_pager - - if {[info exists modsource(LICENSE)]} { - puts $modsource(LICENSE) - return - } - foreach dir [list $autosetup(libdir) $autosetup(srcdir)] { - set path [file join $dir LICENSE] - if {[file exists $path]} { - puts [readfile $path] - return - } - } - puts "LICENSE not found" -} - # If not already paged and stdout is a tty, pipe the output through the pager # This is done by reinvoking autosetup with --nopager added proc use_pager {} { if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} { if {[catch { @@ -1523,16 +1304,10 @@ } proc autosetup_output_block {type lines} { if {[llength $lines]} { switch $type { - section { - section $lines - } - subsection { - subsection $lines - } code { codelines $lines } p { p [join $lines] @@ -1550,45 +1325,30 @@ # Generate a command reference from inline documentation proc automf_command_reference {} { lappend files $::autosetup(prog) lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]] - # We want to process all non-module files before module files - # and then modules in alphabetical order. - # So examine all files and extract docs into doc($modulename) and doc(_core_) - # - # Each entry is a list of {type data} where $type is one of: section, subsection, code, list, p - # and $data is a string for section, subsection or a list of text lines for other types. - - # XXX: Should commands be in alphabetical order too? Currently they are in file order. - - set doc(_core_) {} - lappend doc(_core_) [list section "Core Commands"] + section "Core Commands" + set type p + set lines {} + set cmd {} foreach file $files { - set modulename [file rootname [file tail $file]] - set current _core_ set f [open $file] while {![eof $f]} { set line [gets $f] - # Find embedded module names - if {[regexp {^#.*@module ([^ ]*)} $line -> modulename]} { - continue - } - # Find lines starting with "# @*" and continuing through the remaining comment lines if {![regexp {^# @(.*)} $line -> cmd]} { continue } # Synopsis or command? if {$cmd eq "synopsis:"} { - set current $modulename - lappend doc($current) [list section "Module: $modulename"] + section "Module: [file rootname [file tail $file]]" } else { - lappend doc($current) [list subsection $cmd] + subsection $cmd } set lines {} set type p @@ -1609,38 +1369,29 @@ #puts "hash=$hash, oldhash=$oldhash, lines=[llength $lines], cmd=$cmd" if {$t ne $type || $cmd eq ""} { # Finish the current block - lappend doc($current) [list $type $lines] + autosetup_output_block $type $lines set lines {} set type $t } if {$cmd ne ""} { lappend lines $cmd } } - lappend doc($current) [list $type $lines] + autosetup_output_block $type $lines } close $f } - - # Now format and output the results - - # _core_ will sort first - foreach module [lsort [array names doc]] { - foreach item $doc($module) { - autosetup_output_block {*}$item - } - } } } -# ----- @module init.tcl ----- +# ----- module init ----- -set modsource(init.tcl) { +set modsource(init) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module to help create auto.def and configure @@ -1693,157 +1444,79 @@ } writefile $filename $contents } } -# ----- @module install.tcl ----- +# ----- module install ----- -set modsource(install.tcl) { +set modsource(install) { # Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # 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 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}} { - global autosetup - if {$shared} { - if {$autosetup(installed) || $autosetup(sysinstall)} { - user-error "Can only --sysinstall from development sources" - } - } elseif {$autosetup(installed) && !$autosetup(sysinstall)} { - user-error "Can't --install from project install" - } - - if {$autosetup(sysinstall)} { - # This is the sysinstall version, so install just uses references - cd $dir - - puts "[autosetup_version] creating configure to use system-installed autosetup" - autosetup_create_configure 1 - puts "Creating autosetup/README.autosetup" - file mkdir autosetup - autosetup_install_readme autosetup/README.autosetup 1 - return - } - - if {[catch { - if {$shared} { - set target $dir/bin/autosetup - set installedas $target - } else { - if {$dir eq "."} { - set installedas autosetup - } else { - set installedas $dir/autosetup - } - cd $dir - file mkdir autosetup - set target autosetup/autosetup - } - set targetdir [file dirname $target] - file mkdir $targetdir - - set f [open $target w] - - set publicmodules {} +proc autosetup_install {dir} { + if {[catch { + cd $dir + file mkdir autosetup + + set f [open autosetup/autosetup w] + + set publicmodules [glob $::autosetup(libdir)/*.auto] # First the main script, but only up until "CUT HERE" - set in [open $autosetup(dir)/autosetup] + set in [open $::autosetup(dir)/autosetup] while {[gets $in buf] >= 0} { if {$buf ne "##-- CUT HERE --##"} { puts $f $buf continue } # Insert the static modules here # i.e. those which don't contain @synopsis: - # All modules are inserted if $shared is set puts $f "set autosetup(installed) 1" - puts $f "set autosetup(sysinstall) $shared" - foreach file [lsort [glob $autosetup(libdir)/*.{tcl,auto}]] { - set modname [file tail $file] - set ext [file ext $modname] + foreach file [lsort [glob $::autosetup(libdir)/*.tcl]] { set buf [readfile $file] - if {!$shared} { - if {$ext eq ".auto" || [string match "*\n# @synopsis:*" $buf]} { - lappend publicmodules $file - continue - } - } - dputs "install: importing lib/[file tail $file]" - puts $f "# ----- @module $modname -----" + if {[string match "*\n# @synopsis:*" $buf]} { + lappend publicmodules $file + continue + } + set modname [file rootname [file tail $file]] + puts $f "# ----- module $modname -----" puts $f "\nset modsource($modname) \{" puts $f $buf puts $f "\}\n" } - if {$shared} { - foreach {srcname destname} [list $autosetup(libdir)/README.autosetup-lib README.autosetup \ - $autosetup(srcdir)/LICENSE LICENSE] { - dputs "install: importing $srcname as $destname" - puts $f "\nset modsource($destname) \\\n[list [readfile $srcname]\n]\n" - } - } } close $in close $f - catch {exec chmod 755 $target} - - set installfiles {autosetup-config.guess autosetup-config.sub autosetup-test-tclsh} - set removefiles {} - - if {!$shared} { - autosetup_install_readme $targetdir/README.autosetup 0 - - # Install public modules - foreach file $publicmodules { - set tail [file tail $file] - autosetup_install_file $file $targetdir/$tail - } - lappend installfiles jimsh0.c autosetup-find-tclsh LICENSE - lappend removefiles config.guess config.sub test-tclsh find-tclsh - } else { - lappend installfiles {sys-find-tclsh autosetup-find-tclsh} + exec chmod 755 autosetup/autosetup + + # Install public modules + foreach file $publicmodules { + autosetup_install_file $file autosetup } # Install support files - foreach fileinfo $installfiles { - if {[llength $fileinfo] == 2} { - lassign $fileinfo source dest - } else { - lassign $fileinfo source - set dest $source - } - autosetup_install_file $autosetup(dir)/$source $targetdir/$dest - } - - # Remove obsolete files - foreach file $removefiles { - if {[file exists $targetdir/$file]} { - file delete $targetdir/$file - } - } + foreach file {config.guess config.sub jimsh0.c find-tclsh test-tclsh LICENSE} { + autosetup_install_file $::autosetup(dir)/$file autosetup + } + exec chmod 755 autosetup/config.sub autosetup/config.guess autosetup/find-tclsh + + writefile autosetup/README.autosetup \ + "This is [autosetup_version]. See http://msteveb.github.com/autosetup/\n" + } error]} { user-error "Failed to install autosetup: $error" } - if {$shared} { - set type "system" - } else { - set type "local" - } - puts "Installed $type [autosetup_version] to $installedas" - - if {!$shared} { - # Now create 'configure' if necessary - autosetup_create_configure 0 - } + puts "Installed [autosetup_version] to autosetup/" + + # Now create 'configure' if necessary + autosetup_create_configure } -proc autosetup_create_configure {shared} { +proc autosetup_create_configure {} { if {[file exists configure]} { if {!$::autosetup(force)} { # Could this be an autosetup configure? if {![string match "*\nWRAPPER=*" [readfile configure]]} { puts "I see configure, but not created by autosetup, so I won't overwrite it." @@ -1854,75 +1527,40 @@ puts "I will overwrite the existing configure because you used --force." } } else { puts "I don't see configure, so I will create it." } - if {$shared} { - writefile configure \ -{#!/bin/sh -WRAPPER="$0"; export WRAPPER; "autosetup" "$@" -} - } else { - writefile configure \ + 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/find-tclsh`" "$dir/autosetup" "$@" } - } catch {exec chmod 755 configure} } # Append the contents of $file to filehandle $f proc autosetup_install_append {f file} { - dputs "install: include $file" set in [open $file] puts $f [read $in] close $in } -proc autosetup_install_file {source target} { - dputs "install: $source => $target" - if {![file exists $source]} { - error "Missing installation file '$source'" - } - writefile $target [readfile $source]\n - # If possible, copy the file mode - file stat $source stat - set mode [format %o [expr {$stat(mode) & 0x1ff}]] - catch {exec chmod $mode $target} -} - -proc autosetup_install_readme {target sysinstall} { - set readme "README.autosetup created by [autosetup_version]\n\n" - if {$sysinstall} { - append readme \ -{This is the autosetup directory for a system install of autosetup. -Loadable modules can be added here. -} - } else { - append readme \ -{This is the autosetup directory for a local install of autosetup. -It contains autosetup, support files and loadable modules. -} -} - - append readme { -*.tcl files in this directory are optional modules which -can be loaded with the 'use' directive. - -*.auto files in this directory are auto-loaded. - -For more information, see http://msteveb.github.com/autosetup/ -} - dputs "install: autosetup/README.autosetup" - writefile $target $readme -} -} - -# ----- @module markdown-formatting.tcl ----- - -set modsource(markdown-formatting.tcl) { +proc autosetup_install_file {file dir} { + if {![file exists $file]} { + error "Missing installation file '$file'" + } + writefile [file join $dir [file tail $file]] [readfile $file]\n +} + +if {$::autosetup(installed)} { + user-error "autosetup can only be installed from development source, not from installed copy" +} +} + +# ----- module markdown-formatting ----- + +set modsource(markdown-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # markdown format (kramdown syntax) @@ -1989,13 +1627,13 @@ } puts "$defn" } } -# ----- @module misc.tcl ----- +# ----- module misc ----- -set modsource(misc.tcl) { +set modsource(misc) { # Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module containing misc procs useful to modules # Largely for platform compatibility @@ -2167,218 +1805,106 @@ string trim $result } } } -# ----- @module text-formatting.tcl ----- +# ----- module text-formatting ----- -set modsource(text-formatting.tcl) { +set modsource(text-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting use formatting proc wordwrap {text length {firstprefix ""} {nextprefix ""}} { - set len 0 - set space $firstprefix - - foreach word [split $text] { - set word [string trim $word] - if {$word eq ""} { - continue - } - if {[info exists partial]} { - append partial " " $word - if {[string first $quote $word] < 0} { - # Haven't found end of quoted word - continue - } - # Finished quoted word - set word $partial - unset partial - unset quote - } else { - set quote [string index $word 0] - if {$quote in {' *}} { - if {[string first $quote $word 1] < 0} { - # Haven't found end of quoted word - # Not a whole word. - set first [string index $word 0] - # Start of quoted word - set partial $word - continue - } - } - } - - if {$len && [string length $space$word] + $len >= $length} { - puts "" - set len 0 - set space $nextprefix - } - incr len [string length $space$word] - - # Use man-page conventions for highlighting 'quoted' and *quoted* - # single words. - # Use x^Hx for *bold* and _^Hx for 'underline'. - # - # less and more will both understand this. - # Pipe through 'col -b' to remove them. - if {[regexp {^'(.*)'(.*)} $word -> quoted after]} { - set quoted [string map {~ " "} $quoted] - regsub -all . $quoted "&\b&" quoted - set word $quoted$after - } elseif {[regexp {^[*](.*)[*](.*)} $word -> quoted after]} { - set quoted [string map {~ " "} $quoted] - regsub -all . $quoted "_\b&" quoted - set word $quoted$after - } - puts -nonewline $space$word - set space " " - } - if {[info exists partial]} { - # Missing end of quote - puts -nonewline $space$partial - } - if {$len} { - puts "" - } + set len 0 + set space $firstprefix + foreach word [split $text] { + set word [string trim $word] + if {$word == ""} { + continue + } + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + + # Use man-page conventions for highlighting 'quoted' and *quoted* + # single words. + # Use x^Hx for *bold* and _^Hx for 'underline'. + # + # less and more will both understand this. + # Pipe through 'col -b' to remove them. + if {[regexp {^'(.*)'([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { + regsub -all . $bareword "_\b&" word + append word $dot + } elseif {[regexp {^[*](.*)[*]([^a-zA-Z0-9_]*)$} $word -> bareword dot]} { + regsub -all . $bareword "&\b&" word + append word $dot + } + puts -nonewline $space$word + set space " " + } + if {$len} { + puts "" + } } proc title {text} { - underline [string trim $text] = - nl + underline [string trim $text] = + nl } proc p {text} { - wordwrap $text 80 - nl + wordwrap $text 80 + nl } proc codelines {lines} { - foreach line $lines { - puts " $line" - } - nl + foreach line $lines { + puts " $line" + } + nl } proc nl {} { - puts "" + puts "" } proc underline {text char} { - regexp "^(\[ \t\]*)(.*)" $text -> indent words - puts $text - puts $indent[string repeat $char [string length $words]] + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] } proc section {text} { - underline "[string trim $text]" - - nl + underline "[string trim $text]" - + nl } proc subsection {text} { - underline "$text" ~ - nl + underline "$text" ~ + nl } proc bullet {text} { - wordwrap $text 76 " * " " " + wordwrap $text 76 " * " " " } proc indent {text} { - wordwrap $text 76 " " " " + wordwrap $text 76 " " " " } proc defn {first args} { - if {$first ne ""} { - underline " $first" ~ - } - foreach p $args { - if {$p ne ""} { - indent $p - } - } -} -} - -# ----- @module util.tcl ----- - -set modsource(util.tcl) { -# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ -# All rights reserved - -# Module which contains miscellaneous utility functions - -# @compare-versions version1 version2 -# -# Versions are of the form 'a.b.c' (may be any number of numeric components) -# -# Compares the two versions and returns: -## -1 if v1 < v2 -## 0 if v1 == v2 -## 1 if v1 > v2 -# -# If one version has fewer components than the other, 0 is substituted to the right. e.g. -## 0.2 < 0.3 -## 0.2.5 > 0.2 -## 1.1 == 1.1.0 -# -proc compare-versions {v1 v2} { - foreach c1 [split $v1 .] c2 [split $v2 .] { - if {$c1 eq ""} { - set c1 0 - } - if {$c2 eq ""} { - set c2 0 - } - if {$c1 < $c2} { - return -1 - } - if {$c1 > $c2} { - return 1 - } - } - return 0 -} - -# @suffix suf list -# -# Takes a list and returns a new list with '$suf' appended -# to each element -# -## suffix .c {a b c} => {a.c b.c c.c} -# -proc suffix {suf list} { - set result {} - foreach p $list { - lappend result $p$suf - } - return $result -} - -# @prefix pre list -# -# Takes a list and returns a new list with '$pre' prepended -# to each element -# -## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} -# -proc prefix {pre list} { - set result {} - foreach p $list { - lappend result $pre$p - } - return $result -} - -# @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 ----- - -set modsource(wiki-formatting.tcl) { + if {$first ne ""} { + underline " $first" ~ + } + foreach p $args { + if {$p ne ""} { + indent $p + } + } +} +} + +# ----- module wiki-formatting ----- + +set modsource(wiki-formatting) { # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ # All rights reserved # Module which provides text formatting # wiki.tcl.tk format output @@ -2449,11 +1975,11 @@ if {$autosetup(debug)} { main $argv } if {[catch {main $argv} msg opts] == 1} { show-notices - autosetup-full-error [error-dump $msg $opts $autosetup(debug)] + autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] if {!$autosetup(debug)} { puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" } exit 1 } DELETED autosetup/autosetup-config.guess Index: autosetup/autosetup-config.guess ================================================================== --- autosetup/autosetup-config.guess +++ autosetup/autosetup-config.guess @@ -1,1476 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. - -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 -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# 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 . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. -# -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess -# -# Please send patches to . - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -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 - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -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." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) 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 - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -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 -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" - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - 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 - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # 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=`(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 ;; - 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) and ABI. - case "$UNAME_MACHINE_ARCH" in - earm*) - os=netbsdelf - ;; - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - 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 - Debian*) - release='-gnu' - ;; - *) - 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}${abi}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - 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" - 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" - exit ;; - *:SolidBSD:*:*) - echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd"$UNAME_RELEASE" - exit ;; - *:MirBSD:*:*) - 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) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - 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 ;; - "EV4.5 (21064)") - UNAME_MACHINE=alpha ;; - "LCA4 (21066/21068)") - UNAME_MACHINE=alpha ;; - "EV5 (21164)") - UNAME_MACHINE=alphaev5 ;; - "EV5.6 (21164A)") - UNAME_MACHINE=alphaev56 ;; - "EV5.6 (21164PC)") - UNAME_MACHINE=alphapca56 ;; - "EV5.7 (21164PC)") - UNAME_MACHINE=alphapca57 ;; - "EV6 (21264)") - UNAME_MACHINE=alphaev6 ;; - "EV6.7 (21264A)") - UNAME_MACHINE=alphaev67 ;; - "EV6.8CB (21264C)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8AL (21264B)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8CX (21264D)") - UNAME_MACHINE=alphaev68 ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE=alphaev69 ;; - "EV7 (21364)") - UNAME_MACHINE=alphaev7 ;; - "EV7.9 (21364A)") - 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`" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix"$UNAME_RELEASE" - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - 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/[^.]*//'`" - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux"$UNAME_RELEASE" - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - 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 (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH=x86_64 - fi - fi - 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/[^.]*//'`" - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" - exit ;; - sun3*:SunOS:*:*) - 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 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos"$UNAME_RELEASE" - ;; - sun4) - echo sparc-sun-sunos"$UNAME_RELEASE" - ;; - esac - exit ;; - aushp:SunOS:*:*) - 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 - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # 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" - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint"$UNAME_RELEASE" - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint"$UNAME_RELEASE" - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint"$UNAME_RELEASE" - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten"$UNAME_RELEASE" - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten"$UNAME_RELEASE" - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix"$UNAME_RELEASE" - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix"$UNAME_RELEASE" - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix"$UNAME_RELEASE" - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - 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); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - 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"` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos"$UNAME_RELEASE" - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] - then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] - then - echo m88k-dg-dgux"$UNAME_RELEASE" - else - echo m88k-dg-dguxbcs"$UNAME_RELEASE" - fi - else - echo i586-dg-dgux"$UNAME_RELEASE" - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - 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 - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" - fi - 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" - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - 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 - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/lslpp ] ; then - 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" - fi - echo "$IBM_ARCH"-ibm-aix"$IBM_REV" - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - 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 - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - 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 ;; - 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 - 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 - esac ;; - esac - fi - if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (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 ] - then - 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 - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH=hppa2.0w - else - HP_ARCH=hppa64 - fi - fi - 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" - exit ;; - 3050*:HI-UX:*:*) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $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:*:*) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo "$UNAME_MACHINE"-unknown-osf1mk - else - echo "$UNAME_MACHINE"-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - 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/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - 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/ /_/'` - 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/ /_/'` - 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" - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi"$UNAME_RELEASE" - exit ;; - *:BSD/OS:*:*) - echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in - amd64) - 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 - exit ;; - *:MINGW64*:*) - echo "$UNAME_MACHINE"-pc-mingw64 - exit ;; - *:MINGW*:*) - echo "$UNAME_MACHINE"-pc-mingw32 - exit ;; - *:MSYS*:*) - echo "$UNAME_MACHINE"-pc-msys - exit ;; - i*:PW*:*) - echo "$UNAME_MACHINE"-pc-pw32 - exit ;; - *:Interix*:*) - case "$UNAME_MACHINE" in - x86) - echo i586-pc-interix"$UNAME_RELEASE" - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix"$UNAME_RELEASE" - exit ;; - IA64) - echo ia64-unknown-interix"$UNAME_RELEASE" - exit ;; - esac ;; - i*:UWIN*:*) - echo "$UNAME_MACHINE"-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - 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,/.*$,,'`" - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - 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 - exit ;; - aarch64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - 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" - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arm*:Linux:*:*) - 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" - 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 - else - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - cris:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; - crisv32:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; - e2k:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - frv:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - hexagon:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - i*86:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; - ia64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - k1om:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - m32r*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - m68*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" - sed 's/^ //' << EOF > "$dummy.c" - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #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; } - ;; - mips64el:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - openrisc*:Linux:*:*) - echo or1k-unknown-linux-"$LIBC" - exit ;; - or32:Linux:*:* | or1k*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-"$LIBC" - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - 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" ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-"$LIBC" - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-"$LIBC" - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-"$LIBC" - exit ;; - ppcle:Linux:*:*) - 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" - exit ;; - sh64*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - sh*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - tile*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - vax:Linux:*:*) - echo "$UNAME_MACHINE"-dec-linux-"$LIBC" - exit ;; - x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; - xtensa*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # 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" - 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 - exit ;; - i*86:XTS-300:*:STOP) - echo "$UNAME_MACHINE"-unknown-stop - exit ;; - i*86:atheos:*:*) - echo "$UNAME_MACHINE"-unknown-atheos - exit ;; - i*86: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" - exit ;; - i*86:*DOS:*:*) - echo "$UNAME_MACHINE"-pc-msdosdjgpp - exit ;; - 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" - else - echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - 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 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" - else - echo "$UNAME_MACHINE"-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # 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 configure will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - 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 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - 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; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { 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; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - 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; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { 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; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - 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" - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos"$UNAME_RELEASE" - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos"$UNAME_RELEASE" - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv"$UNAME_RELEASE" - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo "$UNAME_MACHINE"-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - 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" - 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" - else - echo mips-unknown-sysv"$UNAME_RELEASE" - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux"$UNAME_RELEASE" - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux"$UNAME_RELEASE" - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux"$UNAME_RELEASE" - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux"$UNAME_RELEASE" - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux"$UNAME_RELEASE" - exit ;; - SX-8R:SUPER-UX:*:*) - 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" - exit ;; - *:Rhapsody:*:*) - echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - 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 (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (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 - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 - fi - echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = x86; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - 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" - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk"$UNAME_RELEASE" - exit ;; - 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 - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - 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 - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo "$UNAME_MACHINE"-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux"$UNAME_RELEASE" - exit ;; - *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" - exit ;; - i*86:rdos:*:*) - echo "$UNAME_MACHINE"-pc-rdos - exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros - exit ;; - x86_64:VMkernel:*:*) - 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 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 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" -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: DELETED autosetup/autosetup-config.sub Index: autosetup/autosetup-config.sub ================================================================== --- autosetup/autosetup-config.sub +++ autosetup/autosetup-config.sub @@ -1,1801 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2018 Free Software Foundation, Inc. - -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 -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# 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 . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# 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 -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS - -Canonicalize a configuration name. - -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 - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -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." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo "$1" - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -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/'` -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* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - 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/-[^-]*$//'` - if [ "$basic_machine" != "$1" ] - then os=`echo "$1" | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - 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/'` - ;; - -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/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - 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/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | 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 \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | 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[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | 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-* \ - | 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-* | ia16-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | 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*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # 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-pc - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - 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 - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - 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 - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - x64) - basic_machine=x86_64-pc - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # 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 - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # 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. - # -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* | -cloudabi* | -sortix* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -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* | -hcos* \ - | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -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*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -xray | -os68k* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo "$os" | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo "$os" | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo "$os" | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4*) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -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 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - c8051-*) - os=-elf - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - pru-*) - os=-elf - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` - ;; -esac - -echo "$basic_machine$os" -exit - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: DELETED autosetup/autosetup-find-tclsh Index: autosetup/autosetup-find-tclsh ================================================================== --- autosetup/autosetup-find-tclsh +++ autosetup/autosetup-find-tclsh @@ -1,17 +0,0 @@ -#!/bin/sh -# Looks for a suitable tclsh or jimsh in the PATH -# If not found, builds a bootstrap jimsh from source -# Prefer $autosetup_tclsh if is set in the environment -d=`dirname "$0"` -{ "$d/jimsh0" "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0 -PATH="$PATH:$d"; export PATH -for tclsh in $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6; do - { $tclsh "$d/autosetup-test-tclsh"; } 2>/dev/null && exit 0 -done -echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" -for cc in ${CC_FOR_BUILD:-cc} gcc; do - { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue - "$d/jimsh0" "$d/autosetup-test-tclsh" && exit 0 -done -echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." -echo false DELETED autosetup/autosetup-test-tclsh Index: autosetup/autosetup-test-tclsh ================================================================== --- autosetup/autosetup-test-tclsh +++ autosetup/autosetup-test-tclsh @@ -1,20 +0,0 @@ -# A small Tcl script to verify that the chosen -# interpreter works. Sometimes we might e.g. pick up -# an interpreter for a different arch. -# Outputs the full path to the interpreter - -if {[catch {info version} version] == 0} { - # This is Jim Tcl - if {$version >= 0.72} { - # Ensure that regexp works - regexp (a.*?) a - puts [info nameofexecutable] - exit 0 - } -} elseif {[catch {info tclversion} version] == 0} { - if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { - puts [info nameofexecutable] - exit 0 - } -} -exit 1 Index: autosetup/cc-db.tcl ================================================================== --- autosetup/cc-db.tcl +++ autosetup/cc-db.tcl @@ -1,15 +1,15 @@ # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # -# The 'cc-db' module provides a knowledge-base of system idiosyncrasies. -# In general, this module can always be included. +# The 'cc-db' module provides a knowledge based of system idiosyncrasies +# In general, this module can always be included use cc module-options {} # openbsd needs sys/types.h to detect some system headers cc-include-needs sys/socket.h sys/types.h cc-include-needs netinet/in.h sys/types.h Index: autosetup/cc-lib.tcl ================================================================== --- autosetup/cc-lib.tcl +++ autosetup/cc-lib.tcl @@ -9,12 +9,12 @@ module-options {} # @cc-check-lfs # -# The equivalent of the 'AC_SYS_LARGEFILE' macro. -# +# The equivalent of the AC_SYS_LARGEFILE macro +# # defines 'HAVE_LFS' if LFS is available, # and defines '_FILE_OFFSET_BITS=64' if necessary # # Returns 1 if 'LFS' is available or 0 otherwise # @@ -35,12 +35,12 @@ return $lfs } # @cc-check-endian # -# The equivalent of the 'AC_C_BIGENDIAN' macro. -# +# The equivalent of the AC_C_BIGENDIAN macro +# # defines 'HAVE_BIG_ENDIAN' if endian is known to be big, # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. # # Returns 1 if determined, or 0 if not. # @@ -80,110 +80,112 @@ # # Checks whether the given C/C++ compiler flags can be used. Defines feature # names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and # appends working flags to '-cflags' and 'CFLAGS' or 'CXXFLAGS'. proc cc-check-flags {args} { - set result 1 - array set opts [cc-get-settings] - switch -exact -- $opts(-lang) { - c++ { - set lang C++ - set prefix CXXFLAG - } - c { - set lang C - set prefix CFLAG - } - default { - autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" - } - } - foreach flag $args { - msg-checking "Checking whether the $lang compiler accepts $flag..." - if {[cctest -cflags $flag]} { - msg-result yes - define-feature $prefix$flag - cc-with [list -cflags [list $flag]] - define-append ${prefix}S $flag - } else { - msg-result no - set result 0 - } - } - return $result + set result 1 + array set opts [cc-get-settings] + switch -exact -- $opts(-lang) { + c++ { + set lang C++ + set prefix CXXFLAG + } + c { + set lang C + set prefix CFLAG + } + default { + autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" + } + } + foreach flag $args { + msg-checking "Checking whether the $lang compiler accepts $flag..." + if {[cctest -cflags $flag]} { + msg-result yes + define-feature $prefix$flag + cc-with [list -cflags [list $flag]] + define-append ${prefix}S $flag + } else { + msg-result no + set result 0 + } + } + return $result } # @cc-check-standards ver ?...? # # Checks whether the C/C++ compiler accepts one of the specified '-std=$ver' # options, and appends the first working one to '-cflags' and 'CFLAGS' or # 'CXXFLAGS'. proc cc-check-standards {args} { - array set opts [cc-get-settings] - foreach std $args { - if {[cc-check-flags -std=$std]} { - return $std - } - } - return "" + array set opts [cc-get-settings] + foreach std $args { + if {[cc-check-flags -std=$std]} { + return $std + } + } + return "" } # Checks whether $keyword is usable as alignof proc cctest_alignof {keyword} { - msg-checking "Checking for $keyword..." - if {[cctest -code "int x = ${keyword}(char), y = ${keyword}('x');"]} then { - msg-result ok - define-feature $keyword - } else { - msg-result "not found" - } + msg-checking "Checking for $keyword..." + if {[cctest -code [subst -nobackslashes { + printf("minimum alignment is %d == %d\n", ${keyword}(char), ${keyword}('x')); + }]]} then { + msg-result ok + define-feature $keyword + } else { + msg-result "not found" + } } # @cc-check-c11 # # Checks for several C11/C++11 extensions and their alternatives. Currently # checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'. proc cc-check-c11 {} { - msg-checking "Checking for _Static_assert..." - if {[cctest -code { - _Static_assert(1, "static assertions are available"); - }]} then { - msg-result ok - define-feature _Static_assert - } else { - msg-result "not found" - } - - cctest_alignof _Alignof - cctest_alignof __alignof__ - cctest_alignof __alignof + msg-checking "Checking for _Static_assert..." + if {[cctest -code { + _Static_assert(1, "static assertions are available"); + }]} then { + msg-result ok + define-feature _Static_assert + } else { + msg-result "not found" + } + + cctest_alignof _Alignof + cctest_alignof __alignof__ + cctest_alignof __alignof } # @cc-check-alloca # -# The equivalent of the 'AC_FUNC_ALLOCA' macro. +# The equivalent of the AC_FUNC_ALLOCA macro # -# Checks for the existence of 'alloca' -# defines 'HAVE_ALLOCA' and returns 1 if it exists. +# Checks for the existence of alloca +# defines HAVE_ALLOCA and returns 1 if it exists proc cc-check-alloca {} { - cc-check-some-feature alloca { - cctest -includes alloca.h -code { alloca (2 * sizeof (int)); } - } + cc-check-some-feature alloca { + cctest -includes alloca.h -code { alloca (2 * sizeof (int)); } + } } # @cc-signal-return-type # -# The equivalent of the 'AC_TYPE_SIGNAL' macro. +# The equivalent of the AC_TYPE_SIGNAL macro # -# defines 'RETSIGTYPE' to 'int' or 'void'. +# defines RETSIGTYPE to int or void proc cc-signal-return-type {} { - msg-checking "Checking return type of signal handlers..." - cc-with {-includes {sys/types.h signal.h}} { - if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} { - set type int - } else { - set type void - } - define RETSIGTYPE $type - msg-result $type - } + msg-checking "Checking return type of signal handlers..." + cc-with {-includes {sys/types.h signal.h}} { + if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} { + set type int + } else { + set type void + } + define RETSIGTYPE $type + msg-result $type + } } Index: autosetup/cc-shared.tcl ================================================================== --- autosetup/cc-shared.tcl +++ autosetup/cc-shared.tcl @@ -7,30 +7,27 @@ # It defines the following variables: # ## 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 {} # 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, define LD_LIBRARY_PATH LD_LIBRARY_PATH define STRIPLIBFLAGS --strip-unneeded @@ -47,20 +44,18 @@ define SH_LDFLAGS -dynamiclib define SH_LINKFLAGS "" 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 } *-*-ming* - *-*-cygwin - *-*-msys { define SHOBJ_CFLAGS "" 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 define SH_SOPREFIX "" define LD_LIBRARY_PATH PATH @@ -67,23 +62,27 @@ } sparc* { 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 define SH_LINKFLAGS -Wl,-export-dynamic define SH_SOPREFIX -Wl,-h, @@ -104,10 +103,15 @@ define SH_LDFLAGS -shared define SH_LINKFLAGS "" 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]} { define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS] } Index: autosetup/cc.tcl ================================================================== --- autosetup/cc.tcl +++ autosetup/cc.tcl @@ -2,18 +2,17 @@ # All rights reserved # @synopsis: # # The 'cc' module supports checking various 'features' of the C or C++ -# compiler/linker environment. Common commands are 'cc-check-includes', -# 'cc-check-types', 'cc-check-functions', 'cc-with', 'make-config-header' and 'make-template'. +# compiler/linker environment. Common commands are cc-check-includes, +# cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template. # # The following environment variables are used if set: # ## 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 ## LDFLAGS - Additional compiler flags during linking ## LIBS - Additional libraries to use (for all tests) @@ -28,10 +27,15 @@ ## LD use system module-options {} + +# Note that the return code is not meaningful +proc cc-check-something {name code} { + uplevel 1 $code +} # Checks for the existence of the given function by linking # proc cctest_function {function} { cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" @@ -64,12 +68,12 @@ } # @cc-check-sizeof type ... # # Checks the size of the given types (between 1 and 32, inclusive). -# Defines a variable with the size determined, or 'unknown' otherwise. -# e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'. +# Defines a variable with the size determined, or "unknown" otherwise. +# e.g. for type 'long long', defines SIZEOF_LONG_LONG. # Returns the size of the last type. # proc cc-check-sizeof {args} { foreach type $args { msg-checking "Checking for sizeof $type..." @@ -105,11 +109,11 @@ return $ret } # @cc-check-includes includes ... # -# Checks that the given include files can be used. +# Checks that the given include files can be used proc cc-check-includes {args} { cc-check-some-feature $args { set with {} if {[dict exists $::autosetup(cc-include-deps) $each]} { set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] @@ -130,12 +134,12 @@ } } # @cc-include-needs include required ... # -# Ensures that when checking for '$include', a check is first -# made for each '$required' file, and if found, it is included with '#include'. +# Ensures that when checking for 'include', a check is first +# made for each 'required' file, and if found, it is #included proc cc-include-needs {file args} { foreach depfile $args { dict set ::autosetup(cc-include-deps) $file $depfile 1 } } @@ -149,22 +153,22 @@ } } # @cc-check-defines define ... # -# Checks that the given preprocessor symbols are defined. +# Checks that the given preprocessor symbol is defined proc cc-check-defines {args} { cc-check-some-feature $args { cctest_define $each } } # @cc-check-decls name ... # # Checks that each given name is either a preprocessor symbol or rvalue -# such as an enum. Note that the define used is 'HAVE_DECL_xxx' -# rather than 'HAVE_xxx'. +# such as an enum. Note that the define used is HAVE_DECL_xxx +# rather than HAVE_xxx proc cc-check-decls {args} { set ret 1 foreach name $args { msg-checking "Checking for $name..." set r [cctest_decl $name] @@ -179,21 +183,21 @@ return $ret } # @cc-check-functions function ... # -# Checks that the given functions exist (can be linked). +# Checks that the given functions exist (can be linked) proc cc-check-functions {args} { cc-check-some-feature $args { cctest_function $each } } # @cc-check-members type.member ... # # Checks that the given type/structure members exist. -# A structure member is of the form 'struct stat.st_mtime'. +# A structure member is of the form "struct stat.st_mtime" proc cc-check-members {args} { cc-check-some-feature $args { cctest_member $each } } @@ -203,20 +207,20 @@ # Checks that the given function can be found in one of the libs. # # First checks for no library required, then checks each of the libraries # in turn. # -# If the function is found, the feature is defined and 'lib_$function' is defined -# to '-l$lib' where the function was found, or "" if no library required. -# In addition, '-l$lib' is prepended to the 'LIBS' define. +# If the function is found, the feature is defined and lib_$function is defined +# to -l$lib where the function was found, or "" if no library required. +# In addition, -l$lib is prepended to the LIBS define. # # If additional libraries may be needed for linking, they should be specified -# with '$extralibs' as '-lotherlib1 -lotherlib2'. -# These libraries are not automatically added to 'LIBS'. +# as $extralibs as "-lotherlib1 -lotherlib2". +# 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 cc-with [list -libs $otherlibs] { if {[cctest_function $function]} { @@ -236,12 +240,13 @@ } } } } } - define-feature $function $found - if {!$found} { + if {$found} { + define [feature-define-name $function] + } else { msg-result "no" } return $found } @@ -248,16 +253,16 @@ # @cc-check-tools tool ... # # Checks for existence of the given compiler tools, taking # into account any cross compilation prefix. # -# For example, when checking for 'ar', first 'AR' is checked on the command -# line and then in the environment. If not found, '${host}-ar' or -# simply 'ar' is assumed depending upon whether cross compiling. -# The path is searched for this executable, and if found 'AR' is defined +# For example, when checking for "ar", first AR is checked on the command +# line and then in the environment. If not found, "${host}-ar" or +# simply "ar" is assumed depending upon whether cross compiling. +# The path is searched for this executable, and if found AR is defined # to the executable name. -# Note that even when cross compiling, the simple 'ar' is used as a fallback, +# Note that even when cross compiling, the simple "ar" is used as a fallback, # but a warning is generated. This is necessary for some toolchains. # # It is an error if the executable is not found. # proc cc-check-tools {args} { @@ -279,14 +284,14 @@ # @cc-check-progs prog ... # # Checks for existence of the given executables on the path. # -# For example, when checking for 'grep', the path is searched for -# the executable, 'grep', and if found 'GREP' is defined as 'grep'. +# For example, when checking for "grep", the path is searched for +# the executable, 'grep', and if found GREP is defined as "grep". # -# If the executable is not found, the variable is defined as 'false'. +# If the executable is not found, the variable is defined as false. # Returns 1 if all programs were found, or 0 otherwise. # proc cc-check-progs {args} { set failed 0 foreach prog $args { @@ -299,33 +304,10 @@ } else { msg-result ok define $PROG $prog } } - expr {!$failed} -} - -# @cc-path-progs prog ... -# -# Like cc-check-progs, but sets the define to the full path rather -# than just the program name. -# -proc cc-path-progs {args} { - set failed 0 - foreach prog $args { - set PROG [string toupper $prog] - msg-checking "Checking for $prog..." - set path [find-executable-path $prog] - if {$path eq ""} { - msg-result no - define $PROG false - incr failed - } else { - msg-result $path - define $PROG $path - } - } expr {!$failed} } # Adds the given settings to $::autosetup(ccsettings) and # returns the old settings. @@ -344,18 +326,18 @@ foreach {name value} $settings { switch -exact -- $name { -cflags - -includes { # These are given as lists - lappend new($name) {*}[list-non-empty $value] + lappend new($name) {*}$value } -declare { lappend new($name) $value } -libs { # Note that new libraries are added before previous libraries - set new($name) [list {*}[list-non-empty $value] {*}$new($name)] + set new($name) [list {*}$value {*}$new($name)] } -link - -lang - -nooutput { set new($name) $value } -source - -sourcefile - -code { @@ -391,16 +373,16 @@ return $prev } # @cc-with settings ?{ script }? # -# Sets the given 'cctest' settings and then runs the tests in '$script'. -# Note that settings such as '-lang' replace the current setting, while -# those such as '-includes' are appended to the existing setting. +# Sets the given 'cctest' settings and then runs the tests in 'script'. +# Note that settings such as -lang replace the current setting, while +# those such as -includes are appended to the existing setting. # # If no script is given, the settings become the default for the remainder -# of the 'auto.def' file. +# of the auto.def file. # ## cc-with {-lang c++} { ## # This will check with the C++ compiler ## cc-check-types bool ## cc-with {-includes signal.h} { @@ -408,11 +390,11 @@ ## ... ## } ## # back to just the C++ compiler ## } # -# The '-libs' setting is special in that newer values are added *before* earlier ones. +# The -libs setting is special in that newer values are added *before* earlier ones. # ## cc-with {-libs {-lc -lm}} { ## cc-with {-libs -ldl} { ## cctest -libs -lsocket ... ## # libs will be in this order: -lsocket -ldl -lc -lm @@ -433,12 +415,12 @@ return $result } } # @cctest ?settings? -# -# Low level C/C++ compiler checker. Compiles and or links a small C program +# +# Low level C compiler checker. Compiles and or links a small C program # according to the arguments and returns 1 if OK, or 0 if not. # # Supported settings are: # ## -cflags cflags A list of flags to pass to the compiler @@ -450,11 +432,11 @@ ## -code code Code to compile in the body of main() ## -source code Compile a complete program. Ignore -includes, -declare and -code ## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file] ## -nooutput 1 Treat any compiler output (e.g. a warning) as an error # -# Unless '-source' or '-sourcefile' is specified, the C program looks like: +# Unless -source or -sourcefile is specified, the C program looks like: # ## #include /* same for remaining includes in the list */ ## ## declare-code /* any code in -declare, verbatim */ ## @@ -464,10 +446,11 @@ ## } # # Any failures are recorded in 'config.log' # proc cctest {args} { + set src conftest__.c set tmp conftest__ # Easiest way to merge in the settings cc-with $args { array set opts [cc-get-settings] @@ -505,15 +488,13 @@ # Build the command line set cmdline {} 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 { autosetup-error "cctest called with unknown language: $opts(-lang)" } @@ -573,32 +554,32 @@ return $ok } # @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*? # -# Deprecated - see 'make-config-header' +# Deprecated - see make-config-header proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} { user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead" make-config-header $file -auto $autopatterns -bare $barepatterns } # @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ... # # Examines all defined variables which match the given patterns -# and writes an include file, '$file', which defines each of these. +# and writes an include file, $file, which defines each of these. # Variables which match '-auto' are output as follows: -# - defines which have the value '0' are ignored. +# - defines which have the value "0" are ignored. # - defines which have integer values are defined as the integer value. -# - any other value is defined as a string, e.g. '"value"' +# - any other value is defined as a string, e.g. "value" # Variables which match '-bare' are defined as-is. -# Variables which match '-str' are defined as a string, e.g. '"value"' +# Variables which match '-str' are defined as a string, e.g. "value" # Variables which match '-none' are omitted. # -# Note that order is important. The first pattern that matches is selected. +# Note that order is important. The first pattern which matches is selected # Default behaviour is: # -## -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * +# -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * # # If the file would be unchanged, it is not written. proc make-config-header {file args} { set guard _[string toupper [regsub -all {[^a-zA-Z0-9]} [file tail $file] _]] file mkdir [file dirname $file] @@ -697,19 +678,10 @@ user-error "Could not find a C compiler. Tried: [join $try ", "]" } 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) {} msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS]" ADDED autosetup/config.guess Index: autosetup/config.guess ================================================================== --- autosetup/config.guess +++ autosetup/config.guess @@ -0,0 +1,1421 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-11-04' + +# 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 +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# 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 +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2014 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) 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 + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +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 +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 + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +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*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # 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 + 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 ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + 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 + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + 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}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + 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} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + 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" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + 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'` + # 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 + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + 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/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + 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 (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + 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/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + 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 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + 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 + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # 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} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + 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); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + 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` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + 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 + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + 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 + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + 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 + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + 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} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + 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 + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + 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 ;; + 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 + 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 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (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" ] + then + 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 + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + 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} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $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:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + 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/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + 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/ /_/'` + 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/ /_/'` + 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} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + 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/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + 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 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + 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 + 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/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + 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} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + 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} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + 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} + 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 + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #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; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + 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} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # 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} + 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 + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86: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} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V: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} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + 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 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # 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 + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + 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 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { 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; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { 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; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + 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} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + 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} + 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} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + 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 (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (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 + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + 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} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + 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 + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 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} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: ADDED autosetup/config.sub Index: autosetup/config.sub ================================================================== --- autosetup/config.sub +++ autosetup/config.sub @@ -0,0 +1,1807 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-12-03' + +# 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 +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# 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 + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2014 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +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/'` +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* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + 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/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + 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/'` + ;; + -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/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + 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/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | 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 \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | 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-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | 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?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # 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 + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + 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 + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + 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) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + 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 + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + 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 + ;; + we32k) + basic_machine=we32k-att + ;; + 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 + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # 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 + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -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. + # The portable systems comes first. + # 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* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -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* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -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 + ;; + -nacl*) + ;; + -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 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: ADDED autosetup/find-tclsh Index: autosetup/find-tclsh ================================================================== --- autosetup/find-tclsh +++ autosetup/find-tclsh @@ -0,0 +1,16 @@ +#!/bin/sh +# Looks for a suitable tclsh or jimsh in the PATH +# If not found, builds a bootstrap jimsh from source +d=`dirname "$0"` +{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0 +PATH="$PATH:$d"; export PATH +for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do + { $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0 +done +echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" +for cc in ${CC_FOR_BUILD:-cc} gcc; do + { $cc -o "$d/jimsh0" "$d/jimsh0.c"; } 2>/dev/null || continue + "$d/jimsh0" "$d/test-tclsh" && exit 0 +done +echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." +echo false Index: autosetup/jimsh0.c ================================================================== --- autosetup/jimsh0.c +++ autosetup/jimsh0.c @@ -1,7 +1,9 @@ /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ +#define _GNU_SOURCE #define JIM_TCL_COMPAT +#define JIM_REFERENCES #define JIM_ANSIC #define JIM_REGEXP #define HAVE_NO_AUTOCONF #define _JIMAUTOCONF_H #define TCL_LIBRARY "." @@ -29,39 +31,24 @@ #define HAVE_MKDIR_ONE_ARG #define HAVE_SYSTEM #define HAVE_SYS_TIME_H #define HAVE_DIRENT_H #define HAVE_UNISTD_H -#define HAVE_UMASK -#include -#ifndef S_IRWXG -#define S_IRWXG 0 -#endif -#ifndef S_IRWXO -#define S_IRWXO 0 -#endif #else #define TCL_PLATFORM_OS "unknown" #define TCL_PLATFORM_PLATFORM "unix" #define TCL_PLATFORM_PATH_SEPARATOR ":" -#ifdef _MINIX -#define vfork fork -#define _POSIX_SOURCE -#else -#define _GNU_SOURCE -#endif #define HAVE_VFORK #define HAVE_WAITPID #define HAVE_ISATTY #define HAVE_MKSTEMP #define HAVE_LINK #define HAVE_SYS_TIME_H #define HAVE_DIRENT_H #define HAVE_UNISTD_H -#define HAVE_UMASK #endif -#define JIM_VERSION 78 +#define JIM_VERSION 76 #ifndef JIM_WIN32COMPAT_H #define JIM_WIN32COMPAT_H @@ -101,10 +88,11 @@ #define JIM_WIDE_MIN LLONG_MIN #define JIM_WIDE_MAX LLONG_MAX #define JIM_WIDE_MODIFIER "I64d" #define strcasecmp _stricmp #define strtoull _strtoui64 +#define snprintf _snprintf #include struct timeval { long tv_sec; @@ -117,23 +105,28 @@ struct dirent { char *d_name; }; typedef struct DIR { - long handle; + long handle; struct _finddata_t info; - struct dirent result; - char *name; + struct dirent result; + char *name; } DIR; DIR *opendir(const char *name); int closedir(DIR *dir); struct dirent *readdir(DIR *dir); +#elif defined(__MINGW32__) + +#include +#define strtod __strtod + #endif -#endif +#endif #ifdef __cplusplus } #endif @@ -153,21 +146,19 @@ #ifndef JIM_UTF8 #include -#define utf8_strlen(S, B) ((B) < 0 ? (int)strlen(S) : (B)) -#define utf8_strwidth(S, B) utf8_strlen((S), (B)) +#define utf8_strlen(S, B) ((B) < 0 ? strlen(S) : (B)) #define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1) #define utf8_getchars(CP, C) (*(CP) = (C), 1) #define utf8_upper(C) toupper(C) #define utf8_title(C) toupper(C) #define utf8_lower(C) tolower(C) #define utf8_index(C, I) (I) #define utf8_charlen(C) 1 #define utf8_prev_len(S, L) 1 -#define utf8_width(C) 1 #else #endif @@ -184,13 +175,13 @@ extern "C" { #endif #include #include -#include -#include -#include +#include +#include +#include #ifndef HAVE_NO_AUTOCONF #endif @@ -233,31 +224,31 @@ #define JIM_SIGNAL 5 #define JIM_EXIT 6 #define JIM_EVAL 7 -#define JIM_MAX_CALLFRAME_DEPTH 1000 -#define JIM_MAX_EVAL_DEPTH 2000 +#define JIM_MAX_CALLFRAME_DEPTH 1000 +#define JIM_MAX_EVAL_DEPTH 2000 #define JIM_PRIV_FLAG_SHIFT 20 -#define JIM_NONE 0 -#define JIM_ERRMSG 1 -#define JIM_ENUM_ABBREV 2 -#define JIM_UNSHARED 4 -#define JIM_MUSTEXIST 8 - - -#define JIM_SUBST_NOVAR 1 -#define JIM_SUBST_NOCMD 2 -#define JIM_SUBST_NOESC 4 -#define JIM_SUBST_FLAG 128 - - -#define JIM_CASESENS 0 -#define JIM_NOCASE 1 +#define JIM_NONE 0 +#define JIM_ERRMSG 1 +#define JIM_ENUM_ABBREV 2 +#define JIM_UNSHARED 4 +#define JIM_MUSTEXIST 8 + + +#define JIM_SUBST_NOVAR 1 +#define JIM_SUBST_NOCMD 2 +#define JIM_SUBST_NOESC 4 +#define JIM_SUBST_FLAG 128 + + +#define JIM_CASESENS 0 +#define JIM_NOCASE 1 #define JIM_PATH_LEN 1024 @@ -348,80 +339,79 @@ #define Jim_GetHashTableSize(ht) ((ht)->size) #define Jim_GetHashTableUsed(ht) ((ht)->used) typedef struct Jim_Obj { - char *bytes; - const struct Jim_ObjType *typePtr; - int refCount; - int length; - + char *bytes; + const struct Jim_ObjType *typePtr; + int refCount; + int length; + union { - + jim_wide wideValue; - + int intValue; - + double doubleValue; - + void *ptr; - + struct { void *ptr1; void *ptr2; } twoPtrValue; - - struct { - void *ptr; - int int1; - int int2; - } ptrIntValue; - + struct { struct Jim_Var *varPtr; - unsigned long callFrameId; - int global; + unsigned long callFrameId; + int global; } varValue; - + struct { struct Jim_Obj *nsObj; struct Jim_Cmd *cmdPtr; - unsigned long procEpoch; + unsigned long procEpoch; } cmdValue; - + struct { - struct Jim_Obj **ele; - int len; - int maxLen; + struct Jim_Obj **ele; + int len; + int maxLen; } listValue; - + struct { int maxLength; - int charLength; + int charLength; } strValue; - + struct { unsigned long id; struct Jim_Reference *refPtr; } refValue; - + struct { struct Jim_Obj *fileNameObj; int lineNumber; } sourceValue; - + struct { struct Jim_Obj *varNameObjPtr; struct Jim_Obj *indexObjPtr; } dictSubstValue; + + struct { + void *compre; + unsigned flags; + } regexpValue; struct { int line; int argc; } scriptLineValue; } internalRep; - struct Jim_Obj *prevObjPtr; - struct Jim_Obj *nextObjPtr; + struct Jim_Obj *prevObjPtr; + struct Jim_Obj *nextObjPtr; } Jim_Obj; #define Jim_IncrRefCount(objPtr) \ ++(objPtr)->refCount @@ -452,40 +442,40 @@ typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp, struct Jim_Obj *srcPtr, Jim_Obj *dupPtr); typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr); typedef struct Jim_ObjType { - const char *name; + const char *name; Jim_FreeInternalRepProc *freeIntRepProc; Jim_DupInternalRepProc *dupIntRepProc; Jim_UpdateStringProc *updateStringProc; int flags; } Jim_ObjType; -#define JIM_TYPE_NONE 0 -#define JIM_TYPE_REFERENCES 1 +#define JIM_TYPE_NONE 0 +#define JIM_TYPE_REFERENCES 1 typedef struct Jim_CallFrame { - unsigned long id; - int level; - struct Jim_HashTable vars; - struct Jim_HashTable *staticVars; - struct Jim_CallFrame *parent; - Jim_Obj *const *argv; - int argc; - Jim_Obj *procArgsObjPtr; - Jim_Obj *procBodyObjPtr; - struct Jim_CallFrame *next; - Jim_Obj *nsObj; - Jim_Obj *fileNameObj; + unsigned long id; + int level; + struct Jim_HashTable vars; + struct Jim_HashTable *staticVars; + struct Jim_CallFrame *parent; + Jim_Obj *const *argv; + int argc; + Jim_Obj *procArgsObjPtr; + Jim_Obj *procBodyObjPtr; + struct Jim_CallFrame *next; + Jim_Obj *nsObj; + Jim_Obj *fileNameObj; int line; - Jim_Stack *localCommands; - struct Jim_Obj *tailcallObj; - struct Jim_Cmd *tailcallCmd; + Jim_Stack *localCommands; + struct Jim_Obj *tailcallObj; + struct Jim_Cmd *tailcallCmd; } Jim_CallFrame; typedef struct Jim_Var { Jim_Obj *objPtr; struct Jim_CallFrame *linkFramePtr; @@ -497,35 +487,35 @@ typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData); typedef struct Jim_Cmd { - int inUse; - int isproc; - struct Jim_Cmd *prevCmd; + int inUse; + int isproc; + struct Jim_Cmd *prevCmd; union { struct { - - Jim_CmdProc *cmdProc; - Jim_DelCmdProc *delProc; - void *privData; + + Jim_CmdProc *cmdProc; + Jim_DelCmdProc *delProc; + void *privData; } native; struct { - + Jim_Obj *argListObjPtr; Jim_Obj *bodyObjPtr; - Jim_HashTable *staticVars; - int argListLen; - int reqArity; - int optArity; - int argsPos; - int upcall; + Jim_HashTable *staticVars; + int argListLen; + int reqArity; + int optArity; + int argsPos; + int upcall; struct Jim_ProcArg { - Jim_Obj *nameObjPtr; - Jim_Obj *defaultObjPtr; + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; } *arglist; - Jim_Obj *nsObj; + Jim_Obj *nsObj; } proc; } u; } Jim_Cmd; @@ -533,64 +523,64 @@ unsigned char sbox[256]; unsigned int i, j; } Jim_PrngState; typedef struct Jim_Interp { - Jim_Obj *result; - int errorLine; - Jim_Obj *errorFileNameObj; - int addStackTrace; - int maxCallFrameDepth; - int maxEvalDepth; - int evalDepth; - int returnCode; - int returnLevel; - int exitCode; - long id; - int signal_level; - jim_wide sigmask; - int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); - Jim_CallFrame *framePtr; - Jim_CallFrame *topFramePtr; - struct Jim_HashTable commands; + Jim_Obj *result; + int errorLine; + Jim_Obj *errorFileNameObj; + int addStackTrace; + int maxCallFrameDepth; + int maxEvalDepth; + int evalDepth; + int returnCode; + int returnLevel; + int exitCode; + long id; + int signal_level; + jim_wide sigmask; + int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); + Jim_CallFrame *framePtr; + Jim_CallFrame *topFramePtr; + struct Jim_HashTable commands; unsigned long procEpoch; /* Incremented every time the result of procedures names lookup caching may no longer be valid. */ unsigned long callFrameEpoch; /* Incremented every time a new callframe is created. This id is used for the 'ID' field contained in the Jim_CallFrame structure. */ - int local; - Jim_Obj *liveList; - Jim_Obj *freeList; - Jim_Obj *currentScriptObj; - Jim_Obj *nullScriptObj; - Jim_Obj *emptyObj; - Jim_Obj *trueObj; - Jim_Obj *falseObj; - unsigned long referenceNextId; - struct Jim_HashTable references; + int local; + Jim_Obj *liveList; + Jim_Obj *freeList; + Jim_Obj *currentScriptObj; + Jim_Obj *nullScriptObj; + Jim_Obj *emptyObj; + Jim_Obj *trueObj; + Jim_Obj *falseObj; + unsigned long referenceNextId; + struct Jim_HashTable references; unsigned long lastCollectId; /* reference max Id of the last GC - execution. It's set to ~0 while the collection + execution. It's set to -1 while the collection is running as sentinel to avoid to recursive calls via the [collect] command inside finalizers. */ - time_t lastCollectTime; - Jim_Obj *stackTrace; - Jim_Obj *errorProc; - Jim_Obj *unknown; - int unknown_called; - int errorFlag; + time_t lastCollectTime; + Jim_Obj *stackTrace; + Jim_Obj *errorProc; + Jim_Obj *unknown; + int unknown_called; + int errorFlag; void *cmdPrivData; /* Used to pass the private data pointer to a command. It is set to what the user specified via Jim_CreateCommand(). */ - struct Jim_CallFrame *freeFramesList; - struct Jim_HashTable assocData; - Jim_PrngState *prngState; - struct Jim_HashTable packages; - Jim_Stack *loadHandles; + struct Jim_CallFrame *freeFramesList; + struct Jim_HashTable assocData; + Jim_PrngState *prngState; + struct Jim_HashTable packages; + Jim_Stack *loadHandles; } Jim_Interp; #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++ #define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l)) #define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval)) @@ -633,11 +623,11 @@ 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, int unlink_file); +JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *template); JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); @@ -826,33 +816,25 @@ Jim_Obj *newObjPtr, int flags); JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len); JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr); - -#define JIM_DICTMATCH_KEYS 0x0001 -#define JIM_DICTMATCH_VALUES 0x002 - -JIM_EXPORT int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types); +JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj); +JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr); JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr); JIM_EXPORT int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr); -JIM_EXPORT Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv); JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr); JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp, - Jim_Obj *exprObjPtr); + Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr); JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr); - -JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, - int *booleanPtr); - JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr, jim_wide *widePtr); JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr, long *longPtr); @@ -870,12 +852,10 @@ JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg); JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr, const char * const *tablePtr, int *indexPtr, const char *name, int flags); -JIM_EXPORT int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, - const char *const *tablePtr); JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr); JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len); @@ -898,12 +878,11 @@ 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(Jim_Interp *interp, const char *prompt); -JIM_EXPORT void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *commandObj); +JIM_EXPORT char *Jim_HistoryGetline(const char *prompt); JIM_EXPORT void Jim_HistoryAdd(const char *line); JIM_EXPORT void Jim_HistoryShow(void); JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp); @@ -925,11 +904,11 @@ #ifdef __cplusplus } #endif -#endif +#endif #ifndef JIM_SUBCMD_H #define JIM_SUBCMD_H @@ -936,24 +915,24 @@ #ifdef __cplusplus extern "C" { #endif -#define JIM_MODFLAG_HIDDEN 0x0001 -#define JIM_MODFLAG_FULLARGV 0x0002 +#define JIM_MODFLAG_HIDDEN 0x0001 +#define JIM_MODFLAG_FULLARGV 0x0002 typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv); typedef struct { - const char *cmd; - const char *args; - jim_subcmd_function *function; - short minargs; - short maxargs; - unsigned short flags; + const char *cmd; + const char *args; + jim_subcmd_function *function; + short minargs; + short maxargs; + unsigned short flags; } jim_subcmd_type; const jim_subcmd_type * Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv); @@ -981,36 +960,36 @@ int rm_eo; } regmatch_t; typedef struct regexp { - - int re_nsub; - - - int cflags; - int err; - int regstart; - int reganch; - int regmust; - int regmlen; - int *program; - - - const char *regparse; - int p; - int proglen; - - - int eflags; - const char *start; - const char *reginput; - const char *regbol; - - - regmatch_t *pmatch; - int nmatch; + + int re_nsub; + + + int cflags; + int err; + int regstart; + int reganch; + int regmust; + int regmlen; + int *program; + + + const char *regparse; + int p; + int proglen; + + + int eflags; + const char *start; + const char *reginput; + const char *regbol; + + + regmatch_t *pmatch; + int nmatch; } regexp; typedef regexp regex_t; #define REG_EXTENDED 0 @@ -1018,13 +997,13 @@ #define REG_ICASE 2 #define REG_NOTBOL 16 enum { - REG_NOERROR, - REG_NOMATCH, - REG_BADPAT, + REG_NOERROR, + REG_NOMATCH, + REG_BADPAT, REG_ERR_NULL_ARGUMENT, REG_ERR_UNKNOWN, REG_ERR_TOO_BIG, REG_ERR_NOMEM, REG_ERR_TOO_MANY_PAREN, @@ -1049,101 +1028,24 @@ #ifdef __cplusplus } #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) { if (Jim_PackageProvide(interp, "bootstrap", "1.0", JIM_ERRMSG)) return JIM_ERR; return Jim_EvalSource(interp, "bootstrap.tcl", 1, "\n" "\n" -"proc package {cmd pkg args} {\n" +"proc package {cmd pkg} {\n" " if {$cmd eq \"require\"} {\n" " foreach path $::auto_path {\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" +" if {[file exists $path/$pkg.tcl]} {\n" +" uplevel #0 [list source $path/$pkg.tcl]\n" " return\n" " }\n" " }\n" " }\n" "}\n" @@ -1198,43 +1100,10 @@ "\n" "if {$tcl_platform(platform) eq \"windows\"} {\n" " set jim::argv0 [string map {\\\\ /} $jim::argv0]\n" "}\n" "\n" -"\n" -"set tcl::autocomplete_commands {info tcl::prefix socket namespace array clock file package string dict signal history}\n" -"\n" -"\n" -"\n" -"proc tcl::autocomplete {prefix} {\n" -" if {[set space [string first \" \" $prefix]] != -1} {\n" -" set cmd [string range $prefix 0 $space-1]\n" -" if {$cmd in $::tcl::autocomplete_commands || [info channel $cmd] ne \"\"} {\n" -" set arg [string range $prefix $space+1 end]\n" -"\n" -" return [lmap p [$cmd -commands] {\n" -" if {![string match \"${arg}*\" $p]} continue\n" -" function \"$cmd $p\"\n" -" }]\n" -" }\n" -" }\n" -"\n" -" if {[string match \"source *\" $prefix]} {\n" -" set path [string range $prefix 7 end]\n" -" return [lmap p [glob -nocomplain \"${path}*\"] {\n" -" function \"source $p\"\n" -" }]\n" -" }\n" -"\n" -" return [lmap p [lsort [info commands $prefix*]] {\n" -" if {[string match \"* *\" $p]} {\n" -" continue\n" -" }\n" -" function $p\n" -" }]\n" -"}\n" -"\n" "_jimsh_init\n" ); } int Jim_globInit(Jim_Interp *interp) { @@ -1446,17 +1315,10 @@ return JIM_ERR; 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" "}\n" "\n" @@ -1513,17 +1375,10 @@ " }\n" " join $lines \\n\n" "}\n" "\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" " set stacktrace [info stacktrace]\n" @@ -1547,10 +1402,31 @@ " if {[exists ::jim::exe]} {\n" " return $::jim::exe\n" " }\n" "}\n" "\n" +"\n" +"proc {dict with} {&dictVar {args key} script} {\n" +" set keys {}\n" +" foreach {n v} [dict get $dictVar {*}$key] {\n" +" upvar $n var_$n\n" +" set var_$n $v\n" +" lappend keys $n\n" +" }\n" +" catch {uplevel 1 $script} msg opts\n" +" if {[info exists dictVar] && ([llength $key] == 0 || [dict exists $dictVar {*}$key])} {\n" +" foreach n $keys {\n" +" if {[info exists var_$n]} {\n" +" dict set dictVar {*}$key $n [set var_$n]\n" +" } else {\n" +" dict unset dictVar {*}$key $n\n" +" }\n" +" }\n" +" }\n" +" return {*}$opts $msg\n" +"}\n" +"\n" "\n" "proc {dict update} {&varName args script} {\n" " set keys {}\n" " foreach {n v} $args {\n" " upvar $v var_$v\n" @@ -1569,10 +1445,23 @@ " }\n" " }\n" " return {*}$opts $msg\n" "}\n" "\n" +"\n" +"\n" +"proc {dict merge} {dict args} {\n" +" foreach d $args {\n" +"\n" +" dict size $d\n" +" foreach {k v} $d {\n" +" dict set dict $k $v\n" +" }\n" +" }\n" +" return $dict\n" +"}\n" +"\n" "proc {dict replace} {dictionary {args {key value}}} {\n" " if {[llength ${key value}] % 2} {\n" " tailcall {dict replace}\n" " }\n" " tailcall dict merge $dictionary ${key value}\n" @@ -1614,10 +1503,15 @@ " dict unset dictionary $k\n" " }\n" " return $dictionary\n" "}\n" "\n" +"\n" +"proc {dict values} {dictionary {pattern *}} {\n" +" dict keys [lreverse $dictionary] $pattern\n" +"}\n" +"\n" "\n" "proc {dict for} {vars dictionary script} {\n" " if {[llength $vars] != 2} {\n" " return -code error \"must have exactly two variable names\"\n" " }\n" @@ -1696,10 +1590,11 @@ "proc fileevent {args} {\n" " tailcall {*}$args\n" "}\n" "\n" "\n" +"\n" "\n" "proc parray {arrayname {pattern *} {puts puts}} {\n" " upvar $arrayname a\n" "\n" " set max 0\n" @@ -1752,11 +1647,11 @@ "}\n" "\n" "\n" "\n" "proc popen {cmd {mode r}} {\n" -" lassign [pipe] r w\n" +" lassign [socket pipe] r w\n" " try {\n" " if {[string match \"w*\" $mode]} {\n" " lappend cmd <@$r &\n" " set pids [exec {*}$cmd]\n" " $r close\n" @@ -1769,30 +1664,15 @@ " }\n" " lambda {cmd args} {f pids} {\n" " 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" -" 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" +" foreach p $pids { os.wait $p }\n" +" return\n" " }\n" " tailcall $f $cmd {*}$args\n" " }\n" " } on error {error opts} {\n" " $r close\n" @@ -1812,10 +1692,14 @@ " if {[catch {$channelId pid} pids]} {\n" " return \"\"\n" " }\n" " return $pids\n" "}\n" +"\n" +"\n" +"\n" +"\n" "\n" "\n" "\n" "\n" "\n" @@ -1896,13 +1780,10 @@ "}\n" ); } -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #include #include #include #include #ifdef HAVE_UNISTD_H @@ -1912,34 +1793,27 @@ #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 #if defined(JIM_SSL) #include #include #endif -#ifdef HAVE_TERMIOS_H -#endif - -#define AIO_CMD_LEN 32 -#define AIO_BUF_LEN 256 +#define AIO_CMD_LEN 32 +#define AIO_BUF_LEN 256 #ifndef HAVE_FTELLO #define ftello ftell #endif #ifndef HAVE_FSEEKO @@ -1955,15 +1829,11 @@ #ifndef PF_INET6 #define PF_INET6 0 #endif #endif -#ifdef JIM_ANSIC - -#undef HAVE_PIPE -#undef HAVE_SOCKETPAIR -#endif +#define JimCheckStreamError(interp, af) af->fops->error(af) struct AioFile; typedef struct { @@ -1978,11 +1848,11 @@ typedef struct AioFile { FILE *fp; Jim_Obj *filename; int type; - int openFlags; + int openFlags; int fd; Jim_Obj *rEvent; Jim_Obj *wEvent; Jim_Obj *eEvent; int addr_family; @@ -2009,21 +1879,21 @@ { if (!ferror(af->fp)) { return JIM_OK; } clearerr(af->fp); - + if (feof(af->fp) || errno == EAGAIN || errno == EINTR) { return JIM_OK; } #ifdef ECONNRESET if (errno == ECONNRESET) { return JIM_OK; } #endif #ifdef ECONNABORTED - if (errno == ECONNABORTED) { + if (errno != ECONNABORTED) { return JIM_OK; } #endif return JIM_ERR; } @@ -2066,37 +1936,29 @@ else { Jim_SetResultString(interp, JimAioErrorString(af), -1); } } -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; JIM_NOTUSED(interp); Jim_DecrRefCount(interp, af->filename); #ifdef jim_ext_eventloop - - Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION); + + Jim_DeleteFileHandler(interp, af->fp, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION); #endif #if defined(JIM_SSL) if (af->ssl != NULL) { SSL_free(af->ssl); } #endif + if (!(af->openFlags & AIO_KEEPOPEN)) { fclose(af->fp); } Jim_Free(af); @@ -2106,11 +1968,11 @@ { AioFile *af = Jim_CmdPrivData(interp); char buf[AIO_BUF_LEN]; Jim_Obj *objPtr; int nonewline = 0; - jim_wide neededLen = -1; + jim_wide neededLen = -1; if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { nonewline = 1; argv++; argc--; @@ -2145,11 +2007,11 @@ } } if (retval != readlen) break; } - + if (JimCheckStreamError(interp, af)) { Jim_FreeNewObj(interp, objPtr); return JIM_ERR; } if (nonewline) { @@ -2167,11 +2029,11 @@ AioFile *Jim_AioFile(Jim_Interp *interp, Jim_Obj *command) { Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); - + if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { return (AioFile *) cmdPtr->u.native.privData; } Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command); return NULL; @@ -2187,20 +2049,10 @@ } 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); jim_wide count = 0; jim_wide maxlen = JIM_WIDE_MAX; @@ -2258,21 +2110,21 @@ } else { len = strlen(buf); if (len && (buf[len - 1] == '\n')) { - + len--; } Jim_AppendString(interp, objPtr, buf, len); break; } } if (JimCheckStreamError(interp, af)) { - + Jim_FreeNewObj(interp, objPtr); return JIM_ERR; } if (argc) { @@ -2282,11 +2134,11 @@ } len = Jim_Length(objPtr); if (len == 0 && feof(af->fp)) { - + len = -1; } Jim_SetResultInt(interp, len); } else { @@ -2355,11 +2207,11 @@ } static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc == 3) { -#if defined(HAVE_SOCKETS) && defined(HAVE_SHUTDOWN) +#if !defined(JIM_ANSIC) && defined(HAVE_SHUTDOWN) static const char * const options[] = { "r", "w", NULL }; enum { OPT_R, OPT_W, }; int option; AioFile *af = Jim_CmdPrivData(interp); @@ -2446,11 +2298,10 @@ Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0); return JIM_OK; } #endif - #ifdef HAVE_FSYNC static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); @@ -2513,33 +2364,33 @@ static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, Jim_Obj **scriptHandlerObj, int argc, Jim_Obj * const *argv) { if (argc == 0) { - + if (*scriptHandlerObj) { Jim_SetResult(interp, *scriptHandlerObj); } return JIM_OK; } if (*scriptHandlerObj) { - - Jim_DeleteFileHandler(interp, af->fd, mask); + + Jim_DeleteFileHandler(interp, af->fp, mask); } - + if (Jim_Length(argv[0]) == 0) { - + return JIM_OK; } - + Jim_IncrRefCount(argv[0]); *scriptHandlerObj = argv[0]; - Jim_CreateFileHandler(interp, af->fd, mask, + Jim_CreateFileHandler(interp, af->fp, mask, JimAioFileEventHandler, scriptHandlerObj, JimAioFileEventFinalizer); return JIM_OK; } @@ -2564,144 +2415,135 @@ return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, &af->eEvent, argc, argv); } #endif - - static const jim_subcmd_type aio_command_table[] = { { "read", "?-nonewline? ?len?", aio_cmd_read, 0, 2, - + }, { "copyto", "handle ?size?", aio_cmd_copy, 1, 2, - - }, - { "getfd", - NULL, - aio_cmd_getfd, - 0, - 0, - + }, { "gets", "?var?", aio_cmd_gets, 0, 1, - + }, { "puts", "?-nonewline? str", aio_cmd_puts, 1, 2, - + }, { "isatty", NULL, aio_cmd_isatty, 0, 0, - + }, { "flush", NULL, aio_cmd_flush, 0, 0, - + }, { "eof", NULL, aio_cmd_eof, 0, 0, - + }, { "close", "?r(ead)|w(rite)?", aio_cmd_close, 0, 1, JIM_MODFLAG_FULLARGV, - + }, { "seek", "offset ?start|current|end", aio_cmd_seek, 1, 2, - + }, { "tell", NULL, aio_cmd_tell, 0, 0, - + }, { "filename", NULL, aio_cmd_filename, 0, 0, - + }, #ifdef O_NDELAY { "ndelay", "?0|1?", aio_cmd_ndelay, 0, 1, - + }, #endif #ifdef HAVE_FSYNC { "sync", NULL, aio_cmd_sync, 0, 0, - + }, #endif { "buffering", "none|line|full", aio_cmd_buffering, 1, 1, - + }, #ifdef jim_ext_eventloop { "readable", "?readable-script?", aio_cmd_readable, 0, 1, - + }, { "writable", "?writable-script?", aio_cmd_writable, 0, 1, - + }, { "onexception", "?exception-script?", aio_cmd_onexception, 0, 1, - + }, #endif { NULL } }; @@ -2724,11 +2566,11 @@ #ifdef jim_ext_tclcompat { const char *filename = Jim_String(argv[1]); - + if (*filename == '|') { Jim_Obj *evalObj[3]; evalObj[0] = Jim_NewStringObj(interp, "::popen", -1); evalObj[1] = Jim_NewStringObj(interp, filename + 1, -1); @@ -2761,44 +2603,42 @@ } 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); -#ifndef JIM_ANSIC +#if !defined(JIM_ANSIC) if (fd >= 0) { close(fd); } #endif Jim_DecrRefCount(interp, filename); return NULL; } } - + af = Jim_Alloc(sizeof(*af)); memset(af, 0, sizeof(*af)); af->fp = fh; - af->filename = filename; - af->openFlags = openFlags; -#ifndef JIM_ANSIC af->fd = fileno(fh); + af->filename = filename; #ifdef FD_CLOEXEC if ((openFlags & AIO_KEEPOPEN) == 0) { (void)fcntl(af->fd, F_SETFD, FD_CLOEXEC); } #endif -#endif + af->openFlags = openFlags; af->addr_family = family; af->fops = &stdio_fops; af->ssl = NULL; Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); @@ -2813,45 +2653,72 @@ const char *hdlfmt, int family, const char *mode[2]) { 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); return JIM_OK; } } - + close(p[0]); close(p[1]); JimAioSetError(interp, NULL); return JIM_ERR; } #endif -#ifdef HAVE_PIPE -static int JimAioPipeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - int p[2]; - static const char *mode[2] = { "r", "w" }; - - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - - if (pipe(p) != 0) { - JimAioSetError(interp, NULL); - return JIM_ERR; - } - - return JimMakeChannelPair(interp, p, argv[0], "aio.pipe%ld", 0, mode); -} -#endif - + +int Jim_MakeTempFile(Jim_Interp *interp, const char *template) +{ +#ifdef HAVE_MKSTEMP + int fd; + mode_t mask; + Jim_Obj *filenameObj; + + if (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, template, -1); + } + +#if defined(S_IRWXG) && defined(S_IRWXO) + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); +#else + + mask = umask(S_IXUSR); +#endif + + + fd = mkstemp(filenameObj->bytes); + umask(mask); + if (fd < 0) { + JimAioSetError(interp, filenameObj); + Jim_FreeNewObj(interp, filenameObj); + return -1; + } + + Jim_SetResult(interp, filenameObj); + return fd; +#else + Jim_SetResultString(interp, "platform has no tempfile support", -1); + return -1; +#endif +} int Jim_aioInit(Jim_Interp *interp) { if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG)) @@ -2860,18 +2727,15 @@ #if defined(JIM_SSL) Jim_CreateCommand(interp, "load_ssl_certs", JimAioLoadSSLCertsCommand, NULL, NULL); #endif Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); -#ifdef HAVE_SOCKETS +#ifndef JIM_ANSIC 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"); JimMakeChannel(interp, stdout, -1, NULL, "stdout", 0, "w"); JimMakeChannel(interp, stderr, -1, NULL, "stderr", 0, "w"); return JIM_OK; @@ -2949,12 +2813,12 @@ #include #endif static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) { - regfree(objPtr->internalRep.ptrIntValue.ptr); - Jim_Free(objPtr->internalRep.ptrIntValue.ptr); + regfree(objPtr->internalRep.regexpValue.compre); + Jim_Free(objPtr->internalRep.regexpValue.compre); } static const Jim_ObjType regexpObjType = { "regexp", FreeRegexpInternalRep, @@ -2967,20 +2831,20 @@ { regex_t *compre; const char *pattern; int ret; - + if (objPtr->typePtr == ®expObjType && - objPtr->internalRep.ptrIntValue.ptr && objPtr->internalRep.ptrIntValue.int1 == flags) { - - return objPtr->internalRep.ptrIntValue.ptr; + objPtr->internalRep.regexpValue.compre && objPtr->internalRep.regexpValue.flags == flags) { + + return objPtr->internalRep.regexpValue.compre; } + - - + pattern = Jim_String(objPtr); compre = Jim_Alloc(sizeof(regex_t)); if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) { char buf[100]; @@ -2993,12 +2857,12 @@ } Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = ®expObjType; - objPtr->internalRep.ptrIntValue.int1 = flags; - objPtr->internalRep.ptrIntValue.ptr = compre; + objPtr->internalRep.regexpValue.flags = flags; + objPtr->internalRep.regexpValue.compre = compre; return compre; } int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -3137,11 +3001,11 @@ } num_matches++; if (opt_all && !opt_inline) { - + goto try_next_match; } j = 0; @@ -3177,11 +3041,11 @@ if (opt_inline) { Jim_ListAppendElement(interp, resultListObj, resultObj); } else { - + result = Jim_SetVariable(interp, argv[i], resultObj); if (result != JIM_OK) { Jim_FreeObj(interp, resultObj); break; @@ -3304,11 +3168,11 @@ source_str = Jim_GetString(argv[i + 1], &source_len); replace_str = Jim_GetString(argv[i + 2], &replace_len); varname = argv[i + 3]; - + resultObj = Jim_NewStringObj(interp, "", 0); if (offset) { if (offset < 0) { offset += source_len + 1; @@ -3319,11 +3183,11 @@ else if (offset < 0) { offset = 0; } } - + Jim_AppendString(interp, resultObj, source_str, offset); n = source_len - offset; p = source_str + offset; @@ -3378,23 +3242,23 @@ } p += pmatch[0].rm_eo; n -= pmatch[0].rm_eo; - + if (!opt_all || n == 0) { break; } - + if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') { break; } - + if (pattern[0] == '\0' && n) { - + Jim_AppendString(interp, resultObj, p, 1); p++; n--; } @@ -3401,11 +3265,11 @@ regexec_flags |= REG_NOTBOL; } while (n); Jim_AppendString(interp, resultObj, p, -1); - + if (argc - i == 4) { result = Jim_SetVariable(interp, varname, resultObj); if (result == JIM_OK) { Jim_SetResultInt(interp, num_matches); @@ -3456,23 +3320,16 @@ # ifndef MAXPATHLEN # define MAXPATHLEN JIM_PATH_LEN # endif -#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER) +#if defined(__MINGW32__) || 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)) { return "file"; @@ -3514,11 +3371,11 @@ Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value)); } static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb) { - + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); AppendStatElement(interp, listObj, "dev", sb->st_dev); AppendStatElement(interp, listObj, "ino", sb->st_ino); AppendStatElement(interp, listObj, "mode", sb->st_mode); @@ -3527,44 +3384,39 @@ AppendStatElement(interp, listObj, "gid", sb->st_gid); AppendStatElement(interp, listObj, "size", sb->st_size); 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)); - + if (varName) { - Jim_Obj *objPtr; - objPtr = Jim_GetVariable(interp, varName, JIM_NONE); - + Jim_Obj *objPtr = Jim_GetVariable(interp, varName, JIM_NONE); if (objPtr) { - Jim_Obj *objv[2]; - - objv[0] = objPtr; - objv[1] = listObj; - - objPtr = Jim_DictMerge(interp, 2, objv); - if (objPtr == NULL) { - + if (Jim_DictSize(interp, objPtr) < 0) { + Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); Jim_FreeNewObj(interp, listObj); return JIM_ERR; } + if (Jim_IsShared(objPtr)) + objPtr = Jim_DuplicateObj(interp, objPtr); + + + Jim_ListAppendList(interp, objPtr, listObj); + Jim_DictSize(interp, objPtr); Jim_InvalidateStringRep(objPtr); Jim_FreeNewObj(interp, listObj); listObj = objPtr; } Jim_SetVariable(interp, varName, listObj); } - + Jim_SetResult(interp, listObj); return JIM_OK; } @@ -3580,11 +3432,11 @@ } else if (p == path) { Jim_SetResultString(interp, "/", -1); } else if (ISWINDOWS && p[-1] == ':') { - + Jim_SetResultString(interp, path, p - path + 1); } else { Jim_SetResultString(interp, path, p - path); } @@ -3660,35 +3512,35 @@ char *newname = Jim_Alloc(MAXPATHLEN + 1); char *last = newname; *newname = 0; - + for (i = 0; i < argc; i++) { int len; const char *part = Jim_GetString(argv[i], &len); if (*part == '/') { - + last = newname; } else if (ISWINDOWS && strchr(part, ':')) { - + last = newname; } else if (part[0] == '.') { if (part[1] == '/') { part += 2; len -= 2; } else if (part[1] == 0 && last != newname) { - + continue; } } - + if (last != newname && last[-1] != '/') { *last++ = '/'; } if (len) { @@ -3699,22 +3551,22 @@ } memcpy(last, part, len); last += len; } - + if (last > newname + 1 && last[-1] == '/') { - + if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { *--last = 0; } } } *last = 0; - + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); return JIM_OK; } @@ -3739,11 +3591,11 @@ static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { #ifdef X_OK return file_access(interp, argv[0], X_OK); #else - + Jim_SetResultBool(interp, 1); return JIM_OK; #endif } @@ -3764,11 +3616,11 @@ while (argc--) { const char *path = Jim_String(argv[0]); if (unlink(path) == -1 && errno != ENOENT) { if (rmdir(path) == -1) { - + if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path, strerror(errno)); return JIM_ERR; } @@ -3787,15 +3639,15 @@ static int mkdir_all(char *path) { int ok = 1; - + goto first; while (ok--) { - + { char *slash = strrchr(path, '/'); if (slash && slash != path) { *slash = 0; @@ -3808,24 +3660,24 @@ first: if (MKDIR_DEFAULT(path) == 0) { return 0; } if (errno == ENOENT) { - + continue; } - + if (errno == EEXIST) { struct stat sb; if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { return 0; } - + errno = EEXIST; } - + break; } return -1; } @@ -3846,11 +3698,11 @@ return JIM_OK; } 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, 0); + int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL); if (fd < 0) { return JIM_ERR; } close(fd); @@ -3964,67 +3816,42 @@ } Jim_SetResultInt(interp, sb.st_atime); 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) { - jim_wide secs; - if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) { +#ifdef HAVE_UTIMES + jim_wide newtime; + struct timeval times[2]; + + if (Jim_GetWide(interp, argv[1], &newtime) != JIM_OK) { + return JIM_ERR; + } + + times[1].tv_sec = times[0].tv_sec = newtime; + times[1].tv_usec = times[0].tv_usec = 0; + + if (utimes(Jim_String(argv[0]), times) != 0) { + Jim_SetResultFormatted(interp, "can't set time on \"%#s\": %s", argv[0], strerror(errno)); return JIM_ERR; } - return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000); +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif } if (file_stat(interp, argv[0], &sb) != JIM_OK) { return JIM_ERR; } Jim_SetResultInt(interp, sb.st_mtime); return JIM_OK; } -#ifdef STAT_MTIME_US -static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - struct stat sb; - - if (argc == 2) { - jim_wide us; - if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) { - return JIM_ERR; - } - return JimSetFileTimes(interp, Jim_String(argv[0]), us); - } - if (file_stat(interp, argv[0], &sb) != JIM_OK) { - return JIM_ERR; - } - 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) { return Jim_EvalPrefix(interp, "file copy", argc, argv); } @@ -4135,201 +3962,192 @@ { "atime", "name", file_cmd_atime, 1, 1, - + }, { "mtime", "name ?time?", file_cmd_mtime, 1, 2, - - }, -#ifdef STAT_MTIME_US - { "mtimeus", - "name ?time?", - file_cmd_mtimeus, - 1, - 2, - - }, -#endif + + }, { "copy", "?-force? source dest", file_cmd_copy, 2, 3, - + }, { "dirname", "name", file_cmd_dirname, 1, 1, - + }, { "rootname", "name", file_cmd_rootname, 1, 1, - + }, { "extension", "name", file_cmd_extension, 1, 1, - + }, { "tail", "name", file_cmd_tail, 1, 1, - + }, { "normalize", "name", file_cmd_normalize, 1, 1, - + }, { "join", "name ?name ...?", file_cmd_join, 1, -1, - + }, { "readable", "name", file_cmd_readable, 1, 1, - + }, { "writable", "name", file_cmd_writable, 1, 1, - + }, { "executable", "name", file_cmd_executable, 1, 1, - + }, { "exists", "name", file_cmd_exists, 1, 1, - + }, { "delete", "?-force|--? name ...", file_cmd_delete, 1, -1, - + }, { "mkdir", "dir ...", file_cmd_mkdir, 1, -1, - + }, { "tempfile", "?template?", file_cmd_tempfile, 0, 1, - + }, { "rename", "?-force? source dest", file_cmd_rename, 2, 3, - + }, #if defined(HAVE_LINK) && defined(HAVE_SYMLINK) { "link", "?-symbolic|-hard? newname target", file_cmd_link, 2, 3, - + }, #endif #if defined(HAVE_READLINK) { "readlink", "name", file_cmd_readlink, 1, 1, - + }, #endif { "size", "name", file_cmd_size, 1, 1, - + }, { "stat", "name ?var?", file_cmd_stat, 1, 2, - + }, { "lstat", "name ?var?", file_cmd_lstat, 1, 2, - + }, { "type", "name", file_cmd_type, 1, 1, - + }, #ifdef HAVE_GETEUID { "owned", "name", file_cmd_owned, 1, 1, - + }, #endif { "isdirectory", "name", file_cmd_isdirectory, 1, 1, - + }, { "isfile", "name", file_cmd_isfile, 1, 1, - + }, { NULL } }; @@ -4361,11 +4179,11 @@ Jim_SetResultString(interp, "Failed to get pwd", -1); Jim_Free(cwd); return JIM_ERR; } else if (ISWINDOWS) { - + char *p = cwd; while ((p = strchr(p, '\\')) != NULL) { *p++ = '/'; } } @@ -4385,13 +4203,10 @@ Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL); Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL); return JIM_OK; } -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #include #include #if (!defined(HAVE_VFORK) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__) @@ -4399,20 +4214,20 @@ { Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp); int i, j; int rc; - + for (i = 1; i < argc; i++) { int len; const char *arg = Jim_GetString(argv[i], &len); if (i > 1) { Jim_AppendString(interp, cmdlineObj, " ", 1); } if (strpbrk(arg, "\\\" ") == NULL) { - + Jim_AppendString(interp, cmdlineObj, arg, len); continue; } Jim_AppendString(interp, cmdlineObj, "\"", 1); @@ -4451,26 +4266,86 @@ #else #include #include -#include -struct WaitInfoTable; +#if defined(__MINGW32__) + + #ifndef STRICT + #define STRICT + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include -static char **JimOriginalEnviron(void); + 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 + +static const char *JimStrError(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, int *inPipePtr, int *outPipePtr, int *errFilePtr); -static void JimDetachPids(struct WaitInfoTable *table, int numPids, const pidtype *pidPtr); + pidtype **pidArrayPtr, fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr); +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr); static int JimCleanupChildren(Jim_Interp *interp, int numPids, pidtype *pidPtr, Jim_Obj *errStrObj); -static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static fdtype JimCreateTemp(Jim_Interp *interp, const char *contents, int len); +static fdtype JimOpenForWrite(const char *filename, int append); +static int JimRewindFd(fdtype fd); -#if defined(__MINGW32__) -static pidtype JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId); -#endif +static void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) +{ + Jim_SetResultFormatted(interp, "%s: %s", msg, JimStrError()); +} + +static const char *JimStrError(void) +{ + return strerror(JimErrno()); +} static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) { int len; const char *s = Jim_GetString(objPtr, &len); @@ -4479,14 +4354,14 @@ objPtr->length--; objPtr->bytes[objPtr->length] = '\0'; } } -static int JimAppendStreamToString(Jim_Interp *interp, int fd, Jim_Obj *strObj) +static int JimAppendStreamToString(Jim_Interp *interp, fdtype fd, Jim_Obj *strObj) { char buf[256]; - FILE *fh = fdopen(fd, "r"); + FILE *fh = JimFdOpenForRead(fd); int ret = 0; if (fh == NULL) { return -1; } @@ -4515,18 +4390,18 @@ char *envdata; Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE); if (!objPtr) { - return JimOriginalEnviron(); + return Jim_GetEnviron(); } - + num = Jim_ListLength(interp, objPtr); if (num % 2) { - + num--; } size = Jim_Length(objPtr) + 2; envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size); @@ -4558,76 +4433,79 @@ if (env != original_environ) { Jim_Free(env); } } -static Jim_Obj *JimMakeErrorCode(Jim_Interp *interp, pidtype pid, int waitStatus, Jim_Obj *errStrObj) -{ - Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); - - 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)); - } - else if (WIFEXITED(waitStatus)) { +#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) +{ + Jim_Obj *errorCode; + + if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) { + return JIM_OK; + } + errorCode = Jim_NewListObj(interp, NULL, 0); + + 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))); } 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)); if (errStrObj) { Jim_AppendStrings(interp, errStrObj, "child ", action, " by signal ", Jim_SignalId(WTERMSIG(waitStatus)), "\n", NULL); } Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid)); - 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", JimMakeErrorCode(interp, pid, waitStatus, errStrObj)); + 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_SetGlobalVariableStr(interp, "errorCode", errorCode); return JIM_ERR; } struct WaitInfo { - pidtype pid; - int status; - int flags; + pidtype pid; + int status; + int flags; }; - struct WaitInfoTable { - struct WaitInfo *info; - int size; - int used; - int refcount; + struct WaitInfo *info; + int size; + int used; }; #define WI_DETACHED 2 @@ -4635,53 +4513,32 @@ static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData) { struct WaitInfoTable *table = privData; - if (--table->refcount == 0) { - Jim_Free(table->info); - Jim_Free(table); - } + Jim_Free(table->info); + Jim_Free(table); } 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 JimWaitRemove(struct WaitInfoTable *table, pidtype pid) -{ - int i; - - - 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; + fdtype outputId; + fdtype 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; @@ -4688,17 +4545,17 @@ argc--; numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); if (numPids < 0) { return JIM_ERR; } - + listObj = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < numPids; i++) { Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, (long)pidPtr[i])); } Jim_SetResult(interp, listObj); - JimDetachPids(table, numPids, pidPtr); + JimDetachPids(interp, numPids, pidPtr); Jim_Free(pidPtr); return JIM_OK; } numPids = @@ -4710,99 +4567,55 @@ result = JIM_OK; errStrObj = Jim_NewStringObj(interp, "", 0); - - if (outputId != -1) { + + if (outputId != JIM_BAD_FD) { if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) { result = JIM_ERR; Jim_SetResultErrno(interp, "error reading from output pipe"); } } - + childErrObj = Jim_NewStringObj(interp, "", 0); Jim_IncrRefCount(childErrObj); if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) { result = JIM_ERR; } - if (errorId != -1) { + if (errorId != JIM_BAD_FD) { int ret; - lseek(errorId, 0, SEEK_SET); + JimRewindFd(errorId); ret = JimAppendStreamToString(interp, errorId, errStrObj); if (ret < 0) { Jim_SetResultErrno(interp, "error reading from error pipe"); result = JIM_ERR; } else if (ret > 0) { - + child_siginfo = 0; } } if (child_siginfo) { - + Jim_AppendObj(interp, errStrObj, childErrObj); } Jim_DecrRefCount(interp, childErrObj); - + Jim_RemoveTrailingNewline(errStrObj); - + Jim_SetResult(interp, errStrObj); return result; } -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; int count; int dest; @@ -4814,13 +4627,13 @@ waitPtr = table->info; dest = 0; for (count = table->used; count > 0; waitPtr++, count--) { if (waitPtr->flags & WI_DETACHED) { int status; - pidtype pid = waitpid(waitPtr->pid, &status, WNOHANG); + pidtype pid = JimWaitPid(waitPtr->pid, &status, WNOHANG); if (pid == waitPtr->pid) { - + table->used--; continue; } } if (waitPtr != &table->info[dest]) { @@ -4828,62 +4641,66 @@ } dest++; } } -static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +static pidtype JimWaitForProcess(struct WaitInfoTable *table, pidtype pid, int *statusPtr) { + int i; + + + for (i = 0; i < table->used; i++) { + if (pid == table->info[i].pid) { + + JimWaitPid(pid, statusPtr, 0); + + + if (i != table->used - 1) { + table->info[i] = table->info[table->used - 1]; + } + table->used--; + return pid; + } + } + + + return JIM_BAD_PID; +} + +static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr) +{ + int j; struct WaitInfoTable *table = Jim_CmdPrivData(interp); - int nohang = 0; - pidtype pid; - long pidarg; - int status; - Jim_Obj *errCodeObj; - - - 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; - } - - pid = waitpid((pidtype)pidarg, &status, nohang ? WNOHANG : 0); - - errCodeObj = JimMakeErrorCode(interp, pid, status, NULL); - - if (pid != JIM_BAD_PID && (WIFEXITED(status) || WIFSIGNALED(status))) { - - JimWaitRemove(table, pid); - } - Jim_SetResult(interp, errCodeObj); - return JIM_OK; -} - -static int Jim_PidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - - Jim_SetResultInt(interp, (jim_wide)getpid()); - return JIM_OK; + + 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 FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name) +{ + FILE *fh; + Jim_Obj *fhObj; + + fhObj = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(fhObj); + fh = Jim_AioFilehandle(interp, fhObj); + Jim_DecrRefCount(interp, fhObj); + + return fh; } static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr, - int *inPipePtr, int *outPipePtr, int *errFilePtr) + fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr) { pidtype *pidPtr = NULL; /* Points to malloc-ed array holding all * the pids of child processes. */ int numPids = 0; /* Actual number of processes that exist * at *pidPtr right now. */ @@ -4890,16 +4707,16 @@ int cmdCount; /* Count of number of distinct commands * found in argc/argv. */ const char *input = NULL; /* Describes input for pipeline, depending * on "inputFile". NULL means take input * from stdin/pipe. */ - int input_len = 0; + int input_len = 0; -#define FILE_NAME 0 -#define FILE_APPEND 1 -#define FILE_HANDLE 2 -#define FILE_TEXT 3 +#define FILE_NAME 0 +#define FILE_APPEND 1 +#define FILE_HANDLE 2 +#define FILE_TEXT 3 int inputFile = FILE_NAME; /* 1 means input is name of input file. * 2 means input is filehandle name. * 0 means input holds actual * text to be input to command. */ @@ -4916,40 +4733,39 @@ */ const char *output = NULL; /* Holds name of output file to pipe to, * 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. */ - int inputId = -1; - int outputId = -1; - int errorId = -1; - int lastOutputId = -1; - int pipeIds[2]; + fdtype inputId = JIM_BAD_FD; + fdtype outputId = JIM_BAD_FD; + fdtype errorId = JIM_BAD_FD; + fdtype lastOutputId = JIM_BAD_FD; + fdtype 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 = -1; + *inPipePtr = JIM_BAD_FD; } if (outPipePtr != NULL) { - *outPipePtr = -1; + *outPipePtr = JIM_BAD_FD; } if (errFilePtr != NULL) { - *errFilePtr = -1; + *errFilePtr = JIM_BAD_FD; } - pipeIds[0] = pipeIds[1] = -1; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; cmdCount = 1; lastBar = -1; for (i = 0; i < argc; i++) { const char *arg = Jim_String(argv[i]); @@ -4980,11 +4796,11 @@ if (*output == '>') { outputFile = FILE_APPEND; output++; } if (*output == '&') { - + output++; dup_error = 1; } if (*output == '@') { outputFile = FILE_HANDLE; @@ -5021,11 +4837,11 @@ goto badargs; } lastBar = i; cmdCount++; } - + arg_array[arg_count++] = (char *)arg; continue; } if (i >= argc) { @@ -5039,227 +4855,183 @@ badargs: Jim_Free(arg_array); return -1; } - + save_environ = JimSaveEnv(JimBuildEnv(interp)); if (input != NULL) { if (inputFile == FILE_TEXT) { - inputId = Jim_MakeTempFile(interp, NULL, 1); - if (inputId == -1) { + inputId = JimCreateTemp(interp, input, input_len); + if (inputId == JIM_BAD_FD) { 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 (fd < 0) { + if (fh == NULL) { goto error; } - inputId = dup(fd); + inputId = JimDupFd(JimFileno(fh)); } else { - inputId = Jim_OpenForRead(input); - if (inputId == -1) { - Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, strerror(Jim_Errno())); + inputId = JimOpenForRead(input); + if (inputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, JimStrError()); goto error; } } } else if (inPipePtr != NULL) { - if (pipe(pipeIds) != 0) { + if (JimPipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create input pipe for command"); goto error; } inputId = pipeIds[0]; *inPipePtr = pipeIds[1]; - pipeIds[0] = pipeIds[1] = -1; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; } if (output != NULL) { if (outputFile == FILE_HANDLE) { - int fd = JimGetChannelFd(interp, output); - if (fd < 0) { + FILE *fh = JimGetAioFilehandle(interp, output); + if (fh == NULL) { goto error; } - lastOutputId = dup(fd); + fflush(fh); + lastOutputId = JimDupFd(JimFileno(fh)); } else { - lastOutputId = Jim_OpenForWrite(output, outputFile == FILE_APPEND); - if (lastOutputId == -1) { - Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, strerror(Jim_Errno())); + lastOutputId = JimOpenForWrite(output, outputFile == FILE_APPEND); + if (lastOutputId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, JimStrError()); goto error; } } } else if (outPipePtr != NULL) { - if (pipe(pipeIds) != 0) { + if (JimPipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create output pipe"); goto error; } lastOutputId = pipeIds[1]; *outPipePtr = pipeIds[0]; - pipeIds[0] = pipeIds[1] = -1; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; } - + if (error != NULL) { if (errorFile == FILE_HANDLE) { if (strcmp(error, "1") == 0) { - - if (lastOutputId != -1) { - errorId = dup(lastOutputId); + + if (lastOutputId != JIM_BAD_FD) { + errorId = JimDupFd(lastOutputId); } else { - + error = "stdout"; } } - if (errorId == -1) { - int fd = JimGetChannelFd(interp, error); - if (fd < 0) { + if (errorId == JIM_BAD_FD) { + FILE *fh = JimGetAioFilehandle(interp, error); + if (fh == NULL) { goto error; } - errorId = dup(fd); + fflush(fh); + errorId = JimDupFd(JimFileno(fh)); } } else { - errorId = Jim_OpenForWrite(error, errorFile == FILE_APPEND); - if (errorId == -1) { - Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, strerror(Jim_Errno())); + errorId = JimOpenForWrite(error, errorFile == FILE_APPEND); + if (errorId == JIM_BAD_FD) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, JimStrError()); goto error; } } } else if (errFilePtr != NULL) { - errorId = Jim_MakeTempFile(interp, NULL, 1); - if (errorId == -1) { + errorId = JimCreateTemp(interp, NULL, 0); + if (errorId == JIM_BAD_FD) { goto error; } - *errFilePtr = dup(errorId); + *errFilePtr = JimDupFd(errorId); } pidPtr = Jim_Alloc(cmdCount * sizeof(*pidPtr)); for (i = 0; i < numPids; i++) { pidPtr[i] = JIM_BAD_PID; } for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) { int pipe_dup_err = 0; - int origErrorId = errorId; + fdtype origErrorId = errorId; for (lastArg = firstArg; lastArg < arg_count; lastArg++) { - if (strcmp(arg_array[lastArg], "|") == 0) { - break; - } - if (strcmp(arg_array[lastArg], "|&") == 0) { - pipe_dup_err = 1; + if (arg_array[lastArg][0] == '|') { + if (arg_array[lastArg][1] == '&') { + 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 (pipe(pipeIds) != 0) { + if (JimPipe(pipeIds) != 0) { Jim_SetResultErrno(interp, "couldn't create pipe"); goto error; } outputId = pipeIds[1]; } - + if (pipe_dup_err) { errorId = outputId; } - + #ifdef __MINGW32__ - pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ, inputId, outputId, errorId); + pid = JimStartWinProcess(interp, &arg_array[firstArg], save_environ ? save_environ[0] : NULL, inputId, outputId, errorId); if (pid == JIM_BAD_PID) { Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]); 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"); goto error; } if (pid == 0) { - - - 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); - } - - if (outPipePtr) { - close(*outPipePtr); - } - if (errFilePtr) { - close(*errFilePtr); - } - if (pipeIds[0] != -1) { - close(pipeIds[0]); - } - if (lastOutputId != -1) { - close(lastOutputId); - } - - + + + if (inputId != -1) dup2(inputId, 0); + if (outputId != -1) dup2(outputId, 1); + if (errorId != -1) dup2(errorId, 2); + + for (i = 3; (i <= outputId) || (i <= inputId) || (i <= errorId); i++) { + close(i); + } + + (void)signal(SIGPIPE, SIG_DFL); - 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)) { - - } -#ifdef JIM_MAINTAINER - { - - static char *const false_argv[2] = {"false", NULL}; - execvp(false_argv[0],false_argv); - } -#endif + execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron()); + + + fprintf(stderr, "couldn't exec \"%s\"\n", arg_array[firstArg]); _exit(127); } #endif - + if (table->used == table->size) { table->size += WAIT_TABLE_GROW_BY; table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info)); } @@ -5268,66 +5040,66 @@ table->info[table->used].flags = 0; table->used++; pidPtr[numPids] = pid; - + errorId = origErrorId; - if (inputId != -1) { - close(inputId); + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); } - if (outputId != -1) { - close(outputId); + if (outputId != JIM_BAD_FD) { + JimCloseFd(outputId); } inputId = pipeIds[0]; - pipeIds[0] = pipeIds[1] = -1; + pipeIds[0] = pipeIds[1] = JIM_BAD_FD; } *pidArrayPtr = pidPtr; cleanup: - if (inputId != -1) { - close(inputId); - } - if (lastOutputId != -1) { - close(lastOutputId); - } - if (errorId != -1) { - close(errorId); + if (inputId != JIM_BAD_FD) { + JimCloseFd(inputId); + } + if (lastOutputId != JIM_BAD_FD) { + JimCloseFd(lastOutputId); + } + if (errorId != JIM_BAD_FD) { + JimCloseFd(errorId); } Jim_Free(arg_array); JimRestoreEnv(save_environ); return numPids; error: - if ((inPipePtr != NULL) && (*inPipePtr != -1)) { - close(*inPipePtr); - *inPipePtr = -1; - } - if ((outPipePtr != NULL) && (*outPipePtr != -1)) { - close(*outPipePtr); - *outPipePtr = -1; - } - if ((errFilePtr != NULL) && (*errFilePtr != -1)) { - close(*errFilePtr); - *errFilePtr = -1; - } - if (pipeIds[0] != -1) { - close(pipeIds[0]); - } - if (pipeIds[1] != -1) { - close(pipeIds[1]); + if ((inPipePtr != NULL) && (*inPipePtr != JIM_BAD_FD)) { + JimCloseFd(*inPipePtr); + *inPipePtr = JIM_BAD_FD; + } + if ((outPipePtr != NULL) && (*outPipePtr != JIM_BAD_FD)) { + JimCloseFd(*outPipePtr); + *outPipePtr = JIM_BAD_FD; + } + if ((errFilePtr != NULL) && (*errFilePtr != JIM_BAD_FD)) { + JimCloseFd(*errFilePtr); + *errFilePtr = JIM_BAD_FD; + } + if (pipeIds[0] != JIM_BAD_FD) { + JimCloseFd(pipeIds[0]); + } + if (pipeIds[1] != JIM_BAD_FD) { + JimCloseFd(pipeIds[1]); } if (pidPtr != NULL) { for (i = 0; i < numPids; i++) { if (pidPtr[i] != JIM_BAD_PID) { - JimDetachPids(table, 1, &pidPtr[i]); + JimDetachPids(interp, 1, &pidPtr[i]); } } Jim_Free(pidPtr); } numPids = -1; @@ -5339,11 +5111,11 @@ { struct WaitInfoTable *table = Jim_CmdPrivData(interp); int result = JIM_OK; int i; - + for (i = 0; i < numPids; i++) { int waitStatus = 0; if (JimWaitForProcess(table, pidPtr[i], &waitStatus) != JIM_BAD_PID) { if (JimCheckWaitStatus(interp, pidPtr[i], waitStatus, errStrObj) != JIM_OK) { result = JIM_ERR; @@ -5355,29 +5127,233 @@ return result; } int Jim_execInit(Jim_Interp *interp) { - struct WaitInfoTable *waitinfo; if (Jim_PackageProvide(interp, "exec", "1.0", JIM_ERRMSG)) return JIM_ERR; #ifdef SIGPIPE (void)signal(SIGPIPE, SIG_IGN); #endif - 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); - + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, JimAllocWaitInfoTable(), JimFreeWaitInfoTable); 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, 0, NULL); +} + +static fdtype JimOpenForWrite(const char *filename, int append) +{ + return CreateFile(filename, append ? FILE_APPEND_DATA : GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + JimStdSecAttrs(), append ? OPEN_ALWAYS : CREATE_ALWAYS, 0, (HANDLE) NULL); +} + +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]) { int i; @@ -5406,15 +5382,10 @@ static void JimRestoreEnv(char **env) { JimFreeEnv(env, Jim_GetEnviron()); } -static char **JimOriginalEnviron(void) -{ - return NULL; -} - static Jim_Obj * JimWinBuildCommandLine(Jim_Interp *interp, char **argv) { char *start, *special; int quote, i; @@ -5484,19 +5455,18 @@ } return strObj; } static pidtype -JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId) +JimStartWinProcess(Jim_Interp *interp, char **argv, char *env, fdtype inputId, fdtype outputId, fdtype errorId) { STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; - HANDLE hProcess; + HANDLE hProcess, h; char execPath[MAX_PATH]; pidtype pid = JIM_BAD_PID; Jim_Obj *cmdLineObj; - char *winenv; if (JimWinFindExecutable(argv[0], execPath) < 0) { return JIM_BAD_PID; } argv[0] = execPath; @@ -5510,51 +5480,47 @@ startInfo.dwFlags = STARTF_USESTDHANDLES; startInfo.hStdInput = INVALID_HANDLE_VALUE; startInfo.hStdOutput= INVALID_HANDLE_VALUE; startInfo.hStdError = INVALID_HANDLE_VALUE; - if (inputId == -1) { - inputId = _fileno(stdin); - } - DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(inputId), hProcess, &startInfo.hStdInput, - 0, TRUE, DUPLICATE_SAME_ACCESS); - if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { - goto end; - } - - if (outputId == -1) { - outputId = _fileno(stdout); - } - DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(outputId), hProcess, &startInfo.hStdOutput, - 0, TRUE, DUPLICATE_SAME_ACCESS); - if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { - goto end; - } - - - if (errorId == -1) { - errorId = _fileno(stderr); - } - DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(errorId), hProcess, &startInfo.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS); - if (startInfo.hStdError == INVALID_HANDLE_VALUE) { - goto end; - } - - if (env == NULL) { - - winenv = NULL; - } - else if (env[0] == NULL) { - winenv = (char *)"\0"; - } - else { - winenv = env[0]; - } - - if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, - 0, winenv, NULL, &startInfo, &procInfo)) { + 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 (startInfo.hStdInput == JIM_BAD_FD) { + 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 (startInfo.hStdOutput == JIM_BAD_FD) { + 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 (startInfo.hStdError == JIM_BAD_FD) { + goto end; + } + + if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, + 0, env, NULL, &startInfo, &procInfo)) { goto end; } WaitForInputIdle(procInfo.hProcess, 5000); @@ -5562,27 +5528,49 @@ pid = procInfo.hProcess; end: Jim_FreeNewObj(interp, cmdLineObj); - if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { + if (startInfo.hStdInput != JIM_BAD_FD) { CloseHandle(startInfo.hStdInput); } - if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { + if (startInfo.hStdOutput != JIM_BAD_FD) { CloseHandle(startInfo.hStdOutput); } - if (startInfo.hStdError != INVALID_HANDLE_VALUE) { + if (startInfo.hStdError != JIM_BAD_FD) { CloseHandle(startInfo.hStdError); } return pid; } - #else -static char **JimOriginalEnviron(void) +static int JimOpenForWrite(const char *filename, int append) { - return Jim_GetEnviron(); + 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; } static char **JimSaveEnv(char **env) { char **saveenv = Jim_GetEnviron(); @@ -5597,21 +5585,13 @@ } #endif #endif - -#ifdef STRPTIME_NEEDS_XOPEN_SOURCE #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 500 #endif -#endif - - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #include #include #include #include @@ -5619,116 +5599,64 @@ #ifdef HAVE_SYS_TIME_H #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; - jim_wide seconds; - struct clock_options options = { 0, "%a %b %d %H:%M:%S %Z %Y" }; - struct tm *tm; - - if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) { - return JIM_ERR; - } - if (argc % 2 == 0) { + long seconds; + + const char *format = "%a %b %d %H:%M:%S %Z %Y"; + + if (argc == 2 || (argc == 3 && !Jim_CompareStringImmediate(interp, argv[1], "-format"))) { return -1; } - if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { + + if (argc == 3) { + format = Jim_String(argv[2]); + } + + if (Jim_GetLong(interp, argv[0], &seconds) != JIM_OK) { return JIM_ERR; } - t = seconds; - tm = options.gmt ? gmtime(&t) : localtime(&t); - if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) { - Jim_SetResultString(interp, "format string too long or invalid time", -1); + if (strftime(buf, sizeof(buf), format, localtime(&t)) == 0) { + Jim_SetResultString(interp, "format string too long", -1); return JIM_ERR; } Jim_SetResultString(interp, buf, -1); return JIM_OK; } #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(NULL); + time_t now = time(0); - struct clock_options options = { 0, NULL }; - - if (argc % 2 == 0) { + if (!Jim_CompareStringImmediate(interp, argv[1], "-format")) { 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]), options.format, &tm); + pt = strptime(Jim_String(argv[0]), Jim_String(argv[2]), &tm); if (pt == 0 || *pt != 0) { Jim_SetResultString(interp, "Failed to parse time according to format", -1); return JIM_ERR; } - - Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm)); + + Jim_SetResultInt(interp, mktime(&tm)); return JIM_OK; } #endif @@ -5760,54 +5688,54 @@ return JIM_OK; } 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, clock_cmd_micros, 0, 0, - + }, { "milliseconds", NULL, clock_cmd_millis, 0, 0, - + + }, + { "format", + "seconds ?-format format?", + clock_cmd_format, + 1, + 3, + }, #ifdef HAVE_STRPTIME { "scan", - "str -format format ?-gmt boolean?", + "str -format format", clock_cmd_scan, 3, - 5, - + 3, + }, #endif - { "seconds", - NULL, - clock_cmd_seconds, - 0, - 0, - - }, { NULL } }; int Jim_clockInit(Jim_Interp *interp) { @@ -5825,13 +5753,12 @@ #include static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - - Jim_Obj *dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); - Jim_SetResultInt(interp, dictObj && Jim_DictSize(interp, dictObj) != -1); + + Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0); return JIM_OK; } static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -5842,20 +5769,21 @@ return JIM_OK; } patternObj = (argc == 1) ? NULL : argv[1]; - + if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) { if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) { - + Jim_SetResult(interp, objPtr); return JIM_OK; } } - return Jim_DictMatchTypes(interp, objPtr, patternObj, JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS | JIM_DICTMATCH_VALUES); + + return Jim_DictValues(interp, objPtr, patternObj); } static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); @@ -5862,11 +5790,11 @@ if (!objPtr) { return JIM_OK; } - return Jim_DictMatchTypes(interp, objPtr, argc == 1 ? NULL : argv[1], JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS); + return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]); } static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int i; @@ -5874,29 +5802,27 @@ Jim_Obj *resultObj; Jim_Obj *objPtr; Jim_Obj **dictValuesObj; if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { - + Jim_UnsetVariable(interp, argv[0], JIM_NONE); return JIM_OK; } objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); if (objPtr == NULL) { - + return JIM_OK; } if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) { - - Jim_SetResultString(interp, "", -1); - return JIM_OK; + return JIM_ERR; } - + resultObj = Jim_NewDictObj(interp, NULL, 0); for (i = 0; i < len; i += 2) { if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) { Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]); @@ -5911,18 +5837,16 @@ static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr; int len = 0; - + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); if (objPtr) { len = Jim_DictSize(interp, objPtr); if (len < 0) { - - Jim_SetResultInt(interp, 0); - return JIM_OK; + return JIM_ERR; } } Jim_SetResultInt(interp, len); @@ -5952,11 +5876,11 @@ return JIM_ERR; } dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); if (!dictObj) { - + return Jim_SetVariable(interp, argv[0], listObj); } else if (Jim_DictSize(interp, dictObj) < 0) { return JIM_ERR; } @@ -5981,53 +5905,53 @@ { "exists", "arrayName", array_cmd_exists, 1, 1, - + }, { "get", "arrayName ?pattern?", array_cmd_get, 1, 2, - + }, { "names", "arrayName ?pattern?", array_cmd_names, 1, 2, - + }, { "set", "arrayName list", array_cmd_set, 2, 2, - + }, { "size", "arrayName", array_cmd_size, 1, 1, - + }, { "stat", "arrayName", array_cmd_stat, 1, 1, - + }, { "unset", "arrayName ?pattern?", array_cmd_unset, 1, 2, - + }, { NULL } }; @@ -6063,14 +5987,11 @@ Jim_arrayInit(interp); Jim_stdlibInit(interp); Jim_tclcompatInit(interp); return JIM_OK; } -#define JIM_OPTIMIZATION -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +#define JIM_OPTIMIZATION #include #include #include @@ -6135,16 +6056,10 @@ #define JimPanic(X) JimPanicDump X #else #define JimPanic(X) #endif -#ifdef JIM_OPTIMIZATION -#define JIM_IF_OPTIM(X) X -#else -#define JIM_IF_OPTIM(X) -#endif - static char JimEmptyStringRep[] = ""; static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action); static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr, @@ -6197,34 +6112,34 @@ if (*pattern == '^') { not++; pattern++; } - + if (*pattern == ']') { goto first; } } while (*pattern && *pattern != ']') { - + if (pattern[0] == '\\') { first: pattern += utf8_tounicode_case(pattern, &pchar, nocase); } else { - + int start; int end; pattern += utf8_tounicode_case(pattern, &start, nocase); if (pattern[0] == '-' && pattern[1]) { - - pattern++; + + pattern += utf8_tounicode(pattern, &pchar); pattern += utf8_tounicode_case(pattern, &end, nocase); - + if ((c >= start && c <= end) || (c >= end && c <= start)) { match = 1; } continue; } @@ -6254,19 +6169,19 @@ while (pattern[1] == '*') { pattern++; } pattern++; if (!pattern[0]) { - return 1; + return 1; } while (*string) { - + if (JimGlobMatch(pattern, string, nocase)) - return 1; + return 1; string += utf8_tounicode(string, &c); } - return 0; + return 0; case '?': string += utf8_tounicode(string, &c); break; @@ -6275,20 +6190,20 @@ pattern = JimCharsetMatch(pattern + 1, c, nocase ? JIM_NOCASE : 0); if (!pattern) { return 0; } if (!*pattern) { - + continue; } break; } case '\\': if (pattern[1]) { pattern++; } - + default: string += utf8_tounicode_case(string, &c, nocase); utf8_tounicode_case(pattern, &pchar, nocase); if (pchar != c) { return 0; @@ -6334,11 +6249,11 @@ maxchars--; } if (!maxchars) { return 0; } - + if (*s1) { return 1; } if (*s2) { return -1; @@ -6375,11 +6290,11 @@ const char *p; if (!l1 || !l2 || l1 > l2) return -1; - + for (p = s2 + l2 - 1; p != s2 - 1; p--) { if (*p == *s1 && memcmp(s1, p, l1) == 0) { return p - s2; } } @@ -6434,28 +6349,28 @@ } *sign = 1; } if (str[i] != '0') { - + return 0; } - + switch (str[i + 1]) { case 'x': case 'X': *base = 16; break; case 'o': case 'O': *base = 8; break; case 'b': case 'B': *base = 2; break; default: return 0; } i += 2; - + if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) { - + return i; } - + *base = 10; return 0; } static long jim_strtol(const char *str, char **endptr) @@ -6469,11 +6384,11 @@ if (endptr == NULL || *endptr != str + i) { return value * sign; } } - + return strtol(str, endptr, 10); } static jim_wide jim_strtoull(const char *str, char **endptr) @@ -6488,11 +6403,11 @@ if (endptr == NULL || *endptr != str + i) { return value * sign; } } - + return strtoull(str, endptr, 10); #else return (unsigned long)jim_strtol(str, endptr); #endif } @@ -6513,40 +6428,26 @@ int Jim_StringToDouble(const char *str, double *doublePtr) { char *endptr; - + errno = 0; *doublePtr = strtod(str, &endptr); return JimCheckConversion(str, endptr); } static jim_wide JimPowWide(jim_wide b, jim_wide e) { - jim_wide res = 1; - - - if (b == 1) { - - return 1; - } - if (e < 0) { - if (b != -1) { - return 0; - } - e = -e; - } - while (e) - { - if (e & 1) { - res *= b; - } - e >>= 1; - b *= b; + jim_wide i, res = 1; + + if ((b == 0 && e != 0) || (e < 0)) + return 0; + for (i = 0; i < e; i++) { + res *= b; } return res; } #ifdef JIM_DEBUG_PANIC @@ -6608,11 +6509,11 @@ char *Jim_StrDupLen(const char *s, int l) { char *copy = Jim_Alloc(l + 1); memcpy(copy, s, l + 1); - copy[l] = 0; + copy[l] = 0; return copy; } @@ -6697,52 +6598,52 @@ } void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) { - Jim_HashTable n; + Jim_HashTable n; unsigned int realsize = JimHashTableNextPower(size), i; if (size <= ht->used) return; Jim_InitHashTable(&n, ht->type, ht->privdata); n.size = realsize; n.sizemask = realsize - 1; n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *)); - + n.uniq = ht->uniq; - + memset(n.table, 0, realsize * sizeof(Jim_HashEntry *)); n.used = ht->used; for (i = 0; ht->used > 0; i++) { Jim_HashEntry *he, *nextHe; if (ht->table[i] == NULL) continue; - + he = ht->table[i]; while (he) { unsigned int h; nextHe = he->next; - + h = Jim_HashKey(ht, he->key) & n.sizemask; he->next = n.table[h]; n.table[h] = he; ht->used--; - + he = nextHe; } } assert(ht->used == 0); Jim_Free(ht->table); - + *ht = n; } int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val) @@ -6751,11 +6652,11 @@ entry = JimInsertHashEntry(ht, key, 0); if (entry == NULL) return JIM_ERR; - + Jim_SetHashKey(ht, entry, key); Jim_SetHashVal(ht, entry, val); return JIM_OK; } @@ -6777,11 +6678,11 @@ Jim_SetHashVal(ht, entry, val); } existed = 1; } else { - + Jim_SetHashKey(ht, entry, key); Jim_SetHashVal(ht, entry, val); existed = 0; } @@ -6800,11 +6701,11 @@ he = ht->table[h]; prevHe = NULL; while (he) { if (Jim_CompareHashKeys(ht, key, he->key)) { - + if (prevHe) prevHe->next = he->next; else ht->table[h] = he->next; Jim_FreeEntryKey(ht, he); @@ -6814,19 +6715,19 @@ return JIM_OK; } prevHe = he; he = he->next; } - return JIM_ERR; + return JIM_ERR; } int Jim_FreeHashTable(Jim_HashTable *ht) { unsigned int i; - + for (i = 0; ht->used > 0; i++) { Jim_HashEntry *he, *nextHe; if ((he = ht->table[i]) == NULL) continue; @@ -6837,15 +6738,15 @@ Jim_Free(he); ht->used--; he = nextHe; } } - + Jim_Free(ht->table); - + JimResetHashTable(ht); - return JIM_OK; + return JIM_OK; } Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key) { Jim_HashEntry *he; @@ -6918,24 +6819,24 @@ static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace) { unsigned int h; Jim_HashEntry *he; - + JimExpandHashTableIfNeeded(ht); - + h = Jim_HashKey(ht, key) & ht->sizemask; - + he = ht->table[h]; while (he) { if (Jim_CompareHashKeys(ht, key, he->key)) return replace ? he : NULL; he = he->next; } - + he = Jim_Alloc(sizeof(*he)); he->next = ht->table[h]; ht->table[h] = he; ht->used++; he->key = NULL; @@ -6964,16 +6865,16 @@ { Jim_Free(key); } static const Jim_HashTableType JimPackageHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - NULL + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + NULL }; typedef struct AssocDataValue { Jim_InterpDeleteProc *delProc; @@ -6988,16 +6889,16 @@ assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data); Jim_Free(data); } static const Jim_HashTableType JimAssocDataHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimAssocDataHashTableValueDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimAssocDataHashTableValueDestructor }; void Jim_InitStack(Jim_Stack *stack) { stack->len = 0; @@ -7050,61 +6951,56 @@ freeFunc(stack->vector[i]); } -#define JIM_TT_NONE 0 -#define JIM_TT_STR 1 -#define JIM_TT_ESC 2 -#define JIM_TT_VAR 3 -#define JIM_TT_DICTSUGAR 4 -#define JIM_TT_CMD 5 - -#define JIM_TT_SEP 6 -#define JIM_TT_EOL 7 -#define JIM_TT_EOF 8 - -#define JIM_TT_LINE 9 -#define JIM_TT_WORD 10 +#define JIM_TT_NONE 0 +#define JIM_TT_STR 1 +#define JIM_TT_ESC 2 +#define JIM_TT_VAR 3 +#define JIM_TT_DICTSUGAR 4 +#define JIM_TT_CMD 5 + +#define JIM_TT_SEP 6 +#define JIM_TT_EOL 7 +#define JIM_TT_EOF 8 + +#define JIM_TT_LINE 9 +#define JIM_TT_WORD 10 #define JIM_TT_SUBEXPR_START 11 #define JIM_TT_SUBEXPR_END 12 #define JIM_TT_SUBEXPR_COMMA 13 #define JIM_TT_EXPR_INT 14 #define JIM_TT_EXPR_DOUBLE 15 -#define JIM_TT_EXPR_BOOLEAN 16 -#define JIM_TT_EXPRSUGAR 17 +#define JIM_TT_EXPRSUGAR 16 #define JIM_TT_EXPR_OP 20 #define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) -#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA) - -#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP) - struct JimParseMissing { - int ch; - int line; + int ch; + int line; }; struct JimParserCtx { - const char *p; - int len; - int linenr; + const char *p; + int len; + int linenr; const char *tstart; - const char *tend; - int tline; - int tt; - int eof; - int inquote; - int comment; - struct JimParseMissing missing; + const char *tend; + int tline; + int tt; + int eof; + int inquote; + int comment; + struct JimParseMissing missing; }; static int JimParseScript(struct JimParserCtx *pc); static int JimParseSep(struct JimParserCtx *pc); static int JimParseEol(struct JimParserCtx *pc); @@ -7134,11 +7030,11 @@ pc->missing.line = linenr; } static int JimParseScript(struct JimParserCtx *pc) { - while (1) { + while (1) { if (!pc->len) { pc->tstart = pc->p; pc->tend = pc->p - 1; pc->tline = pc->linenr; pc->tt = JIM_TT_EOL; @@ -7170,11 +7066,11 @@ pc->comment = 0; return JimParseCmd(pc); case '$': pc->comment = 0; if (JimParseVar(pc) == JIM_ERR) { - + pc->tstart = pc->tend = pc->p++; pc->len--; pc->tt = JIM_TT_ESC; } return JIM_OK; @@ -7231,11 +7127,11 @@ static void JimParseSubBrace(struct JimParserCtx *pc) { int level = 1; - + pc->p++; pc->len--; while (pc->len) { switch (*pc->p) { case '\\': @@ -7275,11 +7171,11 @@ static int JimParseSubQuote(struct JimParserCtx *pc) { int tt = JIM_TT_STR; int line = pc->tline; - + pc->p++; pc->len--; while (pc->len) { switch (*pc->p) { case '\\': @@ -7324,11 +7220,11 @@ { int level = 1; int startofword = 1; int line = pc->tline; - + pc->p++; pc->len--; while (pc->len) { switch (*pc->p) { case '\\': @@ -7404,17 +7300,17 @@ return JIM_OK; } static int JimParseVar(struct JimParserCtx *pc) { - + pc->p++; pc->len--; #ifdef EXPRSUGAR_BRACKET if (*pc->p == '[') { - + JimParseCmd(pc); pc->tt = JIM_TT_EXPRSUGAR; return JIM_OK; } #endif @@ -7440,11 +7336,11 @@ pc->len--; } } else { while (1) { - + if (pc->p[0] == ':' && pc->p[1] == ':') { while (*pc->p == ':') { pc->p++; pc->len--; } @@ -7455,11 +7351,11 @@ pc->len--; continue; } break; } - + if (*pc->p == '(') { int count = 1; const char *paren = NULL; pc->tt = JIM_TT_DICTSUGAR; @@ -7482,11 +7378,11 @@ if (count == 0) { pc->p++; pc->len--; } else if (paren) { - + paren++; pc->len += (pc->p - paren); pc->p = paren; } #ifndef EXPRSUGAR_BRACKET @@ -7507,19 +7403,19 @@ static int JimParseStr(struct JimParserCtx *pc) { if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL || pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) { - + if (*pc->p == '{') { return JimParseBrace(pc); } if (*pc->p == '"') { pc->inquote = 1; pc->p++; pc->len--; - + pc->missing.line = pc->tline; } } pc->tstart = pc->p; pc->tline = pc->linenr; @@ -7545,25 +7441,25 @@ } pc->p++; pc->len--; } else if (pc->len == 1) { - + pc->missing.ch = '\\'; } break; case '(': - + if (pc->len > 1 && pc->p[1] != '$') { break; } - + case ')': - + if (*pc->p == '(' || pc->tt == JIM_TT_VAR) { if (pc->p == pc->tstart) { - + pc->p++; pc->len--; } pc->tend = pc->p - 1; pc->tt = JIM_TT_ESC; @@ -7603,11 +7499,11 @@ break; } pc->p++; pc->len--; } - return JIM_OK; + return JIM_OK; } static int JimParseComment(struct JimParserCtx *pc) { while (*pc->p) { @@ -7714,34 +7610,34 @@ if (c == -1) { break; } val = (val << 4) | c; } - + if (s[i] == '{') { if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') { - + i--; k = 0; } else { - + k++; } } if (k) { - + if (s[i] == 'x') { *p++ = val; } else { p += utf8_fromunicode(p, val); } i += k; break; } - + *p++ = s[i]; } break; case 'v': *p++ = 0xb; @@ -7750,11 +7646,11 @@ case '\0': *p++ = '\\'; i++; break; case '\n': - + *p++ = ' '; do { i++; } while (s[i + 1] == ' ' || s[i + 1] == '\t'); break; @@ -7764,11 +7660,11 @@ case '3': case '4': case '5': case '6': case '7': - + { int val = 0; int c = odigitval(s[i + 1]); val = c; @@ -7812,23 +7708,27 @@ char *token; int len; start = pc->tstart; end = pc->tend; - len = (end - start) + 1; - if (len < 0) { + if (start > end) { len = 0; - } - token = Jim_Alloc(len + 1); - if (pc->tt != JIM_TT_ESC) { - - memcpy(token, start, len); - token[len] = '\0'; + token = Jim_Alloc(1); + token[0] = '\0'; } else { - - len = JimEscape(token, start, len); + len = (end - start) + 1; + token = Jim_Alloc(len + 1); + if (pc->tt != JIM_TT_ESC) { + + memcpy(token, start, len); + token[len] = '\0'; + } + else { + + len = JimEscape(token, start, len); + } } return Jim_NewStringObjNoAlloc(interp, token, len); } @@ -7890,11 +7790,11 @@ while (pc->len) { switch (*pc->p) { case '\\': pc->tt = JIM_TT_ESC; if (--pc->len == 0) { - + pc->tend = pc->p; return JIM_OK; } pc->p++; break; @@ -7926,11 +7826,11 @@ pc->tend = pc->p - 1; return JIM_OK; } if (*pc->p == '\\') { if (--pc->len == 0) { - + pc->tend = pc->p; return JIM_OK; } pc->tt = JIM_TT_ESC; pc->p++; @@ -7946,24 +7846,24 @@ Jim_Obj *Jim_NewObj(Jim_Interp *interp) { Jim_Obj *objPtr; - + if (interp->freeList != NULL) { - + objPtr = interp->freeList; interp->freeList = objPtr->nextObjPtr; } else { - + objPtr = Jim_Alloc(sizeof(*objPtr)); } objPtr->refCount = 0; - + objPtr->prevObjPtr = NULL; objPtr->nextObjPtr = interp->liveList; if (interp->liveList) interp->liveList->prevObjPtr = objPtr; interp->liveList = objPtr; @@ -7971,32 +7871,32 @@ return objPtr; } void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) { - + JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr, objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "")); - + Jim_FreeIntRep(interp, objPtr); - + if (objPtr->bytes != NULL) { if (objPtr->bytes != JimEmptyStringRep) Jim_Free(objPtr->bytes); } - + if (objPtr->prevObjPtr) objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr; if (objPtr->nextObjPtr) objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr; if (interp->liveList == objPtr) interp->liveList = objPtr->nextObjPtr; #ifdef JIM_DISABLE_OBJECT_POOL Jim_Free(objPtr); #else - + objPtr->prevObjPtr = NULL; objPtr->nextObjPtr = interp->freeList; if (interp->freeList) interp->freeList->prevObjPtr = objPtr; interp->freeList = objPtr; @@ -8019,44 +7919,45 @@ { Jim_Obj *dupPtr; dupPtr = Jim_NewObj(interp); if (objPtr->bytes == NULL) { - + dupPtr->bytes = NULL; } else if (objPtr->length == 0) { + dupPtr->bytes = JimEmptyStringRep; dupPtr->length = 0; dupPtr->typePtr = NULL; return dupPtr; } else { dupPtr->bytes = Jim_Alloc(objPtr->length + 1); dupPtr->length = objPtr->length; - + memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1); } - + dupPtr->typePtr = objPtr->typePtr; if (objPtr->typePtr != NULL) { if (objPtr->typePtr->dupIntRepProc == NULL) { dupPtr->internalRep = objPtr->internalRep; } else { - + objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr); } } return dupPtr; } const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) { if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); } if (lenPtr) *lenPtr = objPtr->length; @@ -8065,22 +7966,25 @@ int Jim_Length(Jim_Obj *objPtr) { if (objPtr->bytes == NULL) { - - Jim_GetString(objPtr, NULL); + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); } return objPtr->length; } const char *Jim_String(Jim_Obj *objPtr) { if (objPtr->bytes == NULL) { - - Jim_GetString(objPtr, 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); } return objPtr->bytes; } static void JimSetStringBytes(Jim_Obj *objPtr, const char *str) @@ -8098,33 +8002,22 @@ DupDictSubstInternalRep, NULL, JIM_TYPE_NONE, }; -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, - 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 const Jim_ObjType interpolatedObjType = { + "interpolated", + FreeInterpolatedInternalRep, + NULL, + NULL, + JIM_TYPE_NONE, +}; static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); static const Jim_ObjType stringObjType = { @@ -8144,22 +8037,22 @@ } static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr->typePtr != &stringObjType) { - + if (objPtr->bytes == NULL) { - + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); objPtr->typePtr->updateStringProc(objPtr); } - + Jim_FreeIntRep(interp, objPtr); - + objPtr->typePtr = &stringObjType; objPtr->internalRep.strValue.maxLength = objPtr->length; - + objPtr->internalRep.strValue.charLength = -1; } return JIM_OK; } @@ -8180,37 +8073,39 @@ Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) { Jim_Obj *objPtr = Jim_NewObj(interp); - + if (len == -1) len = strlen(s); - + if (len == 0) { objPtr->bytes = JimEmptyStringRep; } else { - objPtr->bytes = Jim_StrDupLen(s, len); + objPtr->bytes = Jim_Alloc(len + 1); + memcpy(objPtr->bytes, s, len); + objPtr->bytes[len] = '\0'; } objPtr->length = len; - + objPtr->typePtr = NULL; return objPtr; } Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen) { #ifdef JIM_UTF8 - + int bytelen = utf8_index(s, charlen); Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen); - + objPtr->typePtr = &stringObjType; objPtr->internalRep.strValue.maxLength = bytelen; objPtr->internalRep.strValue.charLength = charlen; return objPtr; @@ -8237,11 +8132,11 @@ len = strlen(str); needlen = objPtr->length + len; if (objPtr->internalRep.strValue.maxLength < needlen || objPtr->internalRep.strValue.maxLength == 0) { needlen *= 2; - + if (needlen < 7) { needlen = 7; } if (objPtr->bytes == JimEmptyStringRep) { objPtr->bytes = Jim_Alloc(needlen + 1); @@ -8253,11 +8148,11 @@ } memcpy(objPtr->bytes + objPtr->length, str, len); objPtr->bytes[objPtr->length + len] = '\0'; if (objPtr->internalRep.strValue.charLength >= 0) { - + objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len); } objPtr->length += len; } @@ -8315,11 +8210,11 @@ int l1, l2; const char *s1 = Jim_GetString(firstObjPtr, &l1); const char *s2 = Jim_GetString(secondObjPtr, &l2); if (nocase) { - + return JimStringCompareLen(s1, s2, -1, nocase); } return JimStringCompare(s1, l1, s2, l2); } @@ -8417,11 +8312,11 @@ if (first == 0 && rangeLen == len) { return strObjPtr; } if (len == bytelen) { - + return Jim_NewStringObj(interp, str + first, rangeLen); } return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen); #else return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr); @@ -8446,19 +8341,19 @@ return strObjPtr; } str = Jim_String(strObjPtr); - + objPtr = Jim_NewStringObjUtf8(interp, str, first); - + if (newStrObj) { Jim_AppendObj(interp, objPtr, newStrObj); } - + Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1); return objPtr; } @@ -8475,10 +8370,12 @@ static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr) { char *buf; int len; const char *str; + + SetStringFromAny(interp, strObjPtr); str = Jim_GetString(strObjPtr, &len); #ifdef JIM_UTF8 len *= 2; @@ -8491,10 +8388,14 @@ static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) { char *buf; const char *str; int len; + + if (strObjPtr->typePtr != &stringObjType) { + SetStringFromAny(interp, strObjPtr); + } str = Jim_GetString(strObjPtr, &len); #ifdef JIM_UTF8 len *= 2; @@ -8510,11 +8411,13 @@ int len; int c; const char *str; str = Jim_GetString(strObjPtr, &len); - + if (len == 0) { + return strObjPtr; + } #ifdef JIM_UTF8 len *= 2; #endif buf = p = Jim_Alloc(len + 1); @@ -8549,11 +8452,11 @@ while (len) { int c; int n = utf8_tounicode(str, &c); if (utf8_memchr(trimchars, trimlen, c) == NULL) { - + break; } str += n; len -= n; } @@ -8620,41 +8523,41 @@ len = Jim_Length(strObjPtr); nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen); if (nontrim == NULL) { - + return Jim_NewEmptyStringObj(interp); } if (nontrim == strObjPtr->bytes + len) { - + return strObjPtr; } if (Jim_IsShared(strObjPtr)) { strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes)); } else { - + strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0; strObjPtr->length = (nontrim - strObjPtr->bytes); } return strObjPtr; } static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) { - + Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr); - + strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr); - + if (objPtr != strObjPtr && objPtr->refCount == 0) { - + Jim_FreeNewObj(interp, objPtr); } return strObjPtr; } @@ -8672,17 +8575,17 @@ static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict) { static const char * const strclassnames[] = { "integer", "alpha", "alnum", "ascii", "digit", "double", "lower", "upper", "space", "xdigit", - "control", "print", "graph", "punct", "boolean", + "control", "print", "graph", "punct", NULL }; enum { STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT, - STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN, + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT }; int strclass; int len; int i; const char *str; @@ -8711,17 +8614,10 @@ double d; Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE); return JIM_OK; } - case STR_IS_BOOLEAN: - { - int b; - Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK); - return JIM_OK; - } - case STR_IS_ALPHA: isclassfunc = isalpha; break; case STR_IS_ALNUM: isclassfunc = isalnum; break; case STR_IS_ASCII: isclassfunc = jim_isascii; break; case STR_IS_DIGIT: isclassfunc = isdigit; break; case STR_IS_LOWER: isclassfunc = islower; break; @@ -8735,11 +8631,11 @@ default: return JIM_ERR; } for (i = 0; i < len; i++) { - if (!isclassfunc(UCHAR(str[i]))) { + if (!isclassfunc(str[i])) { Jim_SetResultBool(interp, 0); return JIM_OK; } } Jim_SetResultBool(interp, 1); @@ -8760,18 +8656,20 @@ { if (objPtr->typePtr == &comparedStringObjType && objPtr->internalRep.ptr == str) { return 1; } else { - if (strcmp(str, Jim_String(objPtr)) != 0) + const char *objStr = Jim_String(objPtr); + + if (strcmp(str, objStr) != 0) return 0; if (objPtr->typePtr != &comparedStringObjType) { Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &comparedStringObjType; } - objPtr->internalRep.ptr = (char *)str; + objPtr->internalRep.ptr = (char *)str; return 1; } } static int qsortCompareStringPointers(const void *a, const void *b) @@ -8860,20 +8758,20 @@ int type; } ScriptToken; typedef struct ScriptObj { - ScriptToken *token; - Jim_Obj *fileNameObj; - int len; - int substFlags; + ScriptToken *token; + Jim_Obj *fileNameObj; + int len; + int substFlags; int inUse; /* Used to share a ScriptObj. Currently only used by Jim_EvalObj() as protection against shimmering of the currently evaluated object. */ - int firstline; - int linenr; - int missing; + int firstline; + int linenr; + int missing; } ScriptObj; static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); static int JimParseCheckMissing(Jim_Interp *interp, int ch); static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr); @@ -8901,23 +8799,23 @@ dupPtr->typePtr = NULL; } typedef struct { - const char *token; - int len; - int type; - int line; + const char *token; + int len; + int type; + int line; } ParseToken; typedef struct { - - ParseToken *list; - int size; - int count; - ParseToken static_list[20]; + + ParseToken *list; + int size; + int count; + ParseToken static_list[20]; } ParseTokenList; static void ScriptTokenListInit(ParseTokenList *tokenlist) { tokenlist->list = tokenlist->static_list; @@ -8936,18 +8834,18 @@ int line) { ParseToken *t; if (tokenlist->count == tokenlist->size) { - + tokenlist->size *= 2; if (tokenlist->list != tokenlist->static_list) { tokenlist->list = Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list)); } else { - + tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list)); memcpy(tokenlist->list, tokenlist->static_list, tokenlist->count * sizeof(*tokenlist->list)); } } @@ -8956,32 +8854,25 @@ t->len = len; t->type = type; t->line = line; } -static int JimCountWordTokens(struct ScriptObj *script, ParseToken *t) +static int JimCountWordTokens(ParseToken *t) { int expand = 1; int count = 0; - + if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) { if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) { - + expand = -1; t++; } - else { - if (script->missing == ' ') { - - script->missing = '}'; - script->linenr = t[1].line; - } - } } - + while (!TOKEN_IS_SEP(t->type)) { t++; count++; } @@ -8991,11 +8882,11 @@ static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t) { Jim_Obj *objPtr; if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) { - + int len = t->len; char *str = Jim_Alloc(len + 1); len = JimEscape(str, t->token, len); objPtr = Jim_NewStringObjNoAlloc(interp, str, len); } @@ -9008,13 +8899,13 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, ParseTokenList *tokenlist) { int i; struct ScriptToken *token; - + int lineargs = 0; - + ScriptToken *linefirst; int count; int linenr; #ifdef DEBUG_SHOW_SCRIPT_TOKENS @@ -9023,11 +8914,11 @@ printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type), tokenlist->list[i].len, tokenlist->list[i].token); } #endif - + count = tokenlist->count; for (i = 0; i < tokenlist->count; i++) { if (tokenlist->list[i].type == JIM_TT_EOL) { count++; } @@ -9034,59 +8925,59 @@ } linenr = script->firstline = tokenlist->list[0].line; token = script->token = Jim_Alloc(sizeof(ScriptToken) * count); - + linefirst = token++; for (i = 0; i < tokenlist->count; ) { - + int wordtokens; - + while (tokenlist->list[i].type == JIM_TT_SEP) { i++; } - wordtokens = JimCountWordTokens(script, tokenlist->list + i); + wordtokens = JimCountWordTokens(tokenlist->list + i); if (wordtokens == 0) { - + if (lineargs) { linefirst->type = JIM_TT_LINE; linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr); Jim_IncrRefCount(linefirst->objPtr); - + lineargs = 0; linefirst = token++; } i++; continue; } else if (wordtokens != 1) { - + token->type = JIM_TT_WORD; token->objPtr = Jim_NewIntObj(interp, wordtokens); Jim_IncrRefCount(token->objPtr); token++; if (wordtokens < 0) { - + i++; wordtokens = -wordtokens - 1; lineargs--; } } if (lineargs == 0) { - + linenr = tokenlist->list[i].line; } lineargs++; - + while (wordtokens--) { const ParseToken *t = &tokenlist->list[i++]; token->type = t->type; token->objPtr = JimMakeScriptObj(interp, t); @@ -9119,11 +9010,11 @@ { ScriptObj *script = JimGetScript(interp, scriptObj); if (stateCharPtr) { *stateCharPtr = script->missing; } - return script->missing == ' ' || script->missing == '}'; + return (script->missing == ' '); } static int JimParseCheckMissing(Jim_Interp *interp, int ch) { const char *msg; @@ -9137,13 +9028,10 @@ msg = "unmatched \"[\""; break; case '{': msg = "missing close-brace"; break; - case '}': - msg = "extra characters after close-brace"; - break; case '"': default: msg = "missing quote"; break; } @@ -9161,11 +9049,11 @@ token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count); for (i = 0; i < tokenlist->count; i++) { const ParseToken *t = &tokenlist->list[i]; - + token->type = t->type; token->objPtr = JimMakeScriptObj(interp, t); Jim_IncrRefCount(token->objPtr); token++; } @@ -9180,29 +9068,29 @@ struct JimParserCtx parser; struct ScriptObj *script; ParseTokenList tokenlist; int line = 1; - + if (objPtr->typePtr == &sourceObjType) { line = objPtr->internalRep.sourceValue.lineNumber; } - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, scriptText, scriptTextLen, line); while (!parser.eof) { JimParseScript(&parser); ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, parser.tline); } - + ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); - + script = Jim_Alloc(sizeof(*script)); memset(script, 0, sizeof(*script)); script->inUse = 1; if (objPtr->typePtr == &sourceObjType) { script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; @@ -9214,14 +9102,14 @@ script->missing = parser.missing.ch; script->linenr = parser.missing.line; ScriptObjAddTokens(interp, script, &tokenlist); - + ScriptTokenListFree(&tokenlist); - + Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, script); objPtr->typePtr = &scriptObjType; } @@ -9228,11 +9116,11 @@ static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script); static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr == interp->emptyObj) { - + objPtr = interp->nullScriptObj; } if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { JimSetScriptFromAny(interp, objPtr); @@ -9267,66 +9155,67 @@ Jim_FreeHashTable(cmdPtr->u.proc.staticVars); Jim_Free(cmdPtr->u.proc.staticVars); } } else { - + if (cmdPtr->u.native.delProc) { cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData); } } if (cmdPtr->prevCmd) { - + JimDecrCmdRefCount(interp, cmdPtr->prevCmd); } Jim_Free(cmdPtr); } } + static void JimVariablesHTValDestructor(void *interp, void *val) { Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr); Jim_Free(val); } static const Jim_HashTableType JimVariablesHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimVariablesHTValDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimVariablesHTValDestructor }; static void JimCommandsHT_ValDestructor(void *interp, void *val) { JimDecrCmdRefCount(interp, val); } static const Jim_HashTableType JimCommandsHashTableType = { - JimStringCopyHTHashFunction, - JimStringCopyHTDup, - NULL, - JimStringCopyHTKeyCompare, - JimStringCopyHTKeyDestructor, - JimCommandsHT_ValDestructor + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimCommandsHT_ValDestructor }; #ifdef jim_ext_namespace static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj) { const char *name = Jim_String(nsObj); if (name[0] == ':' && name[1] == ':') { - + while (*++name == ':') { } nsObj = Jim_NewStringObj(interp, name, -1); } else if (Jim_Length(interp->framePtr->nsObj)) { - + nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, nsObj, "::", name, NULL); } return nsObj; } @@ -9350,16 +9239,16 @@ static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr) { Jim_Obj *objPtr = interp->emptyObj; if (name[0] == ':' && name[1] == ':') { - + while (*++name == ':') { } } else if (Jim_Length(interp->framePtr->nsObj)) { - + objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, objPtr, "::", name, NULL); name = Jim_String(objPtr); } Jim_IncrRefCount(objPtr); @@ -9368,11 +9257,11 @@ } #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ)) #else - + #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME)) #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY) Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr) { @@ -9387,17 +9276,17 @@ Jim_InterpIncrProcEpoch(interp); } if (he && interp->local) { - + cmd->prevCmd = Jim_GetHashEntryVal(he); Jim_SetHashVal(&interp->commands, he, cmd); } else { if (he) { - + Jim_DeleteHashEntry(&interp->commands, name); } Jim_AddHashEntry(&interp->commands, name, cmd); } @@ -9408,11 +9297,11 @@ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) { Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); - + memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; cmdPtr->u.native.delProc = delProc; cmdPtr->u.native.cmdProc = cmdProc; cmdPtr->u.native.privData = privData; @@ -9437,11 +9326,11 @@ Jim_Obj *objPtr, *initObjPtr, *nameObjPtr; Jim_Var *varPtr; int subLen; objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i); - + subLen = Jim_ListLength(interp, objPtr); if (subLen == 1 || subLen == 2) { nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0); if (subLen == 1) { initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE); @@ -9483,19 +9372,19 @@ static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname) { #ifdef jim_ext_namespace if (cmdPtr->isproc) { - + const char *pt = strrchr(cmdname, ':'); if (pt && pt != cmdname && pt[-1] == ':') { Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1); Jim_IncrRefCount(cmdPtr->u.proc.nsObj); if (Jim_FindHashEntry(&interp->commands, pt + 1)) { - + Jim_InterpIncrProcEpoch(interp); } } } #endif @@ -9508,11 +9397,11 @@ int argListLen; int i; argListLen = Jim_ListLength(interp, argListObjPtr); - + cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen); memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; cmdPtr->isproc = 1; cmdPtr->u.proc.argListObjPtr = argListObjPtr; @@ -9523,24 +9412,24 @@ cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj; Jim_IncrRefCount(argListObjPtr); Jim_IncrRefCount(bodyObjPtr); Jim_IncrRefCount(cmdPtr->u.proc.nsObj); - + if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) { goto err; } - - + + for (i = 0; i < argListLen; i++) { Jim_Obj *argPtr; Jim_Obj *nameObjPtr; Jim_Obj *defaultObjPtr; int len; - + argPtr = Jim_ListGetIndex(interp, argListObjPtr, i); len = Jim_ListLength(interp, argPtr); if (len == 0) { Jim_SetResultString(interp, "argument with no name", -1); err: @@ -9551,16 +9440,16 @@ Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr); goto err; } if (len == 2) { - + nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0); defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1); } else { - + nameObjPtr = argPtr; defaultObjPtr = NULL; } @@ -9621,29 +9510,29 @@ } fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj); fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj); - + he = Jim_FindHashEntry(&interp->commands, fqold); if (he == NULL) { Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName); } else if (Jim_FindHashEntry(&interp->commands, fqnew)) { Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName); } else { - + cmdPtr = Jim_GetHashEntryVal(he); JimIncrCmdRefCount(cmdPtr); JimUpdateProcNamespace(interp, cmdPtr, fqnew); Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr); - + Jim_DeleteHashEntry(&interp->commands, fqold); - + Jim_InterpIncrProcEpoch(interp); ret = JIM_OK; } @@ -9682,23 +9571,23 @@ objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch #ifdef jim_ext_namespace || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj) #endif ) { + - - + const char *name = Jim_String(objPtr); Jim_HashEntry *he; if (name[0] == ':' && name[1] == ':') { while (*++name == ':') { } } #ifdef jim_ext_namespace else if (Jim_Length(interp->framePtr->nsObj)) { - + Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj); Jim_AppendStrings(interp, nameObj, "::", name, NULL); he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj)); Jim_FreeNewObj(interp, nameObj); if (he) { @@ -9705,11 +9594,11 @@ goto found; } } #endif - + he = Jim_FindHashEntry(&interp->commands, name); if (he == NULL) { if (flags & JIM_ERRMSG) { Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr); } @@ -9718,11 +9607,11 @@ #ifdef jim_ext_namespace found: #endif cmd = Jim_GetHashEntryVal(he); - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &commandObjType; objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch; objPtr->internalRep.cmdValue.cmdPtr = cmd; objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj; @@ -9737,11 +9626,11 @@ return cmd; } -#define JIM_DICT_SUGAR 100 +#define JIM_DICT_SUGAR 100 static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); static const Jim_ObjType variableObjType = { "variable", @@ -9751,11 +9640,11 @@ JIM_TYPE_REFERENCES, }; static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr) { - + if (nameObjPtr->typePtr != &variableObjType) { int len; const char *str = Jim_GetString(nameObjPtr, &len); if (memchr(str, '\0', len)) { Jim_SetResultFormatted(interp, "%s name contains embedded null", type); @@ -9771,18 +9660,18 @@ Jim_CallFrame *framePtr; Jim_HashEntry *he; int global; int len; - + if (objPtr->typePtr == &variableObjType) { framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr; if (objPtr->internalRep.varValue.callFrameId == framePtr->id) { - + return JIM_OK; } - + } else if (objPtr->typePtr == &dictSubstObjType) { return JIM_DICT_SUGAR; } else if (JimValidName(interp, "variable", objPtr) != JIM_OK) { @@ -9790,11 +9679,11 @@ } varName = Jim_GetString(objPtr, &len); - + if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) { return JIM_DICT_SUGAR; } if (varName[0] == ':' && varName[1] == ':') { @@ -9806,23 +9695,23 @@ else { global = 0; framePtr = interp->framePtr; } - + he = Jim_FindHashEntry(&framePtr->vars, varName); if (he == NULL) { if (!global && framePtr->staticVars) { - + he = Jim_FindHashEntry(framePtr->staticVars, varName); } if (he == NULL) { return JIM_ERR; } } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &variableObjType; objPtr->internalRep.varValue.callFrameId = framePtr->id; objPtr->internalRep.varValue.varPtr = Jim_GetHashEntryVal(he); objPtr->internalRep.varValue.global = global; @@ -9837,11 +9726,11 @@ { const char *name; Jim_CallFrame *framePtr; int global; - + Jim_Var *var = Jim_Alloc(sizeof(*var)); var->objPtr = valObjPtr; Jim_IncrRefCount(valObjPtr); var->linkFramePtr = NULL; @@ -9856,14 +9745,14 @@ else { framePtr = interp->framePtr; global = 0; } - + Jim_AddHashEntry(&framePtr->vars, name, var); - + Jim_FreeIntRep(interp, nameObjPtr); nameObjPtr->typePtr = &variableObjType; nameObjPtr->internalRep.varValue.callFrameId = framePtr->id; nameObjPtr->internalRep.varValue.varPtr = var; nameObjPtr->internalRep.varValue.global = global; @@ -9893,11 +9782,11 @@ if (var->linkFramePtr == NULL) { Jim_IncrRefCount(valObjPtr); Jim_DecrRefCount(interp, var->objPtr); var->objPtr = valObjPtr; } - else { + else { Jim_CallFrame *savedCallFrame; savedCallFrame = interp->framePtr; interp->framePtr = var->linkFramePtr; err = Jim_SetVariable(interp, var->objPtr, valObjPtr); @@ -9933,16 +9822,19 @@ return result; } int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val) { - Jim_Obj *valObjPtr; + Jim_Obj *nameObjPtr, *valObjPtr; int result; + nameObjPtr = Jim_NewStringObj(interp, name, -1); valObjPtr = Jim_NewStringObj(interp, val, -1); + Jim_IncrRefCount(nameObjPtr); Jim_IncrRefCount(valObjPtr); - result = Jim_SetVariableStr(interp, name, valObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); Jim_DecrRefCount(interp, valObjPtr); return result; } int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, @@ -9951,14 +9843,14 @@ const char *varName; const char *targetName; Jim_CallFrame *framePtr; Jim_Var *varPtr; - + switch (SetVariableFromAny(interp, nameObjPtr)) { case JIM_DICT_SUGAR: - + Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr); return JIM_ERR; case JIM_OK: varPtr = nameObjPtr->internalRep.varValue.varPtr; @@ -9966,23 +9858,23 @@ if (varPtr->linkFramePtr == NULL) { Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr); return JIM_ERR; } - + varPtr->linkFramePtr = NULL; break; } - - + + varName = Jim_String(nameObjPtr); if (varName[0] == ':' && varName[1] == ':') { while (*++varName == ':') { } - + framePtr = interp->topFramePtr; } else { framePtr = interp->framePtr; } @@ -10002,15 +9894,15 @@ nameObjPtr); Jim_DecrRefCount(interp, targetNameObjPtr); return JIM_ERR; } - + if (framePtr == targetCallFrame) { Jim_Obj *objPtr = targetNameObjPtr; - + while (1) { if (strcmp(Jim_String(objPtr), varName) == 0) { Jim_SetResultString(interp, "can't upvar from variable to itself", -1); Jim_DecrRefCount(interp, targetNameObjPtr); return JIM_ERR; @@ -10022,13 +9914,13 @@ break; objPtr = varPtr->objPtr; } } - + Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr); - + nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame; Jim_DecrRefCount(interp, targetNameObjPtr); return JIM_OK; } @@ -10042,26 +9934,26 @@ return varPtr->objPtr; } else { Jim_Obj *objPtr; - + Jim_CallFrame *savedCallFrame = interp->framePtr; interp->framePtr = varPtr->linkFramePtr; objPtr = Jim_GetVariable(interp, varPtr->objPtr, flags); interp->framePtr = savedCallFrame; if (objPtr) { return objPtr; } - + } } break; case JIM_DICT_SUGAR: - + return JimDictSugarGet(interp, nameObjPtr, flags); } if (flags & JIM_ERRMSG) { Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr); } @@ -10111,17 +10003,17 @@ int retval; Jim_CallFrame *framePtr; retval = SetVariableFromAny(interp, nameObjPtr); if (retval == JIM_DICT_SUGAR) { - + return JimDictSugarSet(interp, nameObjPtr, NULL); } else if (retval == JIM_OK) { varPtr = nameObjPtr->internalRep.varValue.varPtr; - + if (varPtr->linkFramePtr) { framePtr = interp->framePtr; interp->framePtr = varPtr->linkFramePtr; retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE); interp->framePtr = framePtr; @@ -10136,11 +10028,11 @@ framePtr = interp->framePtr; } retval = Jim_DeleteHashEntry(&framePtr->vars, name); if (retval == JIM_OK) { - + framePtr->id = interp->callFrameEpoch++; } } } if (retval != JIM_OK && (flags & JIM_ERRMSG)) { @@ -10169,11 +10061,11 @@ keyLen = (str + len) - p; if (str[len - 1] == ')') { keyLen--; } - + keyObjPtr = Jim_NewStringObj(interp, p, keyLen); Jim_IncrRefCount(varObjPtr); Jim_IncrRefCount(keyObjPtr); *varPtrPtr = varObjPtr; @@ -10188,23 +10080,23 @@ err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST); if (err == JIM_OK) { - + Jim_SetEmptyResult(interp); } else { if (!valObjPtr) { - + if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) { Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", objPtr); return err; } } - + Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", (valObjPtr ? "set" : "unset"), objPtr); } return err; } @@ -10226,11 +10118,11 @@ Jim_SetResultFormatted(interp, "can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr, ret < 0 ? "variable isn't" : "no such element in"); } else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) { - + Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr)); } return resObjPtr; } @@ -10251,27 +10143,28 @@ { Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr); Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); } -static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) { + JIM_NOTUSED(interp); - dupPtr->internalRep = srcPtr->internalRep; - - Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.varNameObjPtr); - Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr); + dupPtr->internalRep.dictSubstValue.varNameObjPtr = + srcPtr->internalRep.dictSubstValue.varNameObjPtr; + dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr; + dupPtr->typePtr = &dictSubstObjType; } static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr->typePtr != &dictSubstObjType) { Jim_Obj *varObjPtr, *keyObjPtr; if (objPtr->typePtr == &interpolatedObjType) { - + varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr; keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr; Jim_IncrRefCount(varObjPtr); @@ -10309,12 +10202,16 @@ return resObjPtr; } static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr) { - if (Jim_EvalExpression(interp, objPtr) == JIM_OK) { - return Jim_GetResult(interp); + Jim_Obj *resultObjPtr; + + if (Jim_EvalExpression(interp, objPtr, &resultObjPtr) == JIM_OK) { + + resultObjPtr->refCount--; + return resultObjPtr; } return NULL; } @@ -10352,11 +10249,11 @@ return cf; } static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) { - + if (localCommands) { Jim_Obj *cmdNameObj; while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) { Jim_HashEntry *he; @@ -10371,20 +10268,20 @@ Jim_Cmd *cmd = Jim_GetHashEntryVal(he); if (cmd->prevCmd) { Jim_Cmd *prevCmd = cmd->prevCmd; cmd->prevCmd = NULL; - + JimDecrCmdRefCount(interp, cmd); - + Jim_SetHashVal(ht, he, prevCmd); } else { Jim_DeleteHashEntry(ht, fqname); + Jim_InterpIncrProcEpoch(interp); } - Jim_InterpIncrProcEpoch(interp); } Jim_DecrRefCount(interp, cmdNameObj); JimFreeQualifiedName(interp, fqObjName); } Jim_FreeStack(localCommands); @@ -10391,59 +10288,13 @@ Jim_Free(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 + +#define JIM_FCF_FULL 0 +#define JIM_FCF_REUSE 1 static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action) { JimDeleteLocalProcs(interp, cf->localCommands); if (cf->procArgsObjPtr) @@ -10476,10 +10327,263 @@ cf->next = interp->freeFramesList; interp->freeFramesList = cf; } +#ifdef JIM_REFERENCES + +static void JimReferencesHTValDestructor(void *interp, void *val) +{ + Jim_Reference *refPtr = (void *)val; + + Jim_DecrRefCount(interp, refPtr->objPtr); + if (refPtr->finalizerCmdNamePtr != NULL) { + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + } + Jim_Free(val); +} + +static unsigned int JimReferencesHTHashFunction(const void *key) +{ + + const unsigned long *widePtr = key; + unsigned int intValue = (unsigned int)*widePtr; + + return Jim_IntHashFunction(intValue); +} + +static void *JimReferencesHTKeyDup(void *privdata, const void *key) +{ + void *copy = Jim_Alloc(sizeof(unsigned long)); + + JIM_NOTUSED(privdata); + + memcpy(copy, key, sizeof(unsigned long)); + return copy; +} + +static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + JIM_NOTUSED(privdata); + + return memcmp(key1, key2, sizeof(unsigned long)) == 0; +} + +static void JimReferencesHTKeyDestructor(void *privdata, void *key) +{ + JIM_NOTUSED(privdata); + + Jim_Free(key); +} + +static const Jim_HashTableType JimReferencesHashTableType = { + JimReferencesHTHashFunction, + JimReferencesHTKeyDup, + NULL, + JimReferencesHTKeyCompare, + JimReferencesHTKeyDestructor, + JimReferencesHTValDestructor +}; + + + +#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN) + +static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id) +{ + const char *fmt = ".%020lu>"; + + sprintf(buf, fmt, refPtr->tag, id); + return JIM_REFERENCE_SPACE; +} + +static void UpdateStringOfReference(struct Jim_Obj *objPtr); + +static const Jim_ObjType referenceObjType = { + "reference", + NULL, + NULL, + UpdateStringOfReference, + JIM_TYPE_REFERENCES, +}; + +static void UpdateStringOfReference(struct Jim_Obj *objPtr) +{ + char buf[JIM_REFERENCE_SPACE + 1]; + + JimFormatReference(buf, objPtr->internalRep.refValue.refPtr, objPtr->internalRep.refValue.id); + JimSetStringBytes(objPtr, buf); +} + +static int isrefchar(int c) +{ + return (c == '_' || isalnum(c)); +} + +static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + unsigned long value; + int i, len; + const char *str, *start, *end; + char refId[21]; + Jim_Reference *refPtr; + Jim_HashEntry *he; + char *endptr; + + + str = Jim_GetString(objPtr, &len); + + if (len < JIM_REFERENCE_SPACE) + goto badformat; + + start = str; + end = str + len - 1; + while (*start == ' ') + start++; + while (*end == ' ' && end > start) + end--; + if (end - start + 1 != JIM_REFERENCE_SPACE) + goto badformat; + + if (memcmp(start, "references, &value); + if (he == NULL) { + Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr); + return JIM_ERR; + } + refPtr = Jim_GetHashEntryVal(he); + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &referenceObjType; + objPtr->internalRep.refValue.id = value; + objPtr->internalRep.refValue.refPtr = refPtr; + return JIM_OK; + + badformat: + Jim_SetResultFormatted(interp, "expected reference but got \"%#s\"", objPtr); + return JIM_ERR; +} + +Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr) +{ + struct Jim_Reference *refPtr; + unsigned long id; + Jim_Obj *refObjPtr; + const char *tag; + int tagLen, i; + + + Jim_CollectIfNeeded(interp); + + refPtr = Jim_Alloc(sizeof(*refPtr)); + refPtr->objPtr = objPtr; + Jim_IncrRefCount(objPtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + if (cmdNamePtr) + Jim_IncrRefCount(cmdNamePtr); + id = interp->referenceNextId++; + Jim_AddHashEntry(&interp->references, &id, refPtr); + refObjPtr = Jim_NewObj(interp); + refObjPtr->typePtr = &referenceObjType; + refObjPtr->bytes = NULL; + refObjPtr->internalRep.refValue.id = id; + refObjPtr->internalRep.refValue.refPtr = refPtr; + interp->referenceNextId++; + tag = Jim_GetString(tagPtr, &tagLen); + if (tagLen > JIM_REFERENCE_TAGLEN) + tagLen = JIM_REFERENCE_TAGLEN; + for (i = 0; i < JIM_REFERENCE_TAGLEN; i++) { + if (i < tagLen && isrefchar(tag[i])) + refPtr->tag[i] = tag[i]; + else + refPtr->tag[i] = '_'; + } + refPtr->tag[JIM_REFERENCE_TAGLEN] = '\0'; + return refObjPtr; +} + +Jim_Reference *Jim_GetReference(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &referenceObjType && SetReferenceFromAny(interp, objPtr) == JIM_ERR) + return NULL; + return objPtr->internalRep.refValue.refPtr; +} + +int Jim_SetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + Jim_IncrRefCount(cmdNamePtr); + if (refPtr->finalizerCmdNamePtr) + Jim_DecrRefCount(interp, refPtr->finalizerCmdNamePtr); + refPtr->finalizerCmdNamePtr = cmdNamePtr; + return JIM_OK; +} + +int Jim_GetFinalizer(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr) +{ + Jim_Reference *refPtr; + + if ((refPtr = Jim_GetReference(interp, objPtr)) == NULL) + return JIM_ERR; + *cmdNamePtrPtr = refPtr->finalizerCmdNamePtr; + return JIM_OK; +} + + + +static const Jim_HashTableType JimRefMarkHashTableType = { + JimReferencesHTHashFunction, + JimReferencesHTKeyDup, + NULL, + JimReferencesHTKeyCompare, + JimReferencesHTKeyDestructor, + NULL +}; + + +int Jim_Collect(Jim_Interp *interp) +{ + int collected = 0; + return collected; +} + +#define JIM_COLLECT_ID_PERIOD 5000 +#define JIM_COLLECT_TIME_PERIOD 300 + +void Jim_CollectIfNeeded(Jim_Interp *interp) +{ + unsigned long elapsedId; + int elapsedTime; + + elapsedId = interp->referenceNextId - interp->lastCollectId; + elapsedTime = time(NULL) - interp->lastCollectTime; + + + if (elapsedId > JIM_COLLECT_ID_PERIOD || elapsedTime > JIM_COLLECT_TIME_PERIOD) { + Jim_Collect(interp); + } +} +#endif int Jim_IsBigEndian(void) { union { unsigned short s; @@ -10526,11 +10630,11 @@ Jim_IncrRefCount(i->nullScriptObj); Jim_IncrRefCount(i->errorProc); Jim_IncrRefCount(i->trueObj); Jim_IncrRefCount(i->falseObj); - + Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY); Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0"); Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim"); Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS); @@ -10548,14 +10652,12 @@ { Jim_CallFrame *cf, *cfx; Jim_Obj *objPtr, *nextObjPtr; - + for (cf = i->framePtr; cf; cf = cfx) { - - JimInvokeDefer(i, JIM_OK); cfx = cf->parent; JimFreeCallFrame(i, cf, JIM_FCF_FULL); } Jim_DecrRefCount(i, i->emptyObj); @@ -10582,11 +10684,10 @@ printf("\n-------------------------------------\n"); 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", (void *)objPtr, objPtr->refCount, type, objPtr->bytes); } @@ -10604,27 +10705,27 @@ printf("-------------------------------------\n\n"); JimPanic((1, "Live list non empty freeing the interpreter! Leak?")); } #endif - + objPtr = i->freeList; while (objPtr) { nextObjPtr = objPtr->nextObjPtr; Jim_Free(objPtr); objPtr = nextObjPtr; } - + for (cf = i->freeFramesList; cf; cf = cfx) { cfx = cf->next; if (cf->vars.table) Jim_FreeHashTable(&cf->vars); Jim_Free(cf); } - + Jim_Free(i); } Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) { @@ -10645,25 +10746,25 @@ else { if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) { level = -1; } else { - + level = interp->framePtr->level - level; } } } else { - str = "1"; + str = "1"; level = interp->framePtr->level - 1; } if (level == 0) { return interp->topFramePtr; } if (level > 0) { - + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { if (framePtr->level == level) { return framePtr; } } @@ -10678,19 +10779,19 @@ long level; Jim_CallFrame *framePtr; if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { if (level <= 0) { - + level = interp->framePtr->level + level; } if (level == 0) { return interp->topFramePtr; } - + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { if (framePtr->level == level) { return framePtr; } } @@ -10709,11 +10810,11 @@ static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj) { int len; - + Jim_IncrRefCount(stackTraceObj); Jim_DecrRefCount(interp, interp->stackTrace); interp->stackTrace = stackTraceObj; interp->errorFlag = 1; @@ -10730,32 +10831,32 @@ { if (strcmp(procname, "unknown") == 0) { procname = ""; } if (!*procname && !Jim_Length(fileNameObj)) { - + return; } if (Jim_IsShared(interp->stackTrace)) { Jim_DecrRefCount(interp, interp->stackTrace); interp->stackTrace = Jim_DuplicateObj(interp, interp->stackTrace); Jim_IncrRefCount(interp->stackTrace); } - + if (!*procname && Jim_Length(fileNameObj)) { - + int len = Jim_ListLength(interp, interp->stackTrace); if (len >= 3) { Jim_Obj *objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 3); if (Jim_Length(objPtr)) { - + objPtr = Jim_ListGetIndex(interp, interp->stackTrace, len - 2); if (Jim_Length(objPtr) == 0) { - + ListSetIndex(interp, interp->stackTrace, len - 2, fileNameObj, 0); ListSetIndex(interp, interp->stackTrace, len - 1, Jim_NewIntObj(interp, linenr), 0); return; } } @@ -10857,18 +10958,18 @@ { jim_wide wideValue; const char *str; if (objPtr->typePtr == &coercedDoubleObjType) { - + objPtr->typePtr = &intObjType; return JIM_OK; } - + str = Jim_String(objPtr); - + if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) { if (flags & JIM_ERRMSG) { Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr); } return JIM_ERR; @@ -10875,11 +10976,11 @@ } if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) { Jim_SetResultString(interp, "Integer value too big to be represented", -1); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &intObjType; objPtr->internalRep.wideValue = wideValue; return JIM_OK; } @@ -10974,17 +11075,17 @@ { char buf[JIM_DOUBLE_SPACE + 1]; int i; int len = sprintf(buf, "%.12g", value); - + for (i = 0; i < len; i++) { if (buf[i] == '.' || buf[i] == 'e') { #if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX) char *e = strchr(buf, 'e'); if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') { - + e += 2; memmove(e, e + 1, len - (e - buf)); } #endif break; @@ -11003,40 +11104,41 @@ { double doubleValue; jim_wide wideValue; const char *str; + str = Jim_String(objPtr); + #ifdef HAVE_LONG_LONG - + #define MIN_INT_IN_DOUBLE -(1LL << 53) #define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1) if (objPtr->typePtr == &intObjType && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) { - + objPtr->typePtr = &coercedDoubleObjType; return JIM_OK; } + else #endif - str = Jim_String(objPtr); - if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &coercedDoubleObjType; objPtr->internalRep.wideValue = wideValue; return JIM_OK; } else { - + if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); } objPtr->typePtr = &doubleObjType; objPtr->internalRep.doubleValue = doubleValue; return JIM_OK; @@ -11069,50 +11171,10 @@ objPtr->bytes = NULL; objPtr->internalRep.doubleValue = doubleValue; return objPtr; } -static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); - -int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr) -{ - if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) - return JIM_ERR; - *booleanPtr = (int) JimWideValue(objPtr); - return JIM_OK; -} - -static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) -{ - static const char * const falses[] = { - "0", "false", "no", "off", NULL - }; - static const char * const trues[] = { - "1", "true", "yes", "on", NULL - }; - - int boolean; - - int index; - if (Jim_GetEnum(interp, objPtr, falses, &index, NULL, 0) == JIM_OK) { - boolean = 0; - } else if (Jim_GetEnum(interp, objPtr, trues, &index, NULL, 0) == JIM_OK) { - boolean = 1; - } else { - if (flags & JIM_ERRMSG) { - Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr); - } - return JIM_ERR; - } - - - Jim_FreeIntRep(interp, objPtr); - objPtr->typePtr = &intObjType; - objPtr->internalRep.wideValue = boolean; - return JIM_OK; -} - static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec); static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr); static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); static void UpdateStringOfList(struct Jim_Obj *objPtr); @@ -11159,11 +11221,11 @@ #define JIM_ELESTR_QUOTE 2 static unsigned char ListElementQuotingType(const char *s, int len) { int i, level, blevel, trySimple = 1; - + if (len == 0) return JIM_ELESTR_BRACE; if (s[0] == '"' || s[0] == '{') { trySimple = 0; goto testbrace; @@ -11181,20 +11243,20 @@ case '\n': case '\t': case '\f': case '\v': trySimple = 0; - + case '{': case '}': goto testbrace; } } return JIM_ELESTR_SIMPLE; testbrace: - + if (s[len - 1] == '\\') return JIM_ELESTR_QUOTE; level = 0; blevel = 0; for (i = 0; i < len; i++) { @@ -11310,11 +11372,11 @@ int i, bufLen, realLength; const char *strRep; char *p; unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN]; - + if (objc > STATIC_QUOTING_LEN) { quotingType = Jim_Alloc(objc); } else { quotingType = staticQuoting; @@ -11329,25 +11391,25 @@ case JIM_ELESTR_SIMPLE: if (i != 0 || strRep[0] != '#') { bufLen += len; break; } - + quotingType[i] = JIM_ELESTR_BRACE; - + case JIM_ELESTR_BRACE: bufLen += len + 2; break; case JIM_ELESTR_QUOTE: bufLen += len * 2; break; } - bufLen++; + bufLen++; } bufLen++; - + p = objPtr->bytes = Jim_Alloc(bufLen + 1); realLength = 0; for (i = 0; i < objc; i++) { int len, qlen; @@ -11374,17 +11436,17 @@ qlen = BackslashQuoteString(strRep, len, p); p += qlen; realLength += qlen; break; } - + if (i + 1 != objc) { *p++ = ' '; realLength++; } } - *p = '\0'; + *p = '\0'; objPtr->length = realLength; if (quotingType != staticQuoting) { Jim_Free(quotingType); } @@ -11415,21 +11477,21 @@ listObjPtrPtr = JimDictPairs(objPtr, &len); for (i = 0; i < len; i++) { Jim_IncrRefCount(listObjPtrPtr[i]); } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &listObjType; objPtr->internalRep.listValue.len = len; objPtr->internalRep.listValue.maxLen = len; objPtr->internalRep.listValue.ele = listObjPtrPtr; return JIM_OK; } - + if (objPtr->typePtr == &sourceObjType) { fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; linenr = objPtr->internalRep.sourceValue.lineNumber; } else { @@ -11436,20 +11498,20 @@ fileNameObj = interp->emptyObj; linenr = 1; } Jim_IncrRefCount(fileNameObj); - + str = Jim_GetString(objPtr, &strLen); Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &listObjType; objPtr->internalRep.listValue.len = 0; objPtr->internalRep.listValue.maxLen = 0; objPtr->internalRep.listValue.ele = NULL; - + if (strLen) { JimParserInit(&parser, str, strLen, linenr); while (!parser.eof) { Jim_Obj *elementPtr; @@ -11579,11 +11641,11 @@ Jim_Obj *compare_script; int rc; jim_wide ret = 0; - + compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command); Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj); Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj); rc = Jim_EvalObj(sort_info->interp, compare_script); @@ -11601,27 +11663,23 @@ int dst = 0; Jim_Obj **ele = listObjPtr->internalRep.listValue.ele; for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) { if (comp(&ele[dst], &ele[src]) == 0) { - + Jim_DecrRefCount(sort_info->interp, ele[dst]); } else { - + dst++; } ele[dst] = ele[src]; } - - - dst++; - if (dst < listObjPtr->internalRep.listValue.len) { - ele[dst] = ele[src]; - } - - + + ele[++dst] = ele[src]; + + listObjPtr->internalRep.listValue.len = dst; } static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info) @@ -11635,11 +11693,11 @@ int rc; JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object")); SetListFromAny(interp, listObjPtr); - + prev_info = sort_info; sort_info = info; vector = listObjPtr->internalRep.listValue.ele; len = listObjPtr->internalRep.listValue.len; @@ -11658,17 +11716,17 @@ break; case JIM_LSORT_COMMAND: fn = ListSortCommand; break; default: - fn = NULL; + fn = NULL; JimPanic((1, "ListSort called with invalid sort type")); - return -1; + return -1; } if (info->indexed) { - + info->subfn = fn; fn = ListSortIndexHelper; } if ((rc = setjmp(info->jmpbuf)) == 0) { @@ -11692,11 +11750,11 @@ int i; Jim_Obj **point; if (requiredLen > listPtr->internalRep.listValue.maxLen) { if (requiredLen < 2) { - + requiredLen = 4; } else { requiredLen *= 2; } @@ -11878,34 +11936,34 @@ for (i = 0; i < objc; i++) ListAppendList(objPtr, objv[i]); return objPtr; } else { - + int len = 0, objLen; char *bytes, *p; - + for (i = 0; i < objc; i++) { len += Jim_Length(objv[i]); } if (objc) len += objc - 1; - + p = bytes = Jim_Alloc(len + 1); for (i = 0; i < objc; i++) { const char *s = Jim_GetString(objv[i], &objLen); - + while (objLen && isspace(UCHAR(*s))) { s++; objLen--; len--; } - + while (objLen && isspace(UCHAR(s[objLen - 1]))) { - + if (objLen > 1 && s[objLen - 2] == '\\') { break; } objLen--; len--; @@ -11932,11 +11990,11 @@ int len, rangeLen; if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK || Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK) return NULL; - len = Jim_ListLength(interp, listObjPtr); + len = Jim_ListLength(interp, listObjPtr); first = JimRelToAbsIndex(len, first); last = JimRelToAbsIndex(len, last); JimRelToAbsRange(len, &first, &last, &rangeLen); if (first == 0 && last == len) { return listObjPtr; @@ -11972,16 +12030,16 @@ { Jim_DecrRefCount(interp, (Jim_Obj *)val); } static const Jim_HashTableType JimDictHashTableType = { - JimObjectHTHashFunction, - JimObjectHTKeyValDup, - JimObjectHTKeyValDup, - JimObjectHTKeyCompare, - JimObjectHTKeyValDestructor, - JimObjectHTKeyValDestructor + JimObjectHTHashFunction, + JimObjectHTKeyValDup, + JimObjectHTKeyValDup, + JimObjectHTKeyCompare, + JimObjectHTKeyValDestructor, + JimObjectHTKeyValDestructor }; static const Jim_ObjType dictObjType = { "dict", FreeDictInternalRep, @@ -12002,17 +12060,17 @@ { Jim_HashTable *ht, *dupHt; Jim_HashTableIterator htiter; Jim_HashEntry *he; - + ht = srcPtr->internalRep.ptr; dupHt = Jim_Alloc(sizeof(*dupHt)); Jim_InitHashTable(dupHt, &JimDictHashTableType, interp); if (ht->size != 0) Jim_ExpandHashTable(dupHt, ht->size); - + JimInitHashTableIterator(ht, &htiter); while ((he = Jim_NextHashEntry(&htiter)) != NULL) { Jim_AddHashEntry(dupHt, he->key, he->u.val); } @@ -12028,11 +12086,11 @@ Jim_Obj **objv; int i; ht = dictPtr->internalRep.ptr; - + objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *)); JimInitHashTableIterator(ht, &htiter); i = 0; while ((he = Jim_NextHashEntry(&htiter)) != NULL) { objv[i++] = Jim_GetHashEntryKey(he); @@ -12042,15 +12100,15 @@ return objv; } static void UpdateStringOfDict(struct Jim_Obj *objPtr) { - + int len; Jim_Obj **objv = JimDictPairs(objPtr, &len); - + JimMakeListStringRep(objPtr, objv, len); Jim_Free(objv); } @@ -12064,18 +12122,18 @@ if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) { Jim_String(objPtr); } - + listlen = Jim_ListLength(interp, objPtr); if (listlen % 2) { Jim_SetResultString(interp, "missing value to go with key", -1); return JIM_ERR; } else { - + Jim_HashTable *ht; int i; ht = Jim_Alloc(sizeof(*ht)); Jim_InitHashTable(ht, &JimDictHashTableType, interp); @@ -12100,11 +12158,11 @@ static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) { Jim_HashTable *ht = objPtr->internalRep.ptr; - if (valueObjPtr == NULL) { + if (valueObjPtr == NULL) { return Jim_DeleteHashEntry(ht, keyObjPtr); } Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr); return JIM_OK; } @@ -12151,14 +12209,12 @@ if (flags & JIM_ERRMSG) { Jim_SetResultFormatted(interp, "key \"%#s\" not known in dictionary", keyPtr); } return JIM_ERR; } - else { - *objPtrPtr = Jim_GetHashEntryVal(he); - return JIM_OK; - } + *objPtrPtr = he->u.val; + return JIM_OK; } int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len) { @@ -12202,11 +12258,11 @@ int shared, i; varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags); if (objPtr == NULL) { if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) { - + return JIM_ERR; } varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0); if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) { Jim_FreeNewObj(interp, varObjPtr); @@ -12216,26 +12272,26 @@ if ((shared = Jim_IsShared(objPtr))) varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); for (i = 0; i < keyc; i++) { dictObjPtr = objPtr; - + if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) { goto err; } if (i == keyc - 1) { - + if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) { if (newObjPtr || (flags & JIM_MUSTEXIST)) { goto err; } } break; } - + Jim_InvalidateStringRep(dictObjPtr); if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr, newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) { if (Jim_IsShared(objPtr)) { objPtr = Jim_DuplicateObj(interp, objPtr); @@ -12248,11 +12304,11 @@ } objPtr = Jim_NewDictObj(interp, NULL, 0); DictAddElement(interp, dictObjPtr, keyv[i], objPtr); } } - + Jim_InvalidateStringRep(objPtr); Jim_InvalidateStringRep(varObjPtr); if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) { goto err; } @@ -12285,11 +12341,11 @@ char buf[JIM_INTEGER_SPACE + 1]; if (objPtr->internalRep.intValue >= 0) { sprintf(buf, "%d", objPtr->internalRep.intValue); } else { - + sprintf(buf, "end%d", objPtr->internalRep.intValue + 1); } JimSetStringBytes(objPtr, buf); } } @@ -12298,14 +12354,14 @@ { int idx, end = 0; const char *str; char *endptr; - + str = Jim_String(objPtr); - + if (strncmp(str, "end", 3) == 0) { end = 1; str += 3; idx = 0; } @@ -12316,21 +12372,21 @@ goto badindex; } str = endptr; } - + if (*str == '+' || *str == '-') { int sign = (*str == '+' ? 1 : -1); idx += sign * jim_strtol(++str, &endptr); if (str == endptr || *endptr) { goto badindex; } str = endptr; } - + while (isspace(UCHAR(*str))) { str++; } if (*str) { goto badindex; @@ -12338,19 +12394,19 @@ if (end) { if (idx > 0) { idx = INT_MAX; } else { - + idx--; } } else if (idx < 0) { idx = -INT_MAX; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &indexObjType; objPtr->internalRep.intValue = idx; return JIM_OK; @@ -12360,11 +12416,11 @@ return JIM_ERR; } int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr) { - + if (objPtr->typePtr == &intObjType) { jim_wide val = JimWideValue(objPtr); if (val < 0) *indexPtr = -INT_MAX; @@ -12392,11 +12448,11 @@ "exit", "eval", NULL }; -#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes) - 1) +#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes)) static const Jim_ObjType returnCodeObjType = { "return-code", NULL, NULL, @@ -12417,18 +12473,18 @@ static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr) { int returnCode; jim_wide wideValue; - + if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR) returnCode = (int)wideValue; else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) { Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr); return JIM_ERR; } - + Jim_FreeIntRep(interp, objPtr); objPtr->typePtr = &returnCodeObjType; objPtr->internalRep.intValue = returnCode; return JIM_OK; } @@ -12442,19 +12498,19 @@ } static int JimParseExprOperator(struct JimParserCtx *pc); static int JimParseExprNumber(struct JimParserCtx *pc); static int JimParseExprIrrational(struct JimParserCtx *pc); -static int JimParseExprBoolean(struct JimParserCtx *pc); + + enum { - - - - JIM_EXPROP_MUL = JIM_TT_EXPR_OP, + + + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, JIM_EXPROP_DIV, JIM_EXPROP_MOD, JIM_EXPROP_SUB, JIM_EXPROP_ADD, JIM_EXPROP_LSHIFT, @@ -12465,48 +12521,66 @@ JIM_EXPROP_GT, JIM_EXPROP_LTE, JIM_EXPROP_GTE, JIM_EXPROP_NUMEQ, JIM_EXPROP_NUMNE, - JIM_EXPROP_BITAND, + JIM_EXPROP_BITAND, JIM_EXPROP_BITXOR, JIM_EXPROP_BITOR, - JIM_EXPROP_LOGICAND, - JIM_EXPROP_LOGICOR, - JIM_EXPROP_TERNARY, - JIM_EXPROP_COLON, - JIM_EXPROP_POW, + + + 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, - JIM_EXPROP_STREQ, + JIM_EXPROP_STREQ, JIM_EXPROP_STRNE, JIM_EXPROP_STRIN, JIM_EXPROP_STRNI, - JIM_EXPROP_NOT, + JIM_EXPROP_NOT, JIM_EXPROP_BITNOT, JIM_EXPROP_UNARYMINUS, JIM_EXPROP_UNARYPLUS, - - JIM_EXPROP_FUNC_INT, + + JIM_EXPROP_FUNC_FIRST, + JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, JIM_EXPROP_FUNC_WIDE, JIM_EXPROP_FUNC_ABS, JIM_EXPROP_FUNC_DOUBLE, JIM_EXPROP_FUNC_ROUND, JIM_EXPROP_FUNC_RAND, JIM_EXPROP_FUNC_SRAND, - - JIM_EXPROP_FUNC_SIN, + + JIM_EXPROP_FUNC_SIN, JIM_EXPROP_FUNC_COS, JIM_EXPROP_FUNC_TAN, JIM_EXPROP_FUNC_ASIN, JIM_EXPROP_FUNC_ACOS, JIM_EXPROP_FUNC_ATAN, - JIM_EXPROP_FUNC_ATAN2, JIM_EXPROP_FUNC_SINH, JIM_EXPROP_FUNC_COSH, JIM_EXPROP_FUNC_TANH, JIM_EXPROP_FUNC_CEIL, JIM_EXPROP_FUNC_FLOOR, @@ -12513,52 +12587,52 @@ JIM_EXPROP_FUNC_EXP, JIM_EXPROP_FUNC_LOG, JIM_EXPROP_FUNC_LOG10, JIM_EXPROP_FUNC_SQRT, JIM_EXPROP_FUNC_POW, - JIM_EXPROP_FUNC_HYPOT, - JIM_EXPROP_FUNC_FMOD, }; -struct JimExprNode { - int type; - struct Jim_Obj *objPtr; - - struct JimExprNode *left; - struct JimExprNode *right; - struct JimExprNode *ternary; +struct JimExprState +{ + Jim_Obj **stack; + int stacklen; + int opcode; + int skip; }; typedef struct Jim_ExprOperator { const char *name; - int (*funcop) (Jim_Interp *interp, struct JimExprNode *opnode); + int (*funcop) (Jim_Interp *interp, struct JimExprState * e); unsigned char precedence; unsigned char arity; - unsigned char attr; + unsigned char lazy; unsigned char namelen; } Jim_ExprOperator; -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 void ExprPush(struct JimExprState *e, Jim_Obj *obj) +{ + Jim_IncrRefCount(obj); + e->stack[e->stacklen++] = obj; +} -static int JimExprOpNumUnary(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) { int intresult = 1; - int rc; + int rc = JIM_OK; + Jim_Obj *A = ExprPop(e); 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 (node->type) { + switch (e->opcode) { case JIM_EXPROP_FUNC_INT: case JIM_EXPROP_FUNC_WIDE: case JIM_EXPROP_FUNC_ROUND: case JIM_EXPROP_UNARYPLUS: wC = wA; @@ -12579,11 +12653,11 @@ default: abort(); } } else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { - switch (node->type) { + switch (e->opcode) { case JIM_EXPROP_FUNC_INT: case JIM_EXPROP_FUNC_WIDE: wC = dA; break; case JIM_EXPROP_FUNC_ROUND: @@ -12593,15 +12667,11 @@ case JIM_EXPROP_UNARYPLUS: dC = dA; intresult = 0; break; case JIM_EXPROP_FUNC_ABS: -#ifdef JIM_MATH_FUNCTIONS - dC = fabs(dA); -#else dC = dA >= 0 ? dA : -dA; -#endif intresult = 0; break; case JIM_EXPROP_UNARYMINUS: dC = -dA; intresult = 0; @@ -12614,14 +12684,14 @@ } } if (rc == JIM_OK) { if (intresult) { - Jim_SetResultInt(interp, wC); + ExprPush(e, Jim_NewIntObj(interp, wC)); } else { - Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); + ExprPush(e, Jim_NewDoubleObj(interp, dC)); } } Jim_DecrRefCount(interp, A); @@ -12634,29 +12704,24 @@ JimRandomBytes(interp, &x, sizeof(x)); return (double)x / (unsigned long)~0; } -static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprNode *node) +static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) { + Jim_Obj *A = ExprPop(e); jim_wide wA; - Jim_Obj *A; - int rc; - - if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { - return rc; - } - - rc = Jim_GetWide(interp, A, &wA); + + int rc = Jim_GetWide(interp, A, &wA); if (rc == JIM_OK) { - switch (node->type) { + switch (e->opcode) { case JIM_EXPROP_BITNOT: - Jim_SetResultInt(interp, ~wA); + ExprPush(e, Jim_NewIntObj(interp, ~wA)); break; case JIM_EXPROP_FUNC_SRAND: JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); - Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); break; default: abort(); } } @@ -12664,33 +12729,29 @@ Jim_DecrRefCount(interp, A); return rc; } -static int JimExprOpNone(Jim_Interp *interp, struct JimExprNode *node) +static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e) { - JimPanic((node->type != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); + JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); - Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); return JIM_OK; } #ifdef JIM_MATH_FUNCTIONS -static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node) +static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) { 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 (node->type) { + switch (e->opcode) { case JIM_EXPROP_FUNC_SIN: dC = sin(dA); break; case JIM_EXPROP_FUNC_COS: dC = cos(dA); @@ -12735,42 +12796,33 @@ dC = sqrt(dA); break; default: abort(); } - Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); + ExprPush(e, Jim_NewDoubleObj(interp, dC)); } Jim_DecrRefCount(interp, A); return rc; } #endif -static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprNode *node) +static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) { + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); jim_wide wA, wB; - 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; + int 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 (node->type) { + switch (e->opcode) { case JIM_EXPROP_LSHIFT: wC = wA << wB; break; case JIM_EXPROP_RSHIFT: wC = wA >> wB; @@ -12807,28 +12859,29 @@ } } break; case JIM_EXPROP_ROTL: case JIM_EXPROP_ROTR:{ - + unsigned long uA = (unsigned long)wA; unsigned long uB = (unsigned long)wB; const unsigned int S = sizeof(unsigned long) * 8; - + uB %= S; - if (node->type == JIM_EXPROP_ROTR) { + if (e->opcode == JIM_EXPROP_ROTR) { uB = S - uB; } wC = (unsigned long)(uA << uB) | (uA >> (S - uB)); break; } default: abort(); } - Jim_SetResultInt(interp, wC); + ExprPush(e, Jim_NewIntObj(interp, wC)); + } Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); @@ -12835,55 +12888,44 @@ return rc; } -static int JimExprOpBin(Jim_Interp *interp, struct JimExprNode *node) +static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) { + int intresult = 1; int rc = JIM_OK; double dA, dB, dC = 0; jim_wide wA, wB, wC = 0; - 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; - } + + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); if ((A->typePtr != &doubleObjType || A->bytes) && (B->typePtr != &doubleObjType || B->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) { + - - switch (node->type) { + switch (e->opcode) { case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: - if (wA == 0 && wB < 0) { - Jim_SetResultString(interp, "exponentiation of zero by negative power", -1); - rc = JIM_ERR; - goto done; - } wC = JimPowWide(wA, wB); - goto intresult; + break; case JIM_EXPROP_ADD: wC = wA + wB; - goto intresult; + break; case JIM_EXPROP_SUB: wC = wA - wB; - goto intresult; + break; case JIM_EXPROP_MUL: wC = wA * wB; - goto intresult; + break; case JIM_EXPROP_DIV: if (wB == 0) { Jim_SetResultString(interp, "Division by zero", -1); rc = JIM_ERR; - goto done; } else { if (wB < 0) { wB = -wB; wA = -wA; @@ -12890,67 +12932,55 @@ } wC = wA / wB; if (wA % wB < 0) { wC--; } - goto intresult; - } - case JIM_EXPROP_LT: - wC = wA < wB; - goto intresult; - case JIM_EXPROP_GT: - wC = wA > wB; - goto intresult; - case JIM_EXPROP_LTE: - wC = wA <= wB; - goto intresult; - case JIM_EXPROP_GTE: - wC = wA >= wB; - goto intresult; - case JIM_EXPROP_NUMEQ: - wC = wA == wB; - goto intresult; - case JIM_EXPROP_NUMNE: - wC = wA != wB; - goto intresult; - } - } - if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { - switch (node->type) { -#ifndef JIM_MATH_FUNCTIONS - case JIM_EXPROP_POW: - case JIM_EXPROP_FUNC_POW: - case JIM_EXPROP_FUNC_ATAN2: - case JIM_EXPROP_FUNC_HYPOT: - case JIM_EXPROP_FUNC_FMOD: - Jim_SetResultString(interp, "unsupported", -1); - rc = JIM_ERR; - goto done; -#else - case JIM_EXPROP_POW: - case JIM_EXPROP_FUNC_POW: - dC = pow(dA, dB); - goto doubleresult; - case JIM_EXPROP_FUNC_ATAN2: - dC = atan2(dA, dB); - goto doubleresult; - case JIM_EXPROP_FUNC_HYPOT: - dC = hypot(dA, dB); - goto doubleresult; - case JIM_EXPROP_FUNC_FMOD: - dC = fmod(dA, dB); - goto doubleresult; -#endif - case JIM_EXPROP_ADD: - dC = dA + dB; - goto doubleresult; - case JIM_EXPROP_SUB: - dC = dA - dB; - goto doubleresult; - case JIM_EXPROP_MUL: - dC = dA * dB; - goto doubleresult; + } + break; + case JIM_EXPROP_LT: + wC = wA < wB; + break; + case JIM_EXPROP_GT: + wC = wA > wB; + break; + case JIM_EXPROP_LTE: + wC = wA <= wB; + break; + case JIM_EXPROP_GTE: + wC = wA >= wB; + break; + case JIM_EXPROP_NUMEQ: + wC = wA == wB; + break; + case JIM_EXPROP_NUMNE: + wC = wA != wB; + break; + default: + abort(); + } + } + else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { + intresult = 0; + switch (e->opcode) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: +#ifdef JIM_MATH_FUNCTIONS + dC = pow(dA, dB); +#else + Jim_SetResultString(interp, "unsupported", -1); + rc = JIM_ERR; +#endif + break; + case JIM_EXPROP_ADD: + dC = dA + dB; + break; + case JIM_EXPROP_SUB: + dC = dA - dB; + break; + case JIM_EXPROP_MUL: + dC = dA * dB; + break; case JIM_EXPROP_DIV: if (dB == 0) { #ifdef INFINITY dC = dA < 0 ? -INFINITY : INFINITY; #else @@ -12958,70 +12988,83 @@ #endif } else { dC = dA / dB; } - goto doubleresult; + break; case JIM_EXPROP_LT: wC = dA < dB; - goto intresult; + intresult = 1; + break; case JIM_EXPROP_GT: wC = dA > dB; - goto intresult; + intresult = 1; + break; case JIM_EXPROP_LTE: wC = dA <= dB; - goto intresult; + intresult = 1; + break; case JIM_EXPROP_GTE: wC = dA >= dB; - goto intresult; + intresult = 1; + break; case JIM_EXPROP_NUMEQ: wC = dA == dB; - goto intresult; + intresult = 1; + break; case JIM_EXPROP_NUMNE: wC = dA != dB; - goto intresult; + intresult = 1; + break; + default: + abort(); } } else { + - - + int i = Jim_StringCompareObj(interp, A, B, 0); - switch (node->type) { + switch (e->opcode) { case JIM_EXPROP_LT: wC = i < 0; - goto intresult; + break; case JIM_EXPROP_GT: wC = i > 0; - goto intresult; + break; case JIM_EXPROP_LTE: wC = i <= 0; - goto intresult; + break; case JIM_EXPROP_GTE: wC = i >= 0; - goto intresult; + break; case JIM_EXPROP_NUMEQ: wC = i == 0; - goto intresult; + break; case JIM_EXPROP_NUMNE: wC = i != 0; - goto intresult; + break; + default: + rc = JIM_ERR; + break; } } - rc = JIM_ERR; -done: + if (rc == JIM_OK) { + if (intresult) { + ExprPush(e, Jim_NewIntObj(interp, wC)); + } + else { + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + } + } + Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); + return rc; -intresult: - Jim_SetResultInt(interp, wC); - goto done; -doubleresult: - Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); - goto done; } static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) { int listlen; @@ -13034,31 +13077,22 @@ } } 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 (node->type) { + + switch (e->opcode) { case JIM_EXPROP_STREQ: case JIM_EXPROP_STRNE: wC = Jim_StringEqObj(A, B); - if (node->type == JIM_EXPROP_STRNE) { + if (e->opcode == JIM_EXPROP_STRNE) { wC = !wC; } break; case JIM_EXPROP_STRIN: wC = JimSearchList(interp, B, A); @@ -13067,99 +13101,178 @@ wC = !JimSearchList(interp, B, A); break; default: abort(); } - Jim_SetResultInt(interp, wC); + ExprPush(e, Jim_NewIntObj(interp, wC)); Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); - return rc; + return JIM_OK; } 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) { - ret = (l != 0); - } - else if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { - ret = (d != 0); - } - else if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) { - ret = (b != 0); - } - - Jim_DecrRefCount(interp, obj); - return ret; -} - -static int JimExprOpAnd(Jim_Interp *interp, struct JimExprNode *node) -{ - - int result = JimExprGetTermBoolean(interp, node->left); - - if (result == 1) { - - result = JimExprGetTermBoolean(interp, node->right); - } - if (result == -1) { - return JIM_ERR; - } - Jim_SetResultInt(interp, result); - return JIM_OK; -} - -static int JimExprOpOr(Jim_Interp *interp, struct JimExprNode *node) -{ - - int result = JimExprGetTermBoolean(interp, node->left); - - if (result == 0) { - - result = JimExprGetTermBoolean(interp, node->right); - } - if (result == -1) { - return JIM_ERR; - } - Jim_SetResultInt(interp, result); - return JIM_OK; -} - -static int JimExprOpTernary(Jim_Interp *interp, struct JimExprNode *node) -{ - - int result = JimExprGetTermBoolean(interp, node->left); - - if (result == 1) { - - return JimExprEvalTermNode(interp, node->right); - } - else if (result == 0) { - - return JimExprEvalTermNode(interp, node->ternary); - } - - return JIM_ERR; + return l != 0; + } + if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { + return d != 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; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpOrLeft(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: + + break; + + case 1: + + e->skip = JimWideValue(skip); + ExprPush(e, Jim_NewIntObj(interp, 1)); + break; + + case -1: + + rc = JIM_ERR; + break; + } + 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; + } + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) +{ + 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; + + case -1: + + rc = JIM_ERR; + break; + } + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, skip); + + return rc; +} + +static int JimExprOpColonLeft(Jim_Interp *interp, struct JimExprState *e) +{ + Jim_Obj *skip = ExprPop(e); + Jim_Obj *B = ExprPop(e); + Jim_Obj *A = ExprPop(e); + + + if (ExprBool(interp, A)) { + + e->skip = JimWideValue(skip); + + ExprPush(e, B); + } + + Jim_DecrRefCount(interp, skip); + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + return JIM_OK; +} + +static int JimExprOpNull(Jim_Interp *interp, struct JimExprState *e) +{ + return JIM_OK; } enum { - OP_FUNC = 0x0001, - OP_RIGHT_ASSOC = 0x0002, + LAZY_NONE, + LAZY_OP, + LAZY_LEFT, + LAZY_RIGHT }; -#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, 0) +#define OPRINIT(N, P, A, F) {N, F, P, A, LAZY_NONE, sizeof(N) - 1} +#define OPRINIT_LAZY(N, P, A, F, L) {N, F, P, A, L, sizeof(N) - 1} static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("*", 110, 2, JimExprOpBin), OPRINIT("/", 110, 2, JimExprOpBin), OPRINIT("%", 110, 2, JimExprOpIntBin), @@ -13183,79 +13296,86 @@ OPRINIT("&", 50, 2, JimExprOpIntBin), OPRINIT("^", 49, 2, JimExprOpIntBin), OPRINIT("|", 48, 2, JimExprOpIntBin), - 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_LAZY("&&", 10, 2, NULL, LAZY_OP), + OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT), + OPRINIT_LAZY(NULL, 10, 2, JimExprOpAndOrRight, LAZY_RIGHT), + OPRINIT_LAZY("||", 9, 2, NULL, LAZY_OP), + OPRINIT_LAZY(NULL, 9, 2, JimExprOpOrLeft, LAZY_LEFT), + OPRINIT_LAZY(NULL, 9, 2, JimExprOpAndOrRight, LAZY_RIGHT), - OPRINIT_ATTR("**", 120, 2, JimExprOpBin, OP_RIGHT_ASSOC), + OPRINIT_LAZY("?", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT_LAZY(NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT), + OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), + + OPRINIT_LAZY(":", 5, 2, JimExprOpNull, LAZY_OP), + OPRINIT_LAZY(NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT), + OPRINIT_LAZY(NULL, 5, 2, JimExprOpNull, LAZY_RIGHT), + + OPRINIT("**", 250, 2, JimExprOpBin), OPRINIT("eq", 60, 2, JimExprOpStrBin), OPRINIT("ne", 60, 2, JimExprOpStrBin), OPRINIT("in", 55, 2, JimExprOpStrBin), OPRINIT("ni", 55, 2, JimExprOpStrBin), - 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("!", 150, 1, JimExprOpNumUnary), + OPRINIT("~", 150, 1, JimExprOpIntUnary), + OPRINIT(NULL, 150, 1, JimExprOpNumUnary), + OPRINIT(NULL, 150, 1, JimExprOpNumUnary), - 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), + 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), #ifdef JIM_MATH_FUNCTIONS - 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), + 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("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), #endif }; #undef OPRINIT -#undef OPRINIT_ATTR +#undef OPRINIT_LAZY #define JIM_EXPR_OPERATORS_NUM \ (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) static int JimParseExpression(struct JimParserCtx *pc) { - + while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { if (*pc->p == '\n') { pc->linenr++; } pc->p++; pc->len--; } - + pc->tline = pc->linenr; pc->tstart = pc->p; if (pc->len == 0) { pc->tend = pc->p; @@ -13281,11 +13401,11 @@ return JimParseCmd(pc); case '$': if (JimParseVar(pc) == JIM_ERR) return JimParseExprOperator(pc); else { - + if (pc->tt == JIM_TT_EXPRSUGAR) { return JIM_ERR; } return JIM_OK; } @@ -13310,18 +13430,10 @@ case 'N': case 'I': case 'n': case 'i': if (JimParseExprIrrational(pc) == JIM_ERR) - if (JimParseExprBoolean(pc) == JIM_ERR) - return JimParseExprOperator(pc); - break; - case 't': - case 'f': - case 'o': - case 'y': - if (JimParseExprBoolean(pc) == JIM_ERR) return JimParseExprOperator(pc); break; default: return JimParseExprOperator(pc); break; @@ -13331,21 +13443,21 @@ static int JimParseExprNumber(struct JimParserCtx *pc) { char *end; - + pc->tt = JIM_TT_EXPR_INT; jim_strtoull(pc->p, (char **)&pc->p); - + if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) { - if (strtod(pc->tstart, &end)) { } + if (strtod(pc->tstart, &end)) { } if (end == pc->tstart) return JIM_ERR; if (end > pc->p) { - + pc->tt = JIM_TT_EXPR_DOUBLE; pc->p = end; } } pc->tend = pc->p - 1; @@ -13370,65 +13482,35 @@ } } return JIM_ERR; } -static int JimParseExprBoolean(struct JimParserCtx *pc) -{ - const char *booleans[] = { "false", "no", "off", "true", "yes", "on", NULL }; - const int lengths[] = { 5, 2, 3, 4, 3, 2, 0 }; - int i; - - for (i = 0; booleans[i]; i++) { - const char *boolean = booleans[i]; - int length = lengths[i]; - - if (strncmp(boolean, pc->p, length) == 0) { - pc->p += length; - pc->len -= length; - pc->tend = pc->p - 1; - pc->tt = JIM_TT_EXPR_BOOLEAN; - return JIM_OK; - } - } - return JIM_ERR; -} - -static 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; - const struct Jim_ExprOperator *bestOp = NULL; - int bestLen = 0; + int bestIdx = -1, bestLen = 0; - + for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) { - const struct Jim_ExprOperator *op = &Jim_ExprOperators[i]; + const char * const opname = Jim_ExprOperators[i].name; + const int oplen = Jim_ExprOperators[i].namelen; - if (op->name[0] != pc->p[0]) { + if (opname == NULL || opname[0] != pc->p[0]) { continue; } - if (op->namelen > bestLen && strncmp(op->name, pc->p, op->namelen) == 0) { - bestOp = op; - bestLen = op->namelen; + if (oplen > bestLen && strncmp(opname, pc->p, oplen) == 0) { + bestIdx = i + JIM_TT_EXPR_OP; + bestLen = oplen; } } - if (bestOp == NULL) { + if (bestIdx == -1) { return JIM_ERR; } - - if (bestOp->attr & OP_FUNC) { + + if (bestIdx >= JIM_EXPROP_FUNC_FIRST) { const char *p = pc->p + bestLen; int len = pc->len - bestLen; while (len && isspace(UCHAR(*p))) { len--; @@ -13440,28 +13522,31 @@ } pc->tend = pc->p + bestLen - 1; pc->p += bestLen; pc->len -= bestLen; - pc->tt = (bestOp - Jim_ExprOperators) + JIM_TT_EXPR_OP; + pc->tt = bestIdx; 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] = { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT", - "DBL", "BOO", "$()" }; + "DBL", "$()" }; if (type < JIM_TT_EXPR_OP) { return tt_names[type]; } - else if (type == JIM_EXPROP_UNARYMINUS) { - return "-VE"; - } - else if (type == JIM_EXPROP_UNARYPLUS) { - return "+VE"; - } else { const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type); static char buf[20]; if (op->name) { @@ -13483,400 +13568,432 @@ NULL, JIM_TYPE_REFERENCES, }; -struct ExprTree -{ - struct JimExprNode *expr; - struct JimExprNode *nodes; - int len; - int inUse; -}; - -static void ExprTreeFreeNodes(Jim_Interp *interp, struct JimExprNode *nodes, int num) +typedef struct ExprByteCode +{ + ScriptToken *token; + int len; + int inUse; +} ExprByteCode; + +static void ExprFreeByteCode(Jim_Interp *interp, ExprByteCode * expr) { int i; - for (i = 0; i < num; i++) { - if (nodes[i].objPtr) { - Jim_DecrRefCount(interp, nodes[i].objPtr); - } - } - Jim_Free(nodes); -} - -static void ExprTreeFree(Jim_Interp *interp, struct ExprTree *expr) -{ - ExprTreeFreeNodes(interp, expr->nodes, expr->len); + + for (i = 0; i < expr->len; i++) { + Jim_DecrRefCount(interp, expr->token[i].objPtr); + } + Jim_Free(expr->token); Jim_Free(expr); } static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) { - struct ExprTree *expr = (void *)objPtr->internalRep.ptr; + ExprByteCode *expr = (void *)objPtr->internalRep.ptr; if (expr) { if (--expr->inUse != 0) { return; } - ExprTreeFree(interp, expr); + ExprFreeByteCode(interp, expr); } } static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) { JIM_NOTUSED(interp); JIM_NOTUSED(srcPtr); - + dupPtr->typePtr = NULL; } -struct ExprBuilder { - int parencount; - int level; - ParseToken *token; - ParseToken *first_token; + +static int ExprCheckCorrectness(ExprByteCode * expr) +{ + int i; + int stacklen = 0; + int ternary = 0; + + for (i = 0; i < expr->len; i++) { + ScriptToken *t = &expr->token[i]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(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_ERR; + } + return JIM_OK; +} + +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; +} + +static int ExprAddOperator(Jim_Interp *interp, ExprByteCode * expr, ParseToken *t) +{ + struct ScriptToken *token = &expr->token[expr->len]; + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(t->type); + + 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; +} + +static int ExprTernaryGetColonLeftIndex(ExprByteCode *expr, int right_index) +{ + int ternary_count = 1; + + right_index--; + + 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++; + } + else if (expr->token[right_index].type == JIM_EXPROP_COLON_LEFT && ternary_count == 1) { + return right_index; + } + 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; + } + } + else if (expr->token[i].type == JIM_EXPROP_COLON_RIGHT) { + if (ternary_count == 0) { + return 0; + } + 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; + } + + tmp = expr->token[prev_right_index]; + for (j = prev_right_index; j < i; j++) { + expr->token[j] = expr->token[j + 1]; + } + 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 *fileNameObj) +{ 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) -{ + ExprByteCode *expr; + int ok = 1; int i; - for (i = 0; i < level; i++) { - printf(" "); - } - if (TOKEN_IS_EXPR_OP(node->type)) { - printf("%s\n", jim_tt_name(node->type)); - if (node->left) { - JimShowExprNode(node->left, level + 1); - } - if (node->right) { - JimShowExprNode(node->right, level + 1); - } - if (node->ternary) { - JimShowExprNode(node->ternary, level + 1); - } - } - else { - printf("[%s] %s\n", jim_tt_name(node->type), Jim_String(node->objPtr)); - } -} -#endif - -#define EXPR_UNTIL_CLOSE 0x0001 -#define EXPR_FUNC_ARGS 0x0002 -#define EXPR_TERNARY 0x0004 - -static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms) -{ - int rc; - struct JimExprNode *node; - - int exp_stacklen = builder->stack.len + exp_numterms; - - if (builder->level++ > 200) { - Jim_SetResultString(interp, "Expression too complex", -1); - return JIM_ERR; - } - - while (builder->token->type != JIM_TT_EOL) { - ParseToken *t = builder->token++; - int prevtt; - - if (t == builder->first_token) { - prevtt = JIM_TT_NONE; - } - else { - prevtt = t[-1].type; - } - - 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; - } - builder->parencount++; - rc = ExprTreeBuildTree(interp, builder, 0, EXPR_UNTIL_CLOSE, 1); - if (rc != JIM_OK) { - return rc; - } - - } - 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) { - - break; - } - } - else if (t->type == JIM_TT_SUBEXPR_COMMA) { - if (!(flags & EXPR_FUNC_ARGS)) { - if (builder->stack.len == exp_stacklen) { - - builder->token--; - builder->level--; - return JIM_OK; - } - Jim_SetResultFormatted(interp, "unexpected comma in expression: \"%#s\"", builder->exprObjPtr); - return JIM_ERR; - } - else { - - if (builder->stack.len > exp_stacklen) { - Jim_SetResultFormatted(interp, "too many arguments to math function"); - return JIM_ERR; - } - } - - } - 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) { - - builder->token--; - builder->level--; - return JIM_OK; - } - - } - else if (TOKEN_IS_EXPR_OP(t->type)) { - const struct Jim_ExprOperator *op; - - - if (TOKEN_IS_EXPR_OP(prevtt) || TOKEN_IS_EXPR_START(prevtt)) { - if (t->type == JIM_EXPROP_SUB) { - t->type = JIM_EXPROP_UNARYMINUS; - } - else if (t->type == JIM_EXPROP_ADD) { - t->type = JIM_EXPROP_UNARYPLUS; - } - } - - op = JimExprOperatorInfoByOpcode(t->type); - - if (op->precedence < precedence || (!(op->attr & OP_RIGHT_ASSOC) && op->precedence == precedence)) { - - builder->token--; - break; - } - - 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; - } - 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); - } - else if (t->type == JIM_EXPROP_TERNARY) { - - rc = ExprTreeBuildTree(interp, builder, op->precedence, EXPR_TERNARY, 2); - } - else { - rc = ExprTreeBuildTree(interp, builder, op->precedence, 0, 1); - } - - if (rc != JIM_OK) { - return rc; - } - -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 (op->arity >= 2) { - node->right = Jim_StackPop(&builder->stack); - if (node->right == NULL) { - goto missingoperand; - } - } - 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; - - - - - if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) { - Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", builder->exprObjPtr); - return JIM_ERR; - } - - - if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) { - char *endptr; - if (t->type == JIM_TT_EXPR_INT) { - objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); - } - else { - objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); - } - if (endptr != t->token + t->len) { - - Jim_FreeNewObj(interp, objPtr); - objPtr = NULL; - } - } - - if (!objPtr) { - - objPtr = Jim_NewStringObj(interp, t->token, t->len); + 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); + + if (op->lazy == LAZY_OP) { + count += 2; + + if (t->type == JIM_EXPROP_TERNARY) { + have_ternary = 1; + } + } + } + + expr->token = Jim_Alloc(sizeof(ScriptToken) * count); + + for (i = 0; i < tokenlist->count && ok; i++) { + ParseToken *t = &tokenlist->list[i]; + + + struct ScriptToken *token = &expr->token[expr->len]; + + if (t->type == JIM_TT_EOL) { + break; + } + + switch (t->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + case JIM_TT_VAR: + case JIM_TT_DICTSUGAR: + case JIM_TT_EXPRSUGAR: + case JIM_TT_CMD: + token->type = t->type; +strexpr: + token->objPtr = Jim_NewStringObj(interp, t->token, t->len); if (t->type == JIM_TT_CMD) { - - JimSetSourceInfo(interp, objPtr, builder->fileNameObj, t->line); - } - } - - - node = builder->next++; - node->objPtr = objPtr; - Jim_IncrRefCount(node->objPtr); - node->type = t->type; - Jim_StackPush(&builder->stack, node); - } - } - - if (builder->stack.len == exp_stacklen) { - builder->level--; - return JIM_OK; - } - - 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); - } - } - else { - Jim_SetResultFormatted(interp, "extra terms after expression"); - } - } - - return JIM_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); - - rc = ExprTreeBuildTree(interp, &builder, 0, 0, 1); - - if (rc == JIM_OK) { - top = Jim_StackPop(&builder.stack); - - if (builder.parencount) { - Jim_SetResultString(interp, "missing close parenthesis", -1); - rc = JIM_ERR; - } - } - - - Jim_FreeStack(&builder.stack); - - if (rc != JIM_OK) { - ExprTreeFreeNodes(interp, builder.nodes, builder.next - builder.nodes); + + JimSetSourceInfo(interp, token->objPtr, fileNameObj, t->line); + } + expr->len++; + break; + + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + { + char *endptr; + if (t->type == JIM_TT_EXPR_INT) { + token->objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); + } + else { + token->objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); + } + if (endptr != t->token + t->len) { + + Jim_FreeNewObj(interp, token->objPtr); + token->type = JIM_TT_STR; + goto strexpr; + } + token->type = t->type; + expr->len++; + } + break; + + case JIM_TT_SUBEXPR_START: + Jim_StackPush(&stack, t); + prevtt = JIM_TT_NONE; + continue; + + case JIM_TT_SUBEXPR_COMMA: + + continue; + + case JIM_TT_SUBEXPR_END: + ok = 0; + while (Jim_StackLen(&stack)) { + ParseToken *tt = Jim_StackPop(&stack); + + if (tt->type == JIM_TT_SUBEXPR_START) { + ok = 1; + break; + } + + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + goto err; + } + } + if (!ok) { + Jim_SetResultString(interp, "Unexpected close parenthesis", -1); + goto err; + } + break; + + + default:{ + + const struct Jim_ExprOperator *op; + ParseToken *tt; + + + if (prevtt == JIM_TT_NONE || prevtt >= JIM_TT_EXPR_OP) { + if (t->type == JIM_EXPROP_SUB) { + t->type = JIM_EXPROP_UNARYMINUS; + } + else if (t->type == JIM_EXPROP_ADD) { + t->type = JIM_EXPROP_UNARYPLUS; + } + } + + op = JimExprOperatorInfoByOpcode(t->type); + + + while ((tt = Jim_StackPeek(&stack)) != NULL) { + const struct Jim_ExprOperator *tt_op = + JimExprOperatorInfoByOpcode(tt->type); + + + + if (op->arity != 1 && tt_op->precedence >= op->precedence) { + if (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + Jim_StackPop(&stack); + } + else { + break; + } + } + Jim_StackPush(&stack, t); + break; + } + } + prevtt = t->type; + } + + + 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 (ExprAddOperator(interp, expr, tt) != JIM_OK) { + ok = 0; + goto err; + } + } + + if (have_ternary) { + ExprTernaryReorderExpression(interp, expr); + } + + err: + + Jim_FreeStack(&stack); + + for (i = 0; i < expr->len; i++) { + Jim_IncrRefCount(expr->token[i].objPtr); + } + + if (!ok) { + ExprFreeByteCode(interp, expr); 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 ExprTree *expr; + struct ExprByteCode *expr; ParseTokenList tokenlist; int line; Jim_Obj *fileNameObj; int rc = JIM_ERR; - + if (objPtr->typePtr == &sourceObjType) { fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; line = objPtr->internalRep.sourceValue.lineNumber; } else { @@ -13885,17 +14002,18 @@ } Jim_IncrRefCount(fileNameObj); exprText = Jim_GetString(objPtr, &exprTextLen); - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, exprText, exprTextLen, line); while (!parser.eof) { if (JimParseExpression(&parser) != JIM_OK) { ScriptTokenListFree(&tokenlist); + invalidexpr: Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); expr = NULL; goto err; } @@ -13918,174 +14036,125 @@ ScriptTokenListFree(&tokenlist); Jim_DecrRefCount(interp, fileNameObj); return JIM_ERR; } + + expr = ExprCreateByteCode(interp, &tokenlist, fileNameObj); - expr = ExprTreeCreateTree(interp, &tokenlist, objPtr, fileNameObj); - - + ScriptTokenListFree(&tokenlist); if (!expr) { goto err; } #ifdef DEBUG_SHOW_EXPR - printf("==== Expr ====\n"); - JimShowExprNode(expr->expr, 0); + { + 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)); + } + } #endif + + if (ExprCheckCorrectness(expr) != JIM_OK) { + ExprFreeByteCode(interp, expr); + goto invalidexpr; + } + rc = JIM_OK; err: - + Jim_DecrRefCount(interp, fileNameObj); Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, expr); objPtr->typePtr = &exprObjType; return rc; } -static struct ExprTree *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) +static ExprByteCode *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) { if (objPtr->typePtr != &exprObjType) { if (SetExprFromAny(interp, objPtr) != JIM_OK) { return NULL; } } - return (struct ExprTree *) Jim_GetIntRepPtr(objPtr); + return (ExprByteCode *) Jim_GetIntRepPtr(objPtr); } #ifdef JIM_OPTIMIZATION -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); +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); else return NULL; } #endif - -static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node) -{ - 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; +#define JIM_EE_STATICSTACK_LEN 10 + +int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr, Jim_Obj **exprResultPtrPtr) +{ + ExprByteCode *expr; + Jim_Obj *staticStack[JIM_EE_STATICSTACK_LEN]; + int i; int retcode = JIM_OK; + struct JimExprState e; expr = JimGetExpression(interp, exprObjPtr); if (!expr) { - return JIM_ERR; + return JIM_ERR; } #ifdef JIM_OPTIMIZATION { Jim_Obj *objPtr; switch (expr->len) { case 1: - objPtr = JimExprIntValOrVar(interp, expr->expr); + objPtr = JimExprIntValOrVar(interp, &expr->token[0]); if (objPtr) { - Jim_SetResult(interp, objPtr); + Jim_IncrRefCount(objPtr); + *exprResultPtrPtr = objPtr; return JIM_OK; } break; case 2: - if (expr->expr->type == JIM_EXPROP_NOT) { - objPtr = JimExprIntValOrVar(interp, expr->expr->left); + if (expr->token[1].type == JIM_EXPROP_NOT) { + objPtr = JimExprIntValOrVar(interp, &expr->token[0]); if (objPtr && JimIsWide(objPtr)) { - Jim_SetResult(interp, JimWideValue(objPtr) ? interp->falseObj : interp->trueObj); + *exprResultPtrPtr = JimWideValue(objPtr) ? interp->falseObj : interp->trueObj; + Jim_IncrRefCount(*exprResultPtrPtr); return JIM_OK; } } break; case 3: - objPtr = JimExprIntValOrVar(interp, expr->expr->left); + objPtr = JimExprIntValOrVar(interp, &expr->token[0]); if (objPtr && JimIsWide(objPtr)) { - Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, expr->expr->right); + Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, &expr->token[1]); if (objPtr2 && JimIsWide(objPtr2)) { jim_wide wideValueA = JimWideValue(objPtr); jim_wide wideValueB = JimWideValue(objPtr2); int cmpRes; - switch (expr->expr->type) { + switch (expr->token[2].type) { case JIM_EXPROP_LT: cmpRes = wideValueA < wideValueB; break; case JIM_EXPROP_LTE: cmpRes = wideValueA <= wideValueB; @@ -14103,11 +14172,12 @@ cmpRes = wideValueA != wideValueB; break; default: goto noopt; } - Jim_SetResult(interp, cmpRes ? interp->trueObj : interp->falseObj); + *exprResultPtrPtr = cmpRes ? interp->trueObj : interp->falseObj; + Jim_IncrRefCount(*exprResultPtrPtr); return JIM_OK; } } break; } @@ -14115,64 +14185,145 @@ noopt: #endif expr->inUse++; + - retcode = JimExprEvalTermNode(interp, expr->expr); + 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_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; + } + } + } 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_EvalExpression(interp, exprObjPtr); - - if (retcode == JIM_OK) { - switch (ExprBool(interp, Jim_GetResult(interp))) { - case 0: - *boolPtr = 0; - break; - - case 1: - *boolPtr = 1; - break; - - case -1: - retcode = JIM_ERR; - break; - } - } - return retcode; + int retcode; + jim_wide wideValue; + double doubleValue; + Jim_Obj *exprResultPtr; + + retcode = Jim_EvalExpression(interp, exprObjPtr, &exprResultPtr); + if (retcode != JIM_OK) + return retcode; + + if (JimGetWideNoErr(interp, exprResultPtr, &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, exprResultPtr, &doubleValue) != JIM_OK) { + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_ERR; + } + else { + Jim_DecrRefCount(interp, exprResultPtr); + *boolPtr = doubleValue != 0; + return JIM_OK; + } + } + *boolPtr = wideValue != 0; + + Jim_DecrRefCount(interp, exprResultPtr); + return JIM_OK; } typedef struct ScanFmtPartDescr { - const char *arg; - const char *prefix; - size_t width; - int pos; - char type; - char modifier; + char *arg; + char *prefix; + size_t width; + int pos; + char type; + char modifier; } ScanFmtPartDescr; typedef struct ScanFmtStringObj { - jim_wide size; - char *stringRep; - size_t count; - size_t convCount; - size_t maxPos; - const char *error; - char *scratch; - ScanFmtPartDescr descr[1]; + jim_wide size; + char *stringRep; + size_t count; + size_t convCount; + size_t maxPos; + const char *error; + char *scratch; + ScanFmtPartDescr descr[1]; } ScanFmtStringObj; static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); @@ -14213,28 +14364,28 @@ static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) { ScanFmtStringObj *fmtObj; char *buffer; int maxCount, i, approxSize, lastPos = -1; - const char *fmt = Jim_String(objPtr); - int maxFmtLen = Jim_Length(objPtr); + const char *fmt = objPtr->bytes; + int maxFmtLen = objPtr->length; const char *fmtEnd = fmt + maxFmtLen; int curr; Jim_FreeIntRep(interp, objPtr); - + for (i = 0, maxCount = 0; i < maxFmtLen; ++i) if (fmt[i] == '%') ++maxCount; - - approxSize = sizeof(ScanFmtStringObj) - +(maxCount + 1) * sizeof(ScanFmtPartDescr) - +maxFmtLen * sizeof(char) + 3 + 1 - + maxFmtLen * sizeof(char) + 1 - + maxFmtLen * sizeof(char) - +(maxCount + 1) * sizeof(char) - +1; + + approxSize = sizeof(ScanFmtStringObj) + +(maxCount + 1) * sizeof(ScanFmtPartDescr) + +maxFmtLen * sizeof(char) + 3 + 1 + + maxFmtLen * sizeof(char) + 1 + + maxFmtLen * sizeof(char) + +(maxCount + 1) * sizeof(char) + +1; fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize); memset(fmtObj, 0, approxSize); fmtObj->size = approxSize; fmtObj->maxPos = 0; fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1]; @@ -14246,12 +14397,12 @@ for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) { int width = 0, skip; ScanFmtPartDescr *descr = &fmtObj->descr[curr]; fmtObj->count++; - descr->width = 0; - + descr->width = 0; + if (*fmt != '%' || fmt[1] == '%') { descr->type = 0; descr->prefix = &buffer[i]; for (; fmt < fmtEnd; ++fmt) { if (*fmt == '%') { @@ -14261,70 +14412,65 @@ } buffer[i++] = *fmt; } buffer[i++] = 0; } - + ++fmt; - + if (fmt >= fmtEnd) goto done; - descr->pos = 0; + descr->pos = 0; if (*fmt == '*') { - descr->pos = -1; + descr->pos = -1; ++fmt; } else - fmtObj->convCount++; - + fmtObj->convCount++; + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { fmt += skip; - + if (descr->pos != -1 && *fmt == '$') { int prev; ++fmt; descr->pos = width; width = 0; - + if ((lastPos == 0 && descr->pos > 0) || (lastPos > 0 && descr->pos == 0)) { fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers"; return JIM_ERR; } - + for (prev = 0; prev < curr; ++prev) { if (fmtObj->descr[prev].pos == -1) continue; if (fmtObj->descr[prev].pos == descr->pos) { fmtObj->error = "variable is assigned by multiple \"%n$\" conversion specifiers"; 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; fmt += skip; } if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos) fmtObj->maxPos = descr->pos; } else { - + descr->width = width; } } - + if (lastPos == -1) lastPos = descr->pos; - + if (*fmt == '[') { int swapped = 1, beg = i, end, j; descr->type = '['; descr->arg = &buffer[i]; @@ -14339,11 +14485,11 @@ fmtObj->error = "unmatched [ in format string"; return JIM_ERR; } end = i; buffer[i++] = 0; - + while (swapped) { swapped = 0; for (j = beg + 1; j < end - 1; ++j) { if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) { char tmp = buffer[j - 1]; @@ -14354,19 +14500,14 @@ } } } } else { - - if (fmt < fmtEnd && strchr("hlL", *fmt)) + + if (strchr("hlL", *fmt) != 0) 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"; return JIM_ERR; } @@ -14402,11 +14543,11 @@ while (*str) { int c; int n; if (!sdescr && isspace(UCHAR(*str))) - break; + break; n = utf8_tounicode(str, &c); if (sdescr && !JimCharsetMatch(sdescr, c, JIM_CHARSET_SCAN)) break; while (n--) @@ -14425,89 +14566,89 @@ size_t scanned = 0; size_t anchor = pos; int i; Jim_Obj *tmpObj = NULL; - + *valObjPtr = 0; if (descr->prefix) { for (i = 0; pos < strLen && descr->prefix[i]; ++i) { - + if (isspace(UCHAR(descr->prefix[i]))) while (pos < strLen && isspace(UCHAR(str[pos]))) ++pos; else if (descr->prefix[i] != str[pos]) - break; + break; else - ++pos; + ++pos; } if (pos >= strLen) { - return -1; + return -1; } else if (descr->prefix[i] != 0) - return 0; + return 0; } - + if (descr->type != 'c' && descr->type != '[' && descr->type != 'n') while (isspace(UCHAR(str[pos]))) ++pos; - + scanned = pos - anchor; - + if (descr->type == 'n') { - + *valObjPtr = Jim_NewIntObj(interp, anchor + scanned); } else if (pos >= strLen) { - + return -1; } else if (descr->type == 'c') { int c; scanned += utf8_tounicode(&str[pos], &c); *valObjPtr = Jim_NewIntObj(interp, c); return scanned; } else { - + if (descr->width > 0) { size_t sLen = utf8_strlen(&str[pos], strLen - pos); size_t tLen = descr->width > sLen ? sLen : descr->width; tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen); tok = tmpObj->bytes; } else { - + tok = &str[pos]; } switch (descr->type) { case 'd': case 'o': case 'x': case 'u': case 'i':{ - char *endp; + char *endp; jim_wide w; int base = descr->type == 'o' ? 8 : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10; - + if (base == 0) { w = jim_strtoull(tok, &endp); } else { w = strtoull(tok, &endp, base); } if (endp != tok) { - + *valObjPtr = Jim_NewIntObj(interp, w); - + scanned += endp - tok; } else { scanned = *tok ? 0 : -1; } @@ -14524,13 +14665,13 @@ case 'g':{ char *endp; double value = strtod(tok, &endp); if (endp != tok) { - + *valObjPtr = Jim_NewDoubleObj(interp, value); - + scanned += endp - tok; } else { scanned = *tok ? 0 : -1; } @@ -14555,65 +14696,65 @@ Jim_Obj **resultVec = 0; int resultc; Jim_Obj *emptyStr = 0; ScanFmtStringObj *fmtObj; - + JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format")); fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr; - + if (fmtObj->error != 0) { if (flags & JIM_ERRMSG) Jim_SetResultString(interp, fmtObj->error, -1); return 0; } - + emptyStr = Jim_NewEmptyStringObj(interp); Jim_IncrRefCount(emptyStr); - + resultList = Jim_NewListObj(interp, NULL, 0); if (fmtObj->maxPos > 0) { for (i = 0; i < fmtObj->maxPos; ++i) Jim_ListAppendElement(interp, resultList, emptyStr); JimListGetElements(interp, resultList, &resultc, &resultVec); } - + for (i = 0, pos = 0; i < fmtObj->count; ++i) { ScanFmtPartDescr *descr = &(fmtObj->descr[i]); Jim_Obj *value = 0; - + if (descr->type == 0) continue; - + if (scanned > 0) scanned = ScanOneEntry(interp, str, pos, strLen, fmtObj, i, &value); - + if (scanned == -1 && i == 0) goto eof; - + pos += scanned; - + if (value == 0) value = Jim_NewEmptyStringObj(interp); - + if (descr->pos == -1) { Jim_FreeNewObj(interp, value); } else if (descr->pos == 0) - + Jim_ListAppendElement(interp, resultList, value); else if (resultVec[descr->pos - 1] == emptyStr) { - + Jim_DecrRefCount(interp, resultVec[descr->pos - 1]); Jim_IncrRefCount(value); resultVec[descr->pos - 1] = value; } else { - + Jim_FreeNewObj(interp, value); goto err; } } Jim_DecrRefCount(interp, emptyStr); @@ -14651,15 +14792,15 @@ { Jim_PrngState *prng; unsigned char *destByte = (unsigned char *)dest; unsigned int si, sj, x; - + if (interp->prngState == NULL) JimPrngInit(interp); prng = interp->prngState; - + for (x = 0; x < len; x++) { prng->i = (prng->i + 1) & 0xff; si = prng->sbox[prng->i]; prng->j = (prng->j + si) & 0xff; sj = prng->sbox[prng->j]; @@ -14673,19 +14814,19 @@ static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen) { int i; Jim_PrngState *prng; - + if (interp->prngState == NULL) JimPrngInit(interp); prng = interp->prngState; - + for (i = 0; i < 256; i++) prng->sbox[i] = i; - + for (i = 0; i < seedLen; i++) { unsigned char t; t = prng->sbox[i & 0xFF]; prng->sbox[i & 0xFF] = prng->sbox[seed[i]]; @@ -14712,11 +14853,11 @@ if (Jim_GetWide(interp, argv[2], &increment) != JIM_OK) return JIM_ERR; } intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!intObjPtr) { - + wideValue = 0; } else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) { return JIM_ERR; } @@ -14726,26 +14867,26 @@ Jim_FreeNewObj(interp, intObjPtr); return JIM_ERR; } } else { - + Jim_InvalidateStringRep(intObjPtr); JimWideValue(intObjPtr) = wideValue + increment; if (argv[1]->typePtr != &variableObjType) { - + Jim_SetVariable(interp, argv[1], intObjPtr); } } Jim_SetResult(interp, intObjPtr); return JIM_OK; } -#define JIM_EVAL_SARGV_LEN 8 -#define JIM_EVAL_SINTV_LEN 8 +#define JIM_EVAL_SARGV_LEN 8 +#define JIM_EVAL_SINTV_LEN 8 static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int retcode; @@ -14753,16 +14894,16 @@ if (interp->unknown_called > 50) { return JIM_ERR; } - + if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL) return JIM_ERR; interp->unknown_called++; - + retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv); interp->unknown_called--; return retcode; } @@ -14769,11 +14910,10 @@ static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { int retcode; Jim_Cmd *cmdPtr; - void *prevPrivData; #if 0 printf("invoke"); int j; for (j = 0; j < objc; j++) { @@ -14781,11 +14921,11 @@ } printf("\n"); #endif if (interp->framePtr->tailcallCmd) { - + cmdPtr = interp->framePtr->tailcallCmd; interp->framePtr->tailcallCmd = NULL; } else { cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG); @@ -14799,22 +14939,20 @@ Jim_SetResultString(interp, "Infinite eval recursion", -1); retcode = JIM_ERR; goto out; } interp->evalDepth++; - prevPrivData = interp->cmdPrivData; - + Jim_SetEmptyResult(interp); if (cmdPtr->isproc) { retcode = JimCallProcedure(interp, cmdPtr, objc, objv); } else { interp->cmdPrivData = cmdPtr->u.native.privData; retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); } - interp->cmdPrivData = prevPrivData; interp->evalDepth--; out: JimDecrCmdRefCount(interp, cmdPtr); @@ -14823,17 +14961,17 @@ int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv) { int i, retcode; - + for (i = 0; i < objc; i++) Jim_IncrRefCount(objv[i]); retcode = JimInvokeCommand(interp, objc, objv); - + for (i = 0; i < objc; i++) Jim_DecrRefCount(interp, objv[i]); return retcode; } @@ -14851,25 +14989,25 @@ } static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script) { if (!interp->errorFlag) { - + interp->errorFlag = 1; Jim_IncrRefCount(script->fileNameObj); Jim_DecrRefCount(interp, interp->errorFileNameObj); interp->errorFileNameObj = script->fileNameObj; interp->errorLine = script->linenr; JimResetStackTrace(interp); - + interp->addStackTrace++; } - + if (interp->addStackTrace > 0) { - + JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); if (Jim_Length(script->fileNameObj)) { interp->addStackTrace = 0; @@ -14904,14 +15042,14 @@ case JIM_OK: case JIM_RETURN: objPtr = interp->result; break; case JIM_BREAK: - + return JIM_BREAK; case JIM_CONTINUE: - + return JIM_CONTINUE; default: return JIM_ERR; } break; @@ -14946,23 +15084,23 @@ case JIM_OK: case JIM_RETURN: break; case JIM_BREAK: if (flags & JIM_SUBST_FLAG) { - + tokens = i; continue; } - - + + case JIM_CONTINUE: if (flags & JIM_SUBST_FLAG) { intv[i] = NULL; continue; } - - + + default: while (i--) { Jim_DecrRefCount(interp, intv[i]); } if (intv != sintv) { @@ -14973,29 +15111,28 @@ Jim_IncrRefCount(intv[i]); Jim_String(intv[i]); totlen += intv[i]->length; } - + if (tokens == 1 && intv[0] && intv == sintv) { - - intv[0]->refCount--; + Jim_DecrRefCount(interp, intv[0]); return intv[0]; } objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0); if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC && token[2].type == JIM_TT_VAR) { - + objPtr->typePtr = &interpolatedObjType; objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr; objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; Jim_IncrRefCount(intv[2]); } else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) { - + JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber); } s = objPtr->bytes = Jim_Alloc(totlen + 1); @@ -15006,11 +15143,11 @@ s += intv[i]->length; Jim_DecrRefCount(interp, intv[i]); } } objPtr->bytes[totlen] = '\0'; - + if (intv != sintv) { Jim_Free(intv); } return objPtr; @@ -15050,11 +15187,11 @@ if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { return JimEvalObjList(interp, scriptObjPtr); } - Jim_IncrRefCount(scriptObjPtr); + Jim_IncrRefCount(scriptObjPtr); script = JimGetScript(interp, scriptObjPtr); if (!JimScriptValid(interp, script)) { Jim_DecrRefCount(interp, scriptObjPtr); return JIM_ERR; } @@ -15086,11 +15223,11 @@ } #endif script->inUse++; - + prevScriptObj = interp->currentScriptObj; interp->currentScriptObj = scriptObjPtr; interp->errorFlag = 0; argv = sargv; @@ -15097,19 +15234,19 @@ for (i = 0; i < script->len && retcode == JIM_OK; ) { int argc; int j; - + argc = token[i].objPtr->internalRep.scriptLineValue.argc; script->linenr = token[i].objPtr->internalRep.scriptLineValue.line; - + if (argc > JIM_EVAL_SARGV_LEN) argv = Jim_Alloc(sizeof(Jim_Obj *) * argc); - + i++; for (j = 0; j < argc; j++) { long wordtokens = 1; int expand = 0; @@ -15165,11 +15302,11 @@ if (!expand) { argv[j] = wordObjPtr; } else { - + int len = Jim_ListLength(interp, wordObjPtr); int newargc = argc + len - 1; int k; if (len > 1) { @@ -15178,39 +15315,39 @@ argv = Jim_Alloc(sizeof(*argv) * newargc); memcpy(argv, sargv, sizeof(*argv) * j); } } else { - + argv = Jim_Realloc(argv, sizeof(*argv) * newargc); } } - + for (k = 0; k < len; k++) { argv[j++] = wordObjPtr->internalRep.listValue.ele[k]; Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]); } Jim_DecrRefCount(interp, wordObjPtr); - + j--; argc += len - 1; } } if (retcode == JIM_OK && argc) { - + retcode = JimInvokeCommand(interp, argc, argv); - + if (Jim_CheckSignal(interp)) { retcode = JIM_SIGNAL; } } - + while (j-- > 0) { Jim_DecrRefCount(interp, argv[j]); } if (argv != sargv) { @@ -15217,21 +15354,21 @@ Jim_Free(argv); argv = sargv; } } - + if (retcode == JIM_ERR) { JimAddErrorToStack(interp, script); } - + else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) { - + interp->addStackTrace = 0; } - + interp->currentScriptObj = prevScriptObj; Jim_FreeIntRep(interp, scriptObjPtr); scriptObjPtr->typePtr = &scriptObjType; Jim_SetIntRepPtr(scriptObjPtr, script); @@ -15241,14 +15378,14 @@ } static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj) { int retcode; - + const char *varname = Jim_String(argNameObj); if (*varname == '&') { - + Jim_Obj *objPtr; Jim_CallFrame *savedCallFrame = interp->framePtr; interp->framePtr = interp->framePtr->parent; objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG); @@ -15255,11 +15392,11 @@ interp->framePtr = savedCallFrame; if (!objPtr) { return JIM_ERR; } - + objPtr = Jim_NewStringObj(interp, varname + 1, -1); Jim_IncrRefCount(objPtr); retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent); Jim_DecrRefCount(interp, objPtr); } @@ -15269,26 +15406,26 @@ return retcode; } static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) { - + Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); int i; for (i = 0; i < cmd->u.proc.argListLen; i++) { Jim_AppendString(interp, argmsg, " ", 1); if (i == cmd->u.proc.argsPos) { if (cmd->u.proc.arglist[i].defaultObjPtr) { - + Jim_AppendString(interp, argmsg, "?", 1); Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); Jim_AppendString(interp, argmsg, " ...?", -1); } else { - + Jim_AppendString(interp, argmsg, "?arg...?", -1); } } else { if (cmd->u.proc.arglist[i].defaultObjPtr) { @@ -15304,19 +15441,20 @@ Jim_AppendString(interp, argmsg, arg, -1); } } } Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); + Jim_FreeNewObj(interp, argmsg); } #ifdef jim_ext_namespace int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) { Jim_CallFrame *callFramePtr; int retcode; - + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj); callFramePtr->argv = &interp->emptyObj; callFramePtr->argc = 0; callFramePtr->procArgsObjPtr = NULL; callFramePtr->procBodyObjPtr = scriptObj; @@ -15324,21 +15462,21 @@ callFramePtr->fileNameObj = interp->emptyObj; callFramePtr->line = 0; Jim_IncrRefCount(scriptObj); interp->framePtr = callFramePtr; - + if (interp->framePtr->level == interp->maxCallFrameDepth) { Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); retcode = JIM_ERR; } else { - + retcode = Jim_EvalObj(interp, scriptObj); } - + interp->framePtr = interp->framePtr->parent; JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); return retcode; } @@ -15348,62 +15486,62 @@ { Jim_CallFrame *callFramePtr; int i, d, retcode, optargs; ScriptObj *script; - + if (argc - 1 < cmd->u.proc.reqArity || (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) { JimSetProcWrongArgs(interp, argv[0], cmd); return JIM_ERR; } if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) { - + return JIM_OK; } - + if (interp->framePtr->level == interp->maxCallFrameDepth) { Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); return JIM_ERR; } - + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj); callFramePtr->argv = argv; callFramePtr->argc = argc; callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; callFramePtr->staticVars = cmd->u.proc.staticVars; - + script = JimGetScript(interp, interp->currentScriptObj); callFramePtr->fileNameObj = script->fileNameObj; callFramePtr->line = script->linenr; Jim_IncrRefCount(cmd->u.proc.argListObjPtr); Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); interp->framePtr = callFramePtr; - + optargs = (argc - 1 - cmd->u.proc.reqArity); - + i = 1; for (d = 0; d < cmd->u.proc.argListLen; d++) { Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr; if (d == cmd->u.proc.argsPos) { - + Jim_Obj *listObjPtr; int argsLen = 0; if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) { argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity); } listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen); - + if (cmd->u.proc.arglist[d].defaultObjPtr) { nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr; } retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr); if (retcode != JIM_OK) { @@ -15412,34 +15550,33 @@ i += argsLen; continue; } - + if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) { retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]); } else { - + retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr); } if (retcode != JIM_OK) { goto badargset; } } - + retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr); badargset: - - retcode = JimInvokeDefer(interp, retcode); + interp->framePtr = interp->framePtr->parent; JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); - + if (interp->framePtr->tailcallObj) { do { Jim_Obj *tailcallObj = interp->framePtr->tailcallObj; interp->framePtr->tailcallObj = NULL; @@ -15451,18 +15588,18 @@ } } Jim_DecrRefCount(interp, tailcallObj); } while (interp->framePtr->tailcallObj); - + if (interp->framePtr->tailcallCmd) { JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd); interp->framePtr->tailcallCmd = NULL; } } - + if (retcode == JIM_RETURN) { if (--interp->returnLevel <= 0) { retcode = interp->returnCode; interp->returnCode = JIM_OK; interp->returnLevel = 0; @@ -15574,20 +15711,20 @@ prevScriptObj = interp->currentScriptObj; interp->currentScriptObj = scriptObjPtr; retcode = Jim_EvalObj(interp, scriptObjPtr); - + if (retcode == JIM_RETURN) { if (--interp->returnLevel <= 0) { retcode = interp->returnCode; interp->returnCode = JIM_OK; interp->returnLevel = 0; } } if (retcode == JIM_ERR) { - + interp->addStackTrace++; } interp->currentScriptObj = prevScriptObj; @@ -15613,11 +15750,11 @@ } if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { if (JimParseVar(pc) == JIM_OK) { return; } - + pc->tstart = pc->p; flags |= JIM_SUBST_NOVAR; } while (pc->len) { if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { @@ -15644,32 +15781,32 @@ const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); struct JimParserCtx parser; struct ScriptObj *script = Jim_Alloc(sizeof(*script)); ParseTokenList tokenlist; - + ScriptTokenListInit(&tokenlist); JimParserInit(&parser, scriptText, scriptTextLen, 1); while (1) { JimParseSubst(&parser, flags); if (parser.eof) { - + break; } ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, parser.tline); } - + script->inUse = 1; script->substFlags = flags; script->fileNameObj = interp->emptyObj; Jim_IncrRefCount(script->fileNameObj); SubstObjAddTokens(interp, script, &tokenlist); - + ScriptTokenListFree(&tokenlist); #ifdef DEBUG_SHOW_SUBST { int i; @@ -15680,11 +15817,11 @@ Jim_String(script->token[i].objPtr)); } } #endif - + Jim_FreeIntRep(interp, objPtr); Jim_SetIntRepPtr(objPtr, script); objPtr->typePtr = &scriptObjType; return JIM_OK; } @@ -15698,11 +15835,11 @@ int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags) { ScriptObj *script = Jim_GetSubst(interp, substObjPtr, flags); - Jim_IncrRefCount(substObjPtr); + Jim_IncrRefCount(substObjPtr); script->inUse++; *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags); script->inUse--; @@ -15714,24 +15851,22 @@ } void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) { Jim_Obj *objPtr; - Jim_Obj *listObjPtr; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc); - JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0")); - - listObjPtr = Jim_NewListObj(interp, argv, argc); - - if (msg && *msg) { + if (*msg) { Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); } Jim_IncrRefCount(listObjPtr); objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1); Jim_DecrRefCount(interp, listObjPtr); + Jim_IncrRefCount(objPtr); Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr); + Jim_DecrRefCount(interp, objPtr); } typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type); @@ -15741,11 +15876,11 @@ JimHashtableIteratorCallbackType *callback, int type) { Jim_HashEntry *he; Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); - + if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) { he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr)); if (he) { callback(interp, listObjPtr, he, type); } @@ -15772,11 +15907,11 @@ { Jim_Cmd *cmdPtr = Jim_GetHashEntryVal(he); Jim_Obj *objPtr; if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { - + return; } objPtr = Jim_NewStringObj(interp, he->key, -1); Jim_IncrRefCount(objPtr); @@ -15832,11 +15967,11 @@ targetCallFrame = JimGetCallFrameByInteger(interp, levelObjPtr); if (targetCallFrame == NULL) { return JIM_ERR; } - + if (targetCallFrame == interp->topFramePtr) { Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); return JIM_ERR; } if (info_level_cmd) { @@ -15960,17 +16095,12 @@ doubleRes = (double)res; goto trydouble; } if (op == JIM_EXPROP_SUB) res -= wideValue; - else { - if (wideValue == 0) { - Jim_SetResultString(interp, "Division by zero", -1); - return JIM_ERR; - } + else res /= wideValue; - } } Jim_SetResultInt(interp, res); return JIM_OK; trydouble: for (; i < argc; i++) { @@ -16024,11 +16154,11 @@ if (!objPtr) return JIM_ERR; Jim_SetResult(interp, objPtr); return JIM_OK; } - + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) return JIM_ERR; Jim_SetResult(interp, argv[2]); return JIM_OK; } @@ -16067,11 +16197,11 @@ if (argc != 3) { Jim_WrongNumArgs(interp, 1, argv, "condition body"); return JIM_ERR; } - + while (1) { int boolean, retval; if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK) return retval; @@ -16107,11 +16237,11 @@ if (argc != 5) { Jim_WrongNumArgs(interp, 1, argv, "start test next body"); return JIM_ERR; } - + if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { return retval; } retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); @@ -16118,84 +16248,78 @@ #ifdef JIM_OPTIMIZATION if (retval == JIM_OK && boolean) { ScriptObj *incrScript; - struct ExprTree *expr; + ExprByteCode *expr; jim_wide stop, currentVal; Jim_Obj *objPtr; int cmpOffset; - + expr = JimGetExpression(interp, argv[2]); incrScript = JimGetScript(interp, argv[3]); - + if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { goto evalstart; } - - if (incrScript->token[1].type != JIM_TT_ESC) { + + 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)) { goto evalstart; } - if (expr->expr->type == JIM_EXPROP_LT) { + if (expr->token[2].type == JIM_EXPROP_LT) { cmpOffset = 0; } - else if (expr->expr->type == JIM_EXPROP_LTE) { + else if (expr->token[2].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->expr->left->objPtr)) { + + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->token[0].objPtr)) { goto evalstart; } - - if (expr->expr->right->type == JIM_TT_EXPR_INT) { - if (Jim_GetWide(interp, expr->expr->right->objPtr, &stop) == JIM_ERR) { + + if (expr->token[1].type == JIM_TT_EXPR_INT) { + if (Jim_GetWide(interp, expr->token[1].objPtr, &stop) == JIM_ERR) { goto evalstart; } } else { - stopVarNamePtr = expr->expr->right->objPtr; + stopVarNamePtr = expr->token[1].objPtr; Jim_IncrRefCount(stopVarNamePtr); - + stop = 0; } - - varNamePtr = expr->expr->left->objPtr; + + varNamePtr = expr->token[0].objPtr; Jim_IncrRefCount(varNamePtr); objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE); if (objPtr == NULL || Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK) { goto testcond; } - + while (retval == JIM_OK) { + + - - - + if (stopVarNamePtr) { objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE); if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) { goto testcond; } @@ -16203,18 +16327,18 @@ if (currentVal >= stop + cmpOffset) { break; } - + retval = Jim_EvalObj(interp, argv[4]); if (retval == JIM_OK || retval == JIM_CONTINUE) { retval = JIM_OK; objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG); - + if (objPtr == NULL) { retval = JIM_ERR; goto out; } if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { @@ -16234,25 +16358,25 @@ } evalstart: #endif while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { - + retval = Jim_EvalObj(interp, argv[4]); if (retval == JIM_OK || retval == JIM_CONTINUE) { - -JIM_IF_OPTIM(evalnext:) + + evalnext: retval = Jim_EvalObj(interp, argv[3]); if (retval == JIM_OK || retval == JIM_CONTINUE) { - -JIM_IF_OPTIM(testcond:) + + testcond: retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); } } } -JIM_IF_OPTIM(out:) + out: if (stopVarNamePtr) { Jim_DecrRefCount(interp, stopVarNamePtr); } if (varNamePtr) { Jim_DecrRefCount(interp, varNamePtr); @@ -16294,11 +16418,11 @@ if (retval == JIM_OK || retval == JIM_CONTINUE) { Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); retval = JIM_OK; - + i += incr; if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { if (argv[1]->typePtr != &variableObjType) { if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { @@ -16359,21 +16483,21 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap) { int result = JIM_OK; int i, numargs; - Jim_ListIter twoiters[2]; + Jim_ListIter twoiters[2]; Jim_ListIter *iters; Jim_Obj *script; Jim_Obj *resultObj; if (argc < 4 || argc % 2 != 0) { Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); return JIM_ERR; } - script = argv[argc - 1]; - numargs = (argc - 1 - 1); + script = argv[argc - 1]; + numargs = (argc - 1 - 1); if (numargs == 2) { iters = twoiters; } else { @@ -16385,11 +16509,11 @@ result = JIM_ERR; } } if (result != JIM_OK) { Jim_SetResultString(interp, "foreach varlist is empty", -1); - goto empty_varlist; + return result; } if (doMap) { resultObj = Jim_NewListObj(interp, NULL, 0); } @@ -16397,34 +16521,34 @@ resultObj = interp->emptyObj; } Jim_IncrRefCount(resultObj); while (1) { - + for (i = 0; i < numargs; i += 2) { if (!JimListIterDone(interp, &iters[i + 1])) { break; } } if (i == numargs) { - + break; } - + for (i = 0; i < numargs; i += 2) { Jim_Obj *varName; - + JimListIterInit(&iters[i], argv[i + 1]); while ((varName = JimListIterNext(interp, &iters[i])) != NULL) { Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]); if (!valObj) { - + valObj = interp->emptyObj; } - + Jim_IncrRefCount(valObj); result = Jim_SetVariable(interp, varName, valObj); Jim_DecrRefCount(interp, valObj); if (result != JIM_OK) { goto err; @@ -16448,11 +16572,10 @@ out: result = JIM_OK; Jim_SetResult(interp, resultObj); err: Jim_DecrRefCount(interp, resultObj); - empty_varlist: if (numargs > 2) { Jim_Free(iters); } return result; } @@ -16507,41 +16630,41 @@ { int boolean, retval, current = 1, falsebody = 0; if (argc >= 3) { while (1) { - + if (current >= argc) goto err; if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) != JIM_OK) return retval; - + if (current >= argc) goto err; if (Jim_CompareStringImmediate(interp, argv[current], "then")) current++; - + if (current >= argc) goto err; if (boolean) return Jim_EvalObj(interp, argv[current]); - + if (++current >= argc) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); return JIM_OK; } falsebody = current++; if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { - + if (current != argc - 1) goto err; return Jim_EvalObj(interp, argv[current]); } else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) continue; - + else if (falsebody != argc - 1) goto err; return Jim_EvalObj(interp, argv[falsebody]); } return JIM_OK; @@ -16575,17 +16698,19 @@ } 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 = NULL, *scriptObj = NULL, *strObj; - Jim_Obj **caseList; + Jim_Obj *command = 0, *const *caseList = 0, *strObj; + Jim_Obj *script = 0; if (argc < 3) { wrongnumargs: Jim_WrongNumArgs(interp, 1, argv, "?options? string " "pattern body ... ?default body? or " "{pattern body ?pattern body ...?}"); @@ -16622,62 +16747,68 @@ goto wrongnumargs; } strObj = argv[opt++]; patCount = argc - opt; if (patCount == 1) { - JimListGetElements(interp, argv[opt], &patCount, &caseList); + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; } else - caseList = (Jim_Obj **)&argv[opt]; + caseList = &argv[opt]; if (patCount == 0 || patCount % 2 != 0) goto wrongnumargs; - for (i = 0; scriptObj == NULL && i < patCount; i += 2) { + for (i = 0; script == 0 && i < patCount; i += 2) { Jim_Obj *patObj = caseList[i]; if (!Jim_CompareStringImmediate(interp, patObj, "default") || i < (patCount - 2)) { switch (matchOpt) { case SWITCH_EXACT: if (Jim_StringEqObj(strObj, patObj)) - scriptObj = caseList[i + 1]; + script = caseList[i + 1]; break; case SWITCH_GLOB: if (Jim_StringMatchObj(interp, patObj, strObj, 0)) - scriptObj = caseList[i + 1]; + script = caseList[i + 1]; break; case SWITCH_RE: command = Jim_NewStringObj(interp, "regexp", -1); - + case SWITCH_CMD:{ int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0); if (argc - opt == 1) { - JimListGetElements(interp, argv[opt], &patCount, &caseList); + Jim_Obj **vector; + + JimListGetElements(interp, argv[opt], &patCount, &vector); + caseList = vector; } - + if (rc < 0) { return -rc; } if (rc) - scriptObj = caseList[i + 1]; + script = caseList[i + 1]; break; } } } else { - scriptObj = caseList[i + 1]; + script = caseList[i + 1]; } } - for (; i < patCount && Jim_CompareStringImmediate(interp, scriptObj, "-"); i += 2) - scriptObj = caseList[i + 1]; - if (scriptObj && Jim_CompareStringImmediate(interp, scriptObj, "-")) { + for (; i < patCount && Jim_CompareStringImmediate(interp, script, "-"); i += 2) + script = caseList[i + 1]; + if (script && Jim_CompareStringImmediate(interp, script, "-")) { Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]); return JIM_ERR; } Jim_SetEmptyResult(interp); - if (scriptObj) { - return Jim_EvalObj(interp, scriptObj); + if (script) { + return Jim_EvalObj(interp, script); } return JIM_OK; } @@ -16789,11 +16920,11 @@ case OPT_COMMAND: if (i >= argc - 2) { goto wrongargs; } commandObj = argv[++i]; - + case OPT_EXACT: case OPT_GLOB: case OPT_REGEXP: opt_match = option; break; @@ -16837,17 +16968,17 @@ goto done; } break; } - + if (!eq && opt_bool && opt_not && !opt_all) { continue; } if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) { - + Jim_Obj *resultObj; if (opt_bool) { resultObj = Jim_NewIntObj(interp, eq ^ opt_not); } @@ -16870,11 +17001,11 @@ if (opt_all) { Jim_SetResult(interp, listObjPtr); } else { - + if (opt_bool) { Jim_SetResultBool(interp, opt_not); } else if (!opt_inline) { Jim_SetResultInt(interp, -1); @@ -16899,11 +17030,11 @@ Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); return JIM_ERR; } listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!listObjPtr) { - + listObjPtr = Jim_NewListObj(interp, NULL, 0); new_obj = 1; } else if (Jim_IsShared(listObjPtr)) { listObjPtr = Jim_DuplicateObj(interp, listObjPtr); @@ -16972,21 +17103,31 @@ first = JimRelToAbsIndex(len, first); last = JimRelToAbsIndex(len, last); JimRelToAbsRange(len, &first, &last, &rangeLen); - if (first > len) { - first = len; + + 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; } - + newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first); - + ListInsertElements(newListObj, -1, argc - 4, argv + 4); - + ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen); Jim_SetResult(interp, newListObj); return JIM_OK; } @@ -16997,11 +17138,11 @@ if (argc < 3) { Jim_WrongNumArgs(interp, 1, argv, "listVar ?index...? newVal"); return JIM_ERR; } else if (argc == 3) { - + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) return JIM_ERR; Jim_SetResult(interp, argv[2]); return JIM_OK; } @@ -17017,11 +17158,10 @@ enum { OPT_ASCII, OPT_NOCASE, OPT_INCREASING, OPT_DECREASING, OPT_COMMAND, OPT_INTEGER, OPT_REAL, OPT_INDEX, OPT_UNIQUE }; Jim_Obj *resObj; int i; int retCode; - int shared; struct lsort_info info; if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "?options? list"); @@ -17083,18 +17223,16 @@ info.indexed = 1; i++; break; } } - resObj = argv[argc - 1]; - if ((shared = Jim_IsShared(resObj))) - resObj = Jim_DuplicateObj(interp, resObj); + resObj = Jim_DuplicateObj(interp, argv[argc - 1]); retCode = ListSortElements(interp, resObj, &info); if (retCode == JIM_OK) { Jim_SetResult(interp, resObj); } - else if (shared) { + else { Jim_FreeNewObj(interp, resObj); } return retCode; } @@ -17115,11 +17253,11 @@ } else { int new_obj = 0; stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!stringObjPtr) { - + stringObjPtr = Jim_NewEmptyStringObj(interp); new_obj = 1; } else if (Jim_IsShared(stringObjPtr)) { new_obj = 1; @@ -17136,11 +17274,10 @@ } } Jim_SetResult(interp, stringObjPtr); return JIM_OK; } - static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { #if !defined(JIM_DEBUG_COMMAND) @@ -17165,11 +17302,11 @@ else { rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); } if (rc == JIM_ERR) { - + interp->addStackTrace++; } return rc; } @@ -17179,14 +17316,14 @@ if (argc >= 2) { int retcode; Jim_CallFrame *savedCallFrame, *targetCallFrame; const char *str; - + savedCallFrame = interp->framePtr; - + str = Jim_String(argv[1]); if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); argc--; argv++; @@ -17199,11 +17336,11 @@ } if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?"); return JIM_ERR; } - + interp->framePtr = targetCallFrame; if (argc == 2) { retcode = Jim_EvalObj(interp, argv[1]); } else { @@ -17219,29 +17356,32 @@ } 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]); + retcode = Jim_EvalExpression(interp, argv[1], &exprResultPtr); } else if (argc > 2) { Jim_Obj *objPtr; objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); Jim_IncrRefCount(objPtr); - retcode = Jim_EvalExpression(interp, objPtr); + retcode = Jim_EvalExpression(interp, objPtr, &exprResultPtr); Jim_DecrRefCount(interp, objPtr); } else { Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); return JIM_ERR; } if (retcode != JIM_OK) return retcode; + Jim_SetResult(interp, exprResultPtr); + Jim_DecrRefCount(interp, exprResultPtr); return JIM_OK; } static int Jim_BreakCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -17298,15 +17438,15 @@ if (i != argc - 1 && i != argc) { Jim_WrongNumArgs(interp, 1, argv, "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); } - + if (stackTraceObj && returnCode == JIM_ERR) { JimSetStackTrace(interp, stackTraceObj); } - + if (errorCodeObj && returnCode == JIM_ERR) { Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj); } interp->returnCode = returnCode; interp->returnLevel = level; @@ -17323,31 +17463,31 @@ if (interp->framePtr->level == 0) { Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1); return JIM_ERR; } else if (argc >= 2) { - + Jim_CallFrame *cf = interp->framePtr->parent; Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); if (cmdPtr == NULL) { return JIM_ERR; } JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd")); - + JimIncrCmdRefCount(cmdPtr); cf->tailcallCmd = cmdPtr; - + JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj")); cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1); Jim_IncrRefCount(cf->tailcallObj); - + return JIM_EVAL; } return JIM_OK; } @@ -17354,11 +17494,11 @@ static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *cmdList; Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); - + cmdList = Jim_DuplicateObj(interp, prefixListObj); Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1); return JimEvalObjList(interp, cmdList); } @@ -17412,22 +17552,22 @@ else { cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL); } if (cmd) { - + Jim_Obj *qualifiedCmdNameObj; const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj); JimCreateCommand(interp, cmdname, cmd); - + JimUpdateProcNamespace(interp, cmd, cmdname); JimFreeQualifiedName(interp, qualifiedCmdNameObj); - + Jim_SetResult(interp, argv[1]); return JIM_OK; } return JIM_ERR; } @@ -17440,17 +17580,17 @@ if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); return JIM_ERR; } - + interp->local++; retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); interp->local--; - + if (retcode == 0) { Jim_Obj *cmdNameObj = Jim_GetResult(interp); if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) { return JIM_ERR; @@ -17479,18 +17619,18 @@ Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) { Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); return JIM_ERR; } - + cmdPtr->u.proc.upcall++; JimIncrCmdRefCount(cmdPtr); - + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); - + cmdPtr->u.proc.upcall--; JimDecrCmdRefCount(interp, cmdPtr); return retcode; } @@ -17517,11 +17657,11 @@ return JIM_ERR; } if (len == 3) { #ifdef jim_ext_namespace - + nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2)); #else Jim_SetResultString(interp, "namespaces not enabled", -1); return JIM_ERR; #endif @@ -17530,11 +17670,11 @@ bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); if (cmd) { - + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); Jim_IncrRefCount(nargv[0]); memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); @@ -17560,11 +17700,11 @@ static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int i; Jim_CallFrame *targetCallFrame; - + if (argc > 3 && (argc % 2 == 0)) { targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); argc--; argv++; } @@ -17573,17 +17713,17 @@ } if (targetCallFrame == NULL) { return JIM_ERR; } - + if (argc < 3) { Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); return JIM_ERR; } - + for (i = 1; i < argc; i += 2) { if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK) return JIM_ERR; } return JIM_OK; @@ -17596,15 +17736,15 @@ if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); return JIM_ERR; } - + if (interp->framePtr->level == 0) - return JIM_OK; + return JIM_OK; for (i = 1; i < argc; i++) { - + const char *name = Jim_String(argv[i]); if (name[0] != ':' || name[1] != ':') { if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK) return JIM_ERR; } @@ -17627,21 +17767,21 @@ } str = Jim_String(objPtr); strLen = Jim_Utf8Length(interp, objPtr); - + resultObjPtr = Jim_NewStringObj(interp, "", 0); while (strLen) { for (i = 0; i < numMaps; i += 2) { - Jim_Obj *eachObjPtr; + Jim_Obj *objPtr; const char *k; int kl; - eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i); - k = Jim_String(eachObjPtr); - kl = Jim_Utf8Length(interp, eachObjPtr); + objPtr = Jim_ListGetIndex(interp, mapListObjPtr, i); + k = Jim_String(objPtr); + kl = Jim_Utf8Length(interp, objPtr); if (strLen >= kl && kl) { int rc; rc = JimStringCompareLen(str, k, kl, nocase); if (rc == 0) { @@ -17654,11 +17794,11 @@ strLen -= kl; break; } } } - if (i == numMaps) { + if (i == numMaps) { int c; if (noMatchStart == NULL) noMatchStart = str; str += utf8_tounicode(str, &c); strLen--; @@ -17698,11 +17838,11 @@ Jim_WrongNumArgs(interp, 1, argv, "option ?arguments ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) - return Jim_CheckShowCommands(interp, argv[1], options); + return JIM_ERR; switch (option) { case OPT_LENGTH: case OPT_BYTELENGTH: if (argc != 3) { @@ -17719,11 +17859,11 @@ return JIM_OK; case OPT_CAT:{ Jim_Obj *objPtr; if (argc == 3) { - + objPtr = argv[2]; } else { int i; @@ -17738,11 +17878,11 @@ } case OPT_COMPARE: case OPT_EQUAL: { - + long opt_length = -1; int n = argc - 4; int i = 2; while (n > 0) { int subopt; @@ -17751,16 +17891,16 @@ badcompareargs: Jim_WrongNumArgs(interp, 2, argv, "?-nocase? ?-length int? string1 string2"); return JIM_ERR; } if (subopt == 0) { - + opt_case = 0; n--; } else { - + if (n < 2) { goto badcompareargs; } if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) { return JIM_ERR; @@ -17771,11 +17911,11 @@ if (n) { goto badcompareargs; } argv += argc - 2; if (opt_length < 0 && option != OPT_COMPARE && opt_case) { - + Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1])); } else { if (opt_length >= 0) { n = JimStringCompareLen(Jim_String(argv[0]), Jim_String(argv[1]), opt_length, !opt_case); @@ -17885,10 +18025,11 @@ } case OPT_REVERSE:{ char *buf, *p; const char *str; + int len; int i; if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "string"); return JIM_ERR; @@ -17928,11 +18069,11 @@ } if (idx < 0 || idx >= len || str == NULL) { Jim_SetResultString(interp, "", 0); } else if (len == Jim_Length(argv[2])) { - + Jim_SetResultString(interp, str + idx, 1); } else { int c; int i = utf8_index(str, idx); @@ -18082,11 +18223,11 @@ { int exitCode = 0; int i; int sig = 0; - + jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL); static const int max_ignore_code = sizeof(ignore_mask) * 8; Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1)); @@ -18093,11 +18234,11 @@ for (i = 1; i < argc - 1; i++) { const char *arg = Jim_String(argv[i]); jim_wide option; int ignore; - + if (strcmp(arg, "--") == 0) { i++; break; } if (*arg != '-') { @@ -18144,28 +18285,28 @@ sig++; } interp->signal_level += sig; if (Jim_CheckSignal(interp)) { - + exitCode = JIM_SIGNAL; } else { exitCode = Jim_EvalObj(interp, argv[0]); - + interp->errorFlag = 0; } interp->signal_level -= sig; - + if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) { - + return exitCode; } if (sig && exitCode == JIM_SIGNAL) { - + if (interp->signal_set_result) { interp->signal_set_result(interp, interp->sigmask); } else { Jim_SetResultInt(interp, interp->sigmask); @@ -18204,10 +18345,125 @@ } Jim_SetResultInt(interp, exitCode); return JIM_OK; } +#ifdef JIM_REFERENCES + + +static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3 && argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?"); + return JIM_ERR; + } + if (argc == 3) { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL)); + } + else { + Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], argv[3])); + } + return JIM_OK; +} + + +static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "reference"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, refPtr->objPtr); + return JIM_OK; +} + + +static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Reference *refPtr; + + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference newValue"); + return JIM_ERR; + } + if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) + return JIM_ERR; + Jim_IncrRefCount(argv[2]); + Jim_DecrRefCount(interp, refPtr->objPtr); + refPtr->objPtr = argv[2]; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + + +static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_Collect(interp)); + + + while (interp->freeList) { + Jim_Obj *nextObjPtr = interp->freeList->nextObjPtr; + Jim_Free(interp->freeList); + interp->freeList = nextObjPtr; + } + + return JIM_OK; +} + + +static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *cmdNamePtr; + + if (Jim_GetFinalizer(interp, argv[1], &cmdNamePtr) != JIM_OK) + return JIM_ERR; + if (cmdNamePtr != NULL) + Jim_SetResult(interp, cmdNamePtr); + } + else { + if (Jim_SetFinalizer(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + } + return JIM_OK; +} + + +static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + Jim_HashTableIterator htiter; + Jim_HashEntry *he; + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + + JimInitHashTableIterator(&interp->references, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + char buf[JIM_REFERENCE_SPACE + 1]; + Jim_Reference *refPtr = Jim_GetHashEntryVal(he); + const unsigned long *refId = he->key; + + JimFormatReference(buf, refPtr, *refId); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, buf, -1)); + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} +#endif static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { if (argc != 3) { @@ -18220,43 +18476,56 @@ } return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2])); } -#define JIM_DICTMATCH_KEYS 0x0001 -#define JIM_DICTMATCH_VALUES 0x002 +#define JIM_DICTMATCH_VALUES 0x0001 -int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types) +typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type); + +static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type) +{ + Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); + if (type & JIM_DICTMATCH_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he)); + } +} + +static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimDictMatchCallbackType *callback, int type) { Jim_HashEntry *he; - Jim_Obj *listObjPtr; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + Jim_HashTableIterator htiter; + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) { + callback(interp, listObjPtr, he, type); + } + } + return listObjPtr; +} + + +int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0)); + return JIM_OK; +} + +int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr) +{ if (SetDictFromAny(interp, objPtr) != JIM_OK) { return JIM_ERR; } - - listObjPtr = Jim_NewListObj(interp, NULL, 0); - - JimInitHashTableIterator(objPtr->internalRep.ptr, &htiter); - while ((he = Jim_NextHashEntry(&htiter)) != NULL) { - if (patternObj) { - Jim_Obj *matchObj = (match_type == JIM_DICTMATCH_KEYS) ? (Jim_Obj *)he->key : Jim_GetHashEntryVal(he); - if (!JimGlobMatch(Jim_String(patternObj), Jim_String(matchObj), 0)) { - - continue; - } - } - if (return_types & JIM_DICTMATCH_KEYS) { - Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key); - } - if (return_types & JIM_DICTMATCH_VALUES) { - Jim_ListAppendElement(interp, listObjPtr, Jim_GetHashEntryVal(he)); - } - } - - Jim_SetResult(interp, listObjPtr); + Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES)); return JIM_OK; } int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) { @@ -18264,84 +18533,37 @@ return -1; } return ((Jim_HashTable *)objPtr->internalRep.ptr)->used; } -Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv) -{ - Jim_Obj *objPtr = Jim_NewDictObj(interp, NULL, 0); - int i; - - JimPanic((objc == 0, "Jim_DictMerge called with objc=0")); - - - - for (i = 0; i < objc; i++) { - Jim_HashTable *ht; - Jim_HashTableIterator htiter; - Jim_HashEntry *he; - - if (SetDictFromAny(interp, objv[i]) != JIM_OK) { - Jim_FreeNewObj(interp, objPtr); - return NULL; - } - ht = objv[i]->internalRep.ptr; - JimInitHashTableIterator(ht, &htiter); - while ((he = Jim_NextHashEntry(&htiter)) != NULL) { - Jim_ReplaceHashEntry(objPtr->internalRep.ptr, Jim_GetHashEntryKey(he), Jim_GetHashEntryVal(he)); - } - } - return objPtr; -} - int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr) { Jim_HashTable *ht; unsigned int i; - char buffer[100]; - int sum = 0; - int nonzero_count = 0; - Jim_Obj *output; - int bucket_counts[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (SetDictFromAny(interp, objPtr) != JIM_OK) { return JIM_ERR; } ht = (Jim_HashTable *)objPtr->internalRep.ptr; - - snprintf(buffer, sizeof(buffer), "%d entries in table, %d buckets\n", ht->used, ht->size); - output = Jim_NewStringObj(interp, buffer, -1); + + printf("%d entries in table, %d buckets\n", ht->used, ht->size); for (i = 0; i < ht->size; i++) { Jim_HashEntry *he = ht->table[i]; - int entries = 0; - while (he) { - entries++; - he = he->next; - } - if (entries > 9) { - bucket_counts[10]++; - } - else { - bucket_counts[entries]++; - } - if (entries) { - sum += entries; - nonzero_count++; - } - } - for (i = 0; i < 10; i++) { - snprintf(buffer, sizeof(buffer), "number of buckets with %d entries: %d\n", i, bucket_counts[i]); - Jim_AppendString(interp, output, buffer, -1); - } - snprintf(buffer, sizeof(buffer), "number of buckets with 10 or more entries: %d\n", bucket_counts[10]); - Jim_AppendString(interp, output, buffer, -1); - snprintf(buffer, sizeof(buffer), "average search distance for entry: %.1f", nonzero_count ? (double)sum / nonzero_count : 0.0); - Jim_AppendString(interp, output, buffer, -1); - Jim_SetResult(interp, output); + + if (he) { + printf("%d: ", i); + + while (he) { + printf(" %s", Jim_String(he->key)); + he = he->next; + } + printf("\n"); + } + } return JIM_OK; } static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char *subcmd, int argc, Jim_Obj *const *argv) { @@ -18351,67 +18573,14 @@ Jim_AppendString(interp, prefixObj, subcmd, -1); return Jim_EvalObjPrefix(interp, prefixObj, argc, argv); } -static int JimDictWith(Jim_Interp *interp, Jim_Obj *dictVarName, Jim_Obj *const *keyv, int keyc, Jim_Obj *scriptObj) -{ - int i; - Jim_Obj *objPtr; - Jim_Obj *dictObj; - Jim_Obj **dictValues; - int len; - int ret = JIM_OK; - - - dictObj = Jim_GetVariable(interp, dictVarName, JIM_ERRMSG); - if (dictObj == NULL || Jim_DictKeysVector(interp, dictObj, keyv, keyc, &objPtr, JIM_ERRMSG) != JIM_OK) { - return JIM_ERR; - } - - if (Jim_DictPairs(interp, objPtr, &dictValues, &len) == JIM_ERR) { - return JIM_ERR; - } - for (i = 0; i < len; i += 2) { - if (Jim_SetVariable(interp, dictValues[i], dictValues[i + 1]) == JIM_ERR) { - Jim_Free(dictValues); - return JIM_ERR; - } - } - - - if (Jim_Length(scriptObj)) { - ret = Jim_EvalObj(interp, scriptObj); - - - if (ret == JIM_OK && Jim_GetVariable(interp, dictVarName, 0) != NULL) { - - Jim_Obj **newkeyv = Jim_Alloc(sizeof(*newkeyv) * (keyc + 1)); - for (i = 0; i < keyc; i++) { - newkeyv[i] = keyv[i]; - } - - for (i = 0; i < len; i += 2) { - - objPtr = Jim_GetVariable(interp, dictValues[i], 0); - newkeyv[keyc] = dictValues[i]; - Jim_SetDictKeysVector(interp, dictVarName, newkeyv, keyc + 1, objPtr, 0); - } - Jim_Free(newkeyv); - } - } - - Jim_Free(dictValues); - - return ret; -} - static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_Obj *objPtr; - int types = JIM_DICTMATCH_KEYS; int option; static const char * const options[] = { "create", "get", "set", "unset", "exists", "keys", "size", "info", "merge", "with", "append", "lappend", "incr", "remove", "values", "for", "replace", "update", NULL @@ -18427,11 +18596,11 @@ Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arguments ...?"); return JIM_ERR; } if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) { - return Jim_CheckShowCommands(interp, argv[1], options); + return JIM_ERR; } switch (option) { case OPT_GET: if (argc < 3) { @@ -18474,19 +18643,16 @@ if (Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, 0) != JIM_OK) { return JIM_ERR; } return JIM_OK; - case OPT_VALUES: - types = JIM_DICTMATCH_VALUES; - case OPT_KEYS: if (argc != 3 && argc != 4) { Jim_WrongNumArgs(interp, 2, argv, "dictionary ?pattern?"); return JIM_ERR; } - return Jim_DictMatchTypes(interp, argv[2], argc == 4 ? argv[3] : NULL, types, types); + return Jim_DictKeys(interp, argv[2], argc == 4 ? argv[3] : NULL); case OPT_SIZE: if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "dictionary"); return JIM_ERR; @@ -18499,20 +18665,19 @@ case OPT_MERGE: if (argc == 2) { return JIM_OK; } - objPtr = Jim_DictMerge(interp, argc - 2, argv + 2); - if (objPtr == NULL) { + if (Jim_DictSize(interp, argv[2]) < 0) { return JIM_ERR; } - Jim_SetResult(interp, objPtr); - return JIM_OK; + + break; case OPT_UPDATE: if (argc < 6 || argc % 2) { - + argc = 2; } break; case OPT_CREATE: @@ -18528,19 +18693,12 @@ if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "dictionary"); return JIM_ERR; } return Jim_DictInfo(interp, argv[2]); - - case OPT_WITH: - if (argc < 4) { - Jim_WrongNumArgs(interp, 2, argv, "dictVar ?key ...? script"); - return JIM_ERR; - } - return JimDictWith(interp, argv[2], argv + 3, argc - 4, argv[argc - 1]); - } - + } + return Jim_EvalEnsemble(interp, "dict", options[option], argc - 2, argv + 2); } static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -18606,11 +18764,11 @@ #ifdef jim_ext_namespace int nons = 0; if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) { - + argc--; argv++; nons = 1; } #endif @@ -18617,15 +18775,16 @@ if (argc < 2) { Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?"); return JIM_ERR; } - if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { - return Jim_CheckShowCommands(interp, argv[1], commands); + if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) + != JIM_OK) { + return JIM_ERR; } - + switch (cmd) { case INFO_EXISTS: if (argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "varName"); return JIM_ERR; @@ -18650,21 +18809,21 @@ Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData); return JIM_OK; } case INFO_CHANNELS: - mode++; + mode++; #ifndef jim_ext_aio Jim_SetResultString(interp, "aio not enabled", -1); return JIM_ERR; #endif - + case INFO_PROCS: - mode++; - + mode++; + case INFO_COMMANDS: - + if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); return JIM_ERR; } #ifdef jim_ext_namespace @@ -18676,17 +18835,17 @@ #endif Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode)); break; case INFO_VARS: - mode++; - + mode++; + case INFO_LOCALS: - mode++; - + mode++; + case INFO_GLOBALS: - + if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 2, argv, "?pattern?"); return JIM_ERR; } #ifdef jim_ext_namespace @@ -18792,12 +18951,13 @@ case INFO_ARGS: Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr); break; case INFO_STATICS: if (cmdPtr->u.proc.staticVars) { + int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES; Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars, - NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES)); + NULL, JimVariablesMatch, mode)); } break; } break; } @@ -18825,15 +18985,15 @@ } } break; case INFO_HOSTNAME: - + return Jim_Eval(interp, "os.gethostname"); case INFO_NAMEOFEXECUTABLE: - + return Jim_Eval(interp, "{info nameofexecutable}"); case INFO_RETURNCODES: if (argc == 2) { int i; @@ -18910,11 +19070,11 @@ if (option == OPT_VAR) { result = Jim_GetVariable(interp, objPtr, 0) != NULL; } else { - + Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE); if (cmd) { switch (option) { case OPT_COMMAND: @@ -18953,11 +19113,11 @@ if (len == 0) { return JIM_OK; } strLen = Jim_Utf8Length(interp, argv[1]); - + if (argc == 2) { splitChars = " \n\t\r"; splitLen = 4; } else { @@ -18966,11 +19126,11 @@ } noMatchStart = str; resObjPtr = Jim_NewListObj(interp, NULL, 0); - + if (splitLen) { Jim_Obj *objPtr; while (strLen--) { const char *sc = splitChars; int scLen = splitLen; @@ -18995,11 +19155,11 @@ #define NUM_COMMON (128 - 9) while (strLen--) { int n = utf8_tounicode(str, &c); #ifdef JIM_OPTIMIZATION if (c >= 9 && c < 128) { - + c -= 9; if (!commonObj) { commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON); memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON); } @@ -19029,11 +19189,11 @@ if (argc != 2 && argc != 3) { Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); return JIM_ERR; } - + if (argc == 2) { joinStr = " "; joinStrLen = 1; } else { @@ -19308,13 +19468,13 @@ return -1; else if (step < 0 && end > start) return -1; len = end - start; if (len < 0) - len = -len; + len = -len; if (step < 0) - step = -step; + step = -step; len = 1 + ((len - 1) / step); if (len > INT_MAX) len = INT_MAX; return (int)((len < 0) ? -1 : len); } @@ -19484,102 +19644,57 @@ argv[1] = interp->result; Jim_EvalObjVector(interp, 2, argv); } -static char **JimSortStringTable(const char *const *tablePtr) +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name) { int count; char **tablePtrSorted; - + int i; for (count = 0; tablePtr[count]; count++) { } - - tablePtrSorted = Jim_Alloc(sizeof(char *) * (count + 1)); - memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); - qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); - tablePtrSorted[count] = NULL; - - return tablePtrSorted; -} - -static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, - const char *prefix, const char *const *tablePtr, const char *name) -{ - char **tablePtrSorted; - int i; - if (name == NULL) { name = "option"; } Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg); - tablePtrSorted = JimSortStringTable(tablePtr); - for (i = 0; tablePtrSorted[i]; i++) { - if (tablePtrSorted[i + 1] == NULL && i > 0) { + tablePtrSorted = Jim_Alloc(sizeof(char *) * count); + memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); + qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); + for (i = 0; i < count; i++) { + if (i + 1 == count && count > 1) { Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1); } Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL); - if (tablePtrSorted[i + 1]) { + if (i + 1 != count) { Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1); } } Jim_Free(tablePtrSorted); } - -int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr) -{ - if (Jim_CompareStringImmediate(interp, objPtr, "-commands")) { - int i; - char **tablePtrSorted = JimSortStringTable(tablePtr); - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - for (i = 0; tablePtrSorted[i]; i++) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, tablePtrSorted[i], -1)); - } - Jim_Free(tablePtrSorted); - return JIM_OK; - } - return JIM_ERR; -} - -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) { const char *bad = "bad "; const char *const *entryPtr = NULL; int i; int match = -1; int 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); + const char *arg = Jim_GetString(objPtr, &arglen); *indexPtr = -1; for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { - - match = i; - goto found; + + *indexPtr = i; + return JIM_OK; } if (flags & JIM_ENUM_ABBREV) { if (strncmp(arg, *entryPtr, arglen) == 0) { if (*arg == '-' && arglen == 1) { break; @@ -19591,20 +19706,12 @@ match = i; } } } - + 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; } ambiguous: @@ -19636,17 +19743,15 @@ return objPtr->typePtr == &listObjType; } void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) { - + int len = strlen(format); int extra = 0; int n = 0; const char *params[5]; - int nobjparam = 0; - Jim_Obj *objparam[5]; char *buf; va_list args; int i; va_start(args, format); @@ -19661,12 +19766,10 @@ } else if (strncmp(format + i, "%#s", 3) == 0) { Jim_Obj *objPtr = va_arg(args, Jim_Obj *); params[n] = Jim_GetString(objPtr, &l); - objparam[nobjparam++] = objPtr; - Jim_IncrRefCount(objPtr); } else { if (format[i] == '%') { i++; } @@ -19681,14 +19784,10 @@ len = snprintf(buf, len + 1, format, params[0], params[1], params[2], params[3], params[4]); va_end(args); Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); - - for (i = 0; i < nobjparam; i++) { - Jim_DecrRefCount(interp, objparam[i]); - } } #ifndef jim_ext_package int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, int flags) @@ -19709,11 +19808,11 @@ #include static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - + return JIM_OK; } static const jim_subcmd_type dummy_subcmd = { "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN @@ -19732,18 +19831,22 @@ } static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type, Jim_Obj *cmd, Jim_Obj *subcmd) { - Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be ", cmd, type, subcmd); + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type, + " command \"", Jim_String(subcmd), "\": should be ", NULL); 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_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: ", argv[0]); + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]), + " command ... \", where command is one of: ", NULL); add_commands(interp, command_table, ", "); } static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *cmd) { @@ -19761,77 +19864,66 @@ Jim_SetResultString(interp, "wrong # args: should be \"", -1); add_cmd_usage(interp, command_table, subcmd); 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) { const jim_subcmd_type *ct; const jim_subcmd_type *partial = 0; int cmdlen; Jim_Obj *cmd; const char *cmdstr; + const char *cmdname; int help = 0; + cmdname = Jim_String(argv[0]); + if (argc < 2) { - Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n" - "Use \"%#s -help ?command?\" for help", argv[0], argv[0]); + 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); 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) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } help = 1; - + cmd = argv[2]; } - + if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { - + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); add_commands(interp, command_table, " "); return &dummy_subcmd; } cmdstr = Jim_GetString(cmd, &cmdlen); for (ct = command_table; ct->cmd; ct++) { if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { - + break; } if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { if (partial) { - + if (help) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]); return 0; @@ -19839,51 +19931,44 @@ partial = ct; } continue; } - + if (partial && !ct->cmd) { ct = partial; } if (!ct->cmd) { - + if (help) { - + show_cmd_usage(interp, command_table, argc, argv); return &dummy_subcmd; } bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]); return 0; } if (help) { Jim_SetResultString(interp, "Usage: ", -1); - + add_cmd_usage(interp, ct, argv[0]); return &dummy_subcmd; } - - 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); - + add_cmd_usage(interp, ct, argv[0]); Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); return 0; } - + return ct; } int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv) { @@ -19934,11 +20019,11 @@ *p++ = 0xe0 | ((uc & 0xf000) >> 12); *p++ = 0x80 | ((uc & 0xfc0) >> 6); *p = 0x80 | (uc & 0x3f); return 3; } - + else { *p++ = 0xf0 | ((uc & 0x1c0000) >> 18); *p++ = 0x80 | ((uc & 0x3f000) >> 12); *p++ = 0x80 | ((uc & 0xfc0) >> 6); *p = 0x80 | (uc & 0x3f); @@ -20061,12 +20146,11 @@ continue; } *p++ = ch; format += step; step = utf8_tounicode(format, &ch); - - } while (sawFlag && (p - spec <= 5)); + } while (sawFlag); width = 0; if (isdigit(ch)) { width = strtoul(format, &end, 10); @@ -20126,11 +20210,11 @@ if (ch == 'h') { useShort = 1; format += step; step = utf8_tounicode(format, &ch); } else if (ch == 'l') { - + format += step; step = utf8_tounicode(format, &ch); if (ch == 'l') { format += step; step = utf8_tounicode(format, &ch); @@ -20153,11 +20237,11 @@ goto errorMsg; case 's': { formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes); formatted_chars = Jim_Utf8Length(interp, objv[objIndex]); if (gotPrecision && (precision < formatted_chars)) { - + formatted_chars = precision; formatted_bytes = utf8_index(formatted_buf, precision); } break; } @@ -20165,11 +20249,11 @@ jim_wide code; if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) { goto error; } - + formatted_bytes = utf8_getchars(spec, code); formatted_buf = spec; formatted_chars = 1; break; } @@ -20183,11 +20267,11 @@ goto error; } length = sizeof(w) * 8; - + if (num_buffer_size < length + 1) { num_buffer_size = length + 1; num_buffer = Jim_Realloc(num_buffer, num_buffer_size); } @@ -20211,29 +20295,29 @@ case 'E': case 'f': case 'g': case 'G': doubleType = 1; - + case 'd': case 'u': case 'o': case 'x': case 'X': { jim_wide w; double d; int length; - + if (width) { p += sprintf(p, "%ld", width); } if (gotPrecision) { p += sprintf(p, ".%ld", precision); } - + if (doubleType) { if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) { goto error; } length = MAX_FLOAT_WIDTH; @@ -20260,26 +20344,19 @@ } *p++ = (char) ch; *p = '\0'; - - if (width > 10000 || length > 10000 || precision > 10000) { - Jim_SetResultString(interp, "format too long", -1); - goto error; - } - - - + if (width > length) { length = width; } if (gotPrecision) { length += precision; } - + if (num_buffer_size < length + 1) { num_buffer_size = length + 1; num_buffer = Jim_Realloc(num_buffer, num_buffer_size); } @@ -20293,11 +20370,11 @@ formatted_buf = num_buffer; break; } default: { - + spec[0] = ch; spec[1] = '\0'; Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec); goto error; } @@ -20345,37 +20422,37 @@ #define REG_MAX_PAREN 100 -#define END 0 -#define BOL 1 -#define EOL 2 -#define ANY 3 -#define ANYOF 4 -#define ANYBUT 5 -#define BRANCH 6 -#define BACK 7 -#define EXACTLY 8 -#define NOTHING 9 -#define REP 10 -#define REPMIN 11 -#define REPX 12 -#define REPXMIN 13 -#define BOLX 14 -#define EOLX 15 -#define WORDA 16 -#define WORDZ 17 - -#define OPENNC 1000 -#define OPEN 1001 - - - - -#define CLOSENC 2000 -#define CLOSE 2001 +#define END 0 +#define BOL 1 +#define EOL 2 +#define ANY 3 +#define ANYOF 4 +#define ANYBUT 5 +#define BRANCH 6 +#define BACK 7 +#define EXACTLY 8 +#define NOTHING 9 +#define REP 10 +#define REPMIN 11 +#define REPX 12 +#define REPXMIN 13 +#define BOLX 14 +#define EOLX 15 +#define WORDA 16 +#define WORDZ 17 + +#define OPENNC 1000 +#define OPEN 1001 + + + + +#define CLOSENC 2000 +#define CLOSE 2001 #define CLOSE_END (CLOSE+REG_MAX_PAREN) #define REG_MAGIC 0xFADED00D @@ -20388,18 +20465,18 @@ #define FAIL(R,M) { (R)->err = (M); return (M); } #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{') #define META "^$.[()|?{+*" -#define HASWIDTH 1 -#define SIMPLE 2 -#define SPSTART 4 -#define WORST 0 +#define HASWIDTH 1 +#define SIMPLE 2 +#define SPSTART 4 +#define WORST 0 #define MAX_REP_COUNT 1000000 -static int reg(regex_t *preg, int paren, int *flagp ); +static int reg(regex_t *preg, int paren , int *flagp ); static int regpiece(regex_t *preg, int *flagp ); static int regbranch(regex_t *preg, int *flagp ); static int regatom(regex_t *preg, int *flagp ); static int regnode(regex_t *preg, int op ); static int regnext(regex_t *preg, int p ); @@ -20443,15 +20520,15 @@ memset(preg, 0, sizeof(*preg)); if (exp == NULL) FAIL(preg, REG_ERR_NULL_ARGUMENT); - + preg->cflags = cflags; preg->regparse = exp; - + preg->proglen = (strlen(exp) + 1) * 5; preg->program = malloc(preg->proglen * sizeof(int)); if (preg->program == NULL) FAIL(preg, REG_ERR_NOMEM); @@ -20458,24 +20535,24 @@ regc(preg, REG_MAGIC); if (reg(preg, 0, &flags) == 0) { return preg->err; } - - if (preg->re_nsub >= REG_MAX_PAREN) + + if (preg->re_nsub >= REG_MAX_PAREN) FAIL(preg,REG_ERR_TOO_BIG); - - preg->regstart = 0; + + preg->regstart = 0; preg->reganch = 0; preg->regmust = 0; preg->regmlen = 0; - scan = 1; - if (OP(preg, regnext(preg, scan)) == END) { + scan = 1; + if (OP(preg, regnext(preg, scan)) == END) { scan = OPERAND(scan); - + if (OP(preg, scan) == EXACTLY) { preg->regstart = preg->program[OPERAND(scan)]; } else if (OP(preg, scan) == BOL) preg->reganch++; @@ -20502,24 +20579,24 @@ #endif return 0; } -static int reg(regex_t *preg, int paren, int *flagp ) +static int reg(regex_t *preg, int paren , int *flagp ) { int ret; int br; int ender; int parno = 0; int flags; - *flagp = HASWIDTH; + *flagp = HASWIDTH; - + if (paren) { if (preg->regparse[0] == '?' && preg->regparse[1] == ':') { - + preg->regparse += 2; parno = -1; } else { parno = ++preg->re_nsub; @@ -20526,16 +20603,16 @@ } ret = regnode(preg, OPEN+parno); } else ret = 0; - + br = regbranch(preg, &flags); if (br == 0) return 0; if (ret != 0) - regtail(preg, ret, br); + regtail(preg, ret, br); else ret = br; if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; @@ -20542,25 +20619,25 @@ while (*preg->regparse == '|') { preg->regparse++; br = regbranch(preg, &flags); if (br == 0) return 0; - regtail(preg, ret, br); + regtail(preg, ret, br); if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } - + ender = regnode(preg, (paren) ? CLOSE+parno : END); regtail(preg, ret, ender); - + for (br = ret; br != 0; br = regnext(preg, br)) regoptail(preg, br, ender); - + if (paren && *preg->regparse++ != ')') { preg->err = REG_ERR_UNMATCHED_PAREN; return 0; } else if (!paren && *preg->regparse != '\0') { if (*preg->regparse == ')') { @@ -20580,11 +20657,11 @@ int ret; int chain; int latest; int flags; - *flagp = WORST; + *flagp = WORST; ret = regnode(preg, BRANCH); chain = 0; while (*preg->regparse != '\0' && *preg->regparse != ')' && *preg->regparse != '|') { @@ -20598,11 +20675,11 @@ else { regtail(preg, chain, latest); } chain = latest; } - if (chain == 0) + if (chain == 0) (void) regnode(preg, NOTHING); return(ret); } @@ -20628,11 +20705,11 @@ if (!(flags&HASWIDTH) && op != '?') { preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY; return 0; } - + if (op == '{') { char *end; min = strtoul(preg->regparse + 1, &end, 10); if (end == preg->regparse + 1) { @@ -20640,14 +20717,10 @@ return 0; } 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); if (*end != '}') { preg->err = REG_ERR_UNMATCHED_BRACES; @@ -20704,11 +20777,11 @@ static void reg_addrange(regex_t *preg, int lower, int upper) { if (lower > upper) { reg_addrange(preg, upper, lower); } - + regc(preg, upper - lower + 1); regc(preg, lower); } static void reg_addrange_str(regex_t *preg, const char *str) @@ -20772,17 +20845,17 @@ case 'r': *ch = '\r'; break; case 't': *ch = '\t'; break; case 'v': *ch = '\v'; break; case 'u': if (*s == '{') { - + n = parse_hex(s + 1, 6, ch); if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) { s += n + 2; } else { - + *ch = 'u'; } } else if ((n = parse_hex(s, 4, ch)) > 0) { s += n; @@ -20813,15 +20886,15 @@ int nocase = (preg->cflags & REG_ICASE); int ch; int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase); - *flagp = WORST; + *flagp = WORST; preg->regparse += n; switch (ch) { - + case '^': ret = regnode(preg, BOL); break; case '$': ret = regnode(preg, EOL); @@ -20831,60 +20904,37 @@ *flagp |= HASWIDTH|SIMPLE; break; case '[': { const char *pattern = preg->regparse; - if (*pattern == '^') { + if (*pattern == '^') { ret = regnode(preg, ANYBUT); pattern++; } else ret = regnode(preg, ANYOF); - + if (*pattern == ']' || *pattern == '-') { reg_addrange(preg, *pattern, *pattern); pattern++; } while (*pattern && *pattern != ']') { - + int start; int end; - 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; return 0; } } if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') { - + pattern += utf8_tounicode(pattern, &end); pattern += reg_utf8_tounicode_case(pattern, &end, nocase); if (end == '\\') { pattern += reg_decode_escape(pattern, &end); if (end == 0) { @@ -20899,25 +20949,30 @@ if (start == '[' && pattern[0] == ':') { static const char *character_class[] = { ":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 (cc = 0; cc < CC_NUM; cc++) { - n = strlen(character_class[cc]); - if (strncmp(pattern, character_class[cc], n) == 0) { - + for (i = 0; i < CC_NUM; i++) { + int n = strlen(character_class[i]); + if (strncmp(pattern, character_class[i], n) == 0) { + pattern += n + 1; break; } } - if (cc != CC_NUM) { -cc_switch: - switch (cc) { + if (i != CC_NUM) { + switch (i) { case CC_ALNUM: reg_addrange(preg, '0', '9'); - + case CC_ALPHA: if ((preg->cflags & REG_ICASE) == 0) { reg_addrange(preg, 'a', 'z'); } reg_addrange(preg, 'A', 'Z'); @@ -20935,11 +20990,11 @@ reg_addrange(preg, 'a', 'z'); break; case CC_XDIGIT: reg_addrange(preg, 'a', 'f'); reg_addrange(preg, 'A', 'F'); - + case CC_DIGIT: reg_addrange(preg, '0', '9'); break; case CC_CNTRL: reg_addrange(preg, 0, 31); @@ -20959,11 +21014,11 @@ break; } continue; } } - + reg_addrange(preg, start, start); } regc(preg, '\0'); if (*pattern) { @@ -20982,11 +21037,11 @@ break; case '\0': case '|': case ')': preg->err = REG_ERR_INTERNAL; - return 0; + return 0; case '?': case '+': case '*': case '{': preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING; @@ -21035,34 +21090,34 @@ ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT); reg_addrange_str(preg," \t\r\n\f\v"); regc(preg, '\0'); *flagp |= HASWIDTH|SIMPLE; break; - + default: - - + + preg->regparse--; goto de_fault; } break; de_fault: default: { int added = 0; - + preg->regparse -= n; ret = regnode(preg, EXACTLY); - + while (*preg->regparse && strchr(META, *preg->regparse) == NULL) { n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE)); if (ch == '\\' && preg->regparse[n]) { if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) { - + break; } n += reg_decode_escape(preg->regparse + n, &ch); if (ch == 0) { preg->err = REG_ERR_NULL_CHAR; @@ -21070,23 +21125,23 @@ } } if (ISMULT(preg->regparse[n])) { - + if (added) { - + break; } - + regc(preg, ch); added++; preg->regparse += n; break; } - + regc(preg, ch); added++; preg->regparse += n; } regc(preg, '\0'); @@ -21113,15 +21168,15 @@ static int regnode(regex_t *preg, int op) { reg_grow(preg, 2); - + preg->program[preg->p++] = op; preg->program[preg->p++] = 0; - + return preg->p - 2; } static void regc(regex_t *preg, int b ) { @@ -21131,13 +21186,13 @@ static int reginsert(regex_t *preg, int op, int size, int opnd ) { reg_grow(preg, size); - + memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd)); - + memset(preg->program + opnd, 0, sizeof(int) * size); preg->program[opnd] = op; preg->p += size; @@ -21149,11 +21204,11 @@ { int scan; int temp; int offset; - + scan = p; for (;;) { temp = regnext(preg, scan); if (temp == 0) break; @@ -21169,11 +21224,11 @@ } static void regoptail(regex_t *preg, int p, int val ) { - + if (p != 0 && OP(preg, p) == BRANCH) { regtail(preg, OPERAND(p), val); } } @@ -21185,16 +21240,16 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { const char *s; int scan; - + if (preg == NULL || preg->program == NULL || string == NULL) { return REG_ERR_NULL_ARGUMENT; } - + if (*preg->program != REG_MAGIC) { return REG_ERR_CORRUPTED; } #ifdef DEBUG @@ -21203,51 +21258,51 @@ #endif preg->eflags = eflags; preg->pmatch = pmatch; preg->nmatch = nmatch; - preg->start = string; + preg->start = string; - + for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) { int op = OP(preg, scan); if (op == END) break; if (op == REPX || op == REPXMIN) preg->program[scan + 4] = 0; } - + if (preg->regmust != 0) { s = string; while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) { if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) { break; } s++; } - if (s == NULL) + if (s == NULL) return REG_NOMATCH; } - + preg->regbol = string; - + if (preg->reganch) { if (eflags & REG_NOTBOL) { - + goto nextline; } while (1) { if (regtry(preg, string)) { return REG_NOERROR; } if (*string) { nextline: if (preg->cflags & REG_NEWLINE) { - + string = strchr(string, '\n'); if (string) { preg->regbol = ++string; continue; } @@ -21255,22 +21310,22 @@ } return REG_NOMATCH; } } - + s = string; if (preg->regstart != '\0') { - + while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) { if (regtry(preg, s)) return REG_NOERROR; s++; } } else - + while (1) { if (regtry(preg, s)) return REG_NOERROR; if (*s == '\0') { break; @@ -21279,15 +21334,15 @@ int c; s += utf8_tounicode(s, &c); } } - + return REG_NOMATCH; } - + static int regtry( regex_t *preg, const char *string ) { int i; preg->reginput = string; @@ -21324,11 +21379,11 @@ } static int reg_range_find(const int *range, int c) { while (*range) { - + if (c >= range[1] && c <= (range[0] + range[1] - 1)) { return 1; } range += 2; } @@ -21336,11 +21391,11 @@ } static const char *str_find(const char *string, int c, int nocase) { if (nocase) { - + c = utf8_upper(c); } while (*string) { int ch; int n = reg_utf8_tounicode_case(string, &ch, nocase); @@ -21380,15 +21435,15 @@ no = regrepeat(preg, scan + 5, max); if (no < min) { return 0; } if (matchmin) { - + max = no; no = min; } - + while (1) { if (matchmin) { if (no > max) { break; } @@ -21398,22 +21453,22 @@ break; } } preg->reginput = save + utf8_index(save, no); reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); - + if (reg_iseol(preg, nextch) || c == nextch) { if (regmatch(preg, next)) { return(1); } } if (matchmin) { - + no++; } else { - + no--; } } return(0); } @@ -21423,13 +21478,13 @@ int *scanpt = preg->program + scan; int max = scanpt[2]; int min = scanpt[3]; - + if (scanpt[4] < min) { - + scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; @@ -21438,39 +21493,39 @@ if (scanpt[4] > max) { return 0; } if (matchmin) { - + if (regmatch(preg, regnext(preg, scan))) { return 1; } - + scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; return 0; } - + if (scanpt[4] < max) { scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; } - + return regmatch(preg, regnext(preg, scan)); } static int regmatch(regex_t *preg, int prog) { - int scan; - int next; + int scan; + int next; const char *save; scan = prog; #ifdef DEBUG @@ -21480,11 +21535,11 @@ while (scan != 0) { int n; int c; #ifdef DEBUG if (regnarrate) { - fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); + fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); } #endif next = regnext(preg, scan); n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); @@ -21491,49 +21546,49 @@ switch (OP(preg, scan)) { case BOLX: if ((preg->eflags & REG_NOTBOL)) { return(0); } - + case BOL: if (preg->reginput != preg->regbol) { return(0); } break; case EOLX: if (c != 0) { - + return 0; } break; case EOL: if (!reg_iseol(preg, c)) { return(0); } break; case WORDA: - + if ((!isalnum(UCHAR(c))) && c != '_') return(0); - + if (preg->reginput > preg->regbol && (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) return(0); break; case WORDZ: - + if (preg->reginput > preg->regbol) { - + if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') { c = preg->reginput[-1]; - + if (isalnum(UCHAR(c)) || c == '_') { break; } } } - + return(0); case ANY: if (reg_iseol(preg, c)) return 0; @@ -21569,12 +21624,12 @@ case NOTHING: break; case BACK: break; case BRANCH: - if (OP(preg, next) != BRANCH) - next = OPERAND(scan); + if (OP(preg, next) != BRANCH) + next = OPERAND(scan); else { do { save = preg->reginput; if (regmatch(preg, OPERAND(scan))) { return(1); @@ -21581,11 +21636,11 @@ } preg->reginput = save; scan = regnext(preg, scan); } while (scan != 0 && OP(preg, scan) == BRANCH); return(0); - + } break; case REP: case REPMIN: return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN); @@ -21593,11 +21648,11 @@ case REPX: case REPXMIN: return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); case END: - return 1; + return 1; case OPENNC: case CLOSENC: return regmatch(preg, next); @@ -21640,11 +21695,11 @@ scan = preg->reginput; opnd = OPERAND(p); switch (OP(preg, p)) { case ANY: - + while (!reg_iseol(preg, *scan) && count < max) { count++; scan++; } break; @@ -21676,13 +21731,13 @@ } count++; scan += n; } break; - default: + default: preg->err = REG_ERR_INTERNAL; - count = 0; + count = 0; break; } preg->reginput = scan; return(count); @@ -21703,11 +21758,11 @@ return(p+offset); } static int regopsize(regex_t *preg, int p ) { - + switch (OP(preg, p)) { case REP: case REPMIN: case REPX: case REPXMIN: @@ -21764,223 +21819,10 @@ 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) #ifndef STRICT #define STRICT @@ -22037,26 +21879,26 @@ { DIR *dir = 0; if (name && name[0]) { size_t base_length = strlen(name); - const char *all = + const char *all = strchr("/\\", name[base_length - 1]) ? "*" : "/*"; if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 && (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1) dir->result.d_name = 0; - else { + else { Jim_Free(dir->name); Jim_Free(dir); dir = 0; } } - else { + else { Jim_Free(dir); dir = 0; errno = ENOMEM; } } @@ -22074,11 +21916,11 @@ if (dir->handle != -1) result = _findclose(dir->handle); Jim_Free(dir->name); Jim_Free(dir); } - if (result == -1) + if (result == -1) errno = EBADF; return result; } struct dirent *readdir(DIR * dir) @@ -22096,77 +21938,28 @@ } return result; } #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 #ifdef USE_LINENOISE #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_SYS_STAT_H - #include -#endif #include "linenoise.h" #else #define MAX_LINE_LEN 512 #endif -#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 - 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; +char *Jim_HistoryGetline(const char *prompt) +{ +#ifdef USE_LINENOISE + return linenoise(prompt); #else int len; char *line = malloc(MAX_LINE_LEN); fputs(prompt, stdout); @@ -22199,90 +21992,24 @@ } void Jim_HistorySave(const char *filename) { #ifdef USE_LINENOISE -#ifdef HAVE_UMASK - mode_t mask; - - mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); -#endif linenoiseHistorySave(filename); -#ifdef HAVE_UMASK - umask(mask); -#endif #endif } void Jim_HistoryShow(void) { #ifdef USE_LINENOISE - + int i; int len; char **history = linenoiseHistory(&len); for (i = 0; i < len; i++) { printf("%4d %s\n", i + 1, history[i]); } -#endif -} - -#ifdef USE_LINENOISE -struct JimCompletionInfo { - Jim_Interp *interp; - Jim_Obj *command; -}; - -static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata) -{ - struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata; - Jim_Obj *objv[2]; - int ret; - - objv[0] = info->command; - objv[1] = Jim_NewStringObj(info->interp, prefix, -1); - - ret = Jim_EvalObjVector(info->interp, 2, objv); - - - if (ret == JIM_OK) { - int i; - Jim_Obj *listObj = Jim_GetResult(info->interp); - int len = Jim_ListLength(info->interp, listObj); - for (i = 0; i < len; i++) { - linenoiseAddCompletion(comp, Jim_String(Jim_ListGetIndex(info->interp, listObj, i))); - } - } -} - -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) { @@ -22296,12 +22023,10 @@ int history_len = strlen(home) + sizeof("/.jim_history"); history_file = Jim_Alloc(history_len); snprintf(history_file, history_len, "%s/.jim_history", home); Jim_HistoryLoad(history_file); } - - Jim_HistorySetCompletion(interp, Jim_NewStringObj(interp, "tcl::autocomplete", -1)); #endif printf("Welcome to Jim version %d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1"); @@ -22330,21 +22055,21 @@ Jim_IncrRefCount(scriptObjPtr); while (1) { char state; char *line; - line = Jim_HistoryGetline(interp, prompt); + line = Jim_HistoryGetline(prompt); if (line == NULL) { if (errno == EINTR) { continue; } Jim_DecrRefCount(interp, scriptObjPtr); retcode = JIM_OK; goto out; } if (Jim_Length(scriptObjPtr) != 0) { - + Jim_AppendString(interp, scriptObjPtr, "\n", 1); } Jim_AppendString(interp, scriptObjPtr, line, -1); free(line); if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state)) @@ -22352,11 +22077,11 @@ snprintf(prompt, sizeof(prompt), "%c> ", state); } #ifdef USE_LINENOISE if (strcmp(Jim_String(scriptObjPtr), "h") == 0) { - + Jim_HistoryShow(); Jim_DecrRefCount(interp, scriptObjPtr); continue; } @@ -22379,11 +22104,10 @@ printf("%s\n", result); } } out: Jim_Free(history_file); - return retcode; } #include #include @@ -22396,11 +22120,11 @@ static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) { int n; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); - + for (n = 0; n < argc; n++) { Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); Jim_ListAppendElement(interp, listObj, obj); } @@ -22422,75 +22146,71 @@ printf("or : %s [options] [filename]\n", executable_name); printf("\n"); printf("Without options: Interactive mode\n"); printf("\n"); printf("Options:\n"); - printf(" --version : prints the version string\n"); - printf(" --help : prints this text\n"); - printf(" -e CMD : executes command CMD\n"); - printf(" NOTE: all subsequent options will be passed as arguments to the command\n"); - printf(" [filename|-] : executes the script contained in the named file, or from stdin if \"-\"\n"); - printf(" NOTE: all subsequent options will be passed to the script\n\n"); + printf(" --version : prints the version string\n"); + printf(" --help : prints this text\n"); + printf(" -e CMD : executes command CMD\n"); + printf(" NOTE: all subsequent options will be passed as arguments to the command\n"); + printf(" [filename] : executes the script contained in the named file\n"); + printf(" NOTE: all subsequent options will be passed to the script\n\n"); } int main(int argc, char *const argv[]) { int retcode; Jim_Interp *interp; char *const orig_argv0 = argv[0]; - + if (argc > 1 && strcmp(argv[1], "--version") == 0) { printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); return 0; } else if (argc > 1 && strcmp(argv[1], "--help") == 0) { usage(argv[0]); return 0; } - + interp = Jim_CreateInterp(); Jim_RegisterCoreCommands(interp); - + if (Jim_InitStaticExtensions(interp) != JIM_OK) { JimPrintErrorMessage(interp); } Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0); Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); retcode = Jim_initjimshInit(interp); if (argc == 1) { - + if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); } if (retcode != JIM_EXIT) { JimSetArgv(interp, 0, NULL); retcode = Jim_InteractivePrompt(interp); } } else { - + if (argc > 2 && strcmp(argv[1], "-e") == 0) { - + JimSetArgv(interp, argc - 3, argv + 3); retcode = Jim_Eval(interp, argv[2]); if (retcode != JIM_ERR) { printf("%s\n", Jim_String(Jim_GetResult(interp))); } } else { Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); JimSetArgv(interp, argc - 2, argv + 2); - if (strcmp(argv[1], "-") == 0) { - retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]"); - } else { - retcode = Jim_EvalFile(interp, argv[1]); - } + retcode = Jim_EvalFile(interp, argv[1]); } if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); } } Index: autosetup/pkg-config.tcl ================================================================== --- autosetup/pkg-config.tcl +++ autosetup/pkg-config.tcl @@ -1,35 +1,34 @@ # Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/ # All rights reserved # @synopsis: # -# The 'pkg-config' module allows package information to be found via 'pkg-config'. +# The 'pkg-config' module allows package information to be found via pkg-config # # If not cross-compiling, the package path should be determined automatically -# by 'pkg-config'. +# by pkg-config. # If cross-compiling, the default package path is the compiler sysroot. -# If the C compiler doesn't support '-print-sysroot', the path can be supplied -# by the '--sysroot' option or by defining 'SYSROOT'. +# If the C compiler doesn't support -print-sysroot, the path can be supplied +# by the --sysroot option or by defining SYSROOT. # -# 'PKG_CONFIG' may be set to use an alternative to 'pkg-config'. +# PKG_CONFIG may be set to use an alternative to pkg-config use cc module-options { sysroot:dir => "Override compiler sysroot for pkg-config search path" } # @pkg-config-init ?required? # -# Initialises the 'pkg-config' system. Unless '$required' is set to 0, -# it is a fatal error if a usable 'pkg-config' is not found . -# +# Initialises the pkg-config system. Unless required is set to 0, +# it is a fatal error if the pkg-config # This command will normally be called automatically as required, -# but it may be invoked explicitly if lack of 'pkg-config' is acceptable. +# but it may be invoked explicitly if lack of pkg-config is acceptable. # -# Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$required' is 0). +# Returns 1 if ok, or 0 if pkg-config not found/usable (only if required=0) # proc pkg-config-init {{required 1}} { if {[is-defined HAVE_PKG_CONFIG]} { return [get-define HAVE_PKG_CONFIG] } @@ -47,12 +46,12 @@ msg-result $version define PKG_CONFIG_VERSION $version set found 1 - if {[opt-str sysroot o]} { - define SYSROOT [file-normalize $o] + if {[opt-val sysroot] ne ""} { + define SYSROOT [file-normalize [opt-val sysroot]] msg-result "Using specified sysroot [get-define SYSROOT]" } elseif {[get-define build] ne [get-define host]} { if {[catch {exec-with-stderr [get-define CC] -print-sysroot} result errinfo] == 0} { # Use the compiler sysroot, if there is one define SYSROOT $result @@ -82,21 +81,21 @@ return $found } # @pkg-config module ?requirements? # -# Use 'pkg-config' to find the given module meeting the given requirements. +# Use pkg-config to find the given module meeting the given requirements. # e.g. # ## pkg-config pango >= 1.37.0 # -# If found, returns 1 and sets 'HAVE_PKG_PANGO' to 1 along with: +# If found, returns 1 and sets HAVE_PKG_PANGO to 1 along with: # ## PKG_PANGO_VERSION to the found version -## PKG_PANGO_LIBS to the required libs (--libs-only-l) +## PKG_PANGO_LIBS to the required libs (--libs-only-l) ## PKG_PANGO_LDFLAGS to the required linker flags (--libs-only-L) -## PKG_PANGO_CFLAGS to the required compiler flags (--cflags) +## PKG_PANGO_CFLAGS to the required compiler flags (--cflags) # # If not found, returns 0. # proc pkg-config {module args} { set ok [pkg-config-init] @@ -123,13 +122,13 @@ return 1 } # @pkg-config-get module setting # -# Convenience access to the results of 'pkg-config'. +# Convenience access to the results of pkg-config # -# For example, '[pkg-config-get pango CFLAGS]' returns -# the value of 'PKG_PANGO_CFLAGS', or '""' if not defined. +# For example, [pkg-config-get pango CFLAGS] returns +# the value of PKG_PANGO_CFLAGS, or "" if not defined. proc pkg-config-get {module name} { set prefix [feature-define-name $module PKG_] get-define ${prefix}_${name} "" } Index: autosetup/system.tcl ================================================================== --- autosetup/system.tcl +++ autosetup/system.tcl @@ -2,40 +2,35 @@ # All rights reserved # @synopsis: # # This module supports common system interrogation and options -# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. +# such as --host, --build, --prefix, and setting srcdir, builddir, and EXEEXT # -# It also support the "feature" naming convention, where searching -# for a feature such as 'sys/type.h' defines 'HAVE_SYS_TYPES_H'. +# It also support the 'feature' naming convention, where searching +# for a feature such as sys/type.h defines HAVE_SYS_TYPES_H # -# It defines the following variables, based on '--prefix' unless overridden by the user: +# It defines the following variables, based on --prefix unless overridden by the user: # ## datadir ## sysconfdir ## sharedstatedir ## localstatedir ## infodir ## mandir ## includedir -# -# If '--prefix' is not supplied, it defaults to '/usr/local' unless 'defaultprefix' is defined *before* -# including the 'system' module. - -if {[is-defined defaultprefix]} { - user-notice "Note: defaultprefix is deprecated. Use options-defaults to set default options" - options-defaults [list prefix [get-define defaultprefix]] -} + +# Do "define defaultprefix myvalue" to set the default prefix *before* the first "use" +set defaultprefix [get-define defaultprefix /usr/local] module-options [subst -noc -nob { host:host-alias => {a complete or partial cpu-vendor-opsys for the system where the application will run (defaults to the same value as --build)} build:build-alias => {a complete or partial cpu-vendor-opsys for the system where the application will be built (defaults to the result of running config.guess)} - prefix:dir=/usr/local => {the target directory for the build (default: '@default@')} + prefix:dir => {the target directory for the build (defaults to '$defaultprefix')} # These (hidden) options are supported for autoconf/automake compatibility exec-prefix: bindir: sbindir: @@ -46,26 +41,16 @@ datadir: libdir: sysconfdir: sharedstatedir: localstatedir: - runstatedir: maintainer-mode=0 dependency-tracking=0 - silent-rules=0 }] -# @check-feature name { script } -# -# defines feature '$name' to the return value of '$script', -# which should be 1 if found or 0 if not found. -# -# e.g. the following will define 'HAVE_CONST' to 0 or 1. -# -## check-feature const { -## cctest -code {const int _x = 0;} -## } +# Returns 1 if exists, or 0 if not +# proc check-feature {name code} { msg-checking "Checking for $name..." set r [uplevel 1 $code] define-feature $name $r if {$r} { @@ -76,54 +61,49 @@ return $r } # @have-feature name ?default=0? # -# Returns the value of feature '$name' if defined, or '$default' if not. -# -# See 'feature-define-name' for how the "feature" name -# is translated into the "define" name. +# Returns the value of the feature if defined, or $default if not. +# See 'feature-define-name' for how the feature name +# is translated into the define name. # proc have-feature {name {default 0}} { get-define [feature-define-name $name] $default } # @define-feature name ?value=1? # -# Sets the feature 'define' to '$value'. -# -# See 'feature-define-name' for how the "feature" name -# is translated into the "define" name. +# Sets the feature 'define' to the given value. +# See 'feature-define-name' for how the feature name +# is translated into the define name. # proc define-feature {name {value 1}} { define [feature-define-name $name] $value } # @feature-checked name # -# Returns 1 if feature '$name' has been checked, whether true or not. +# Returns 1 if the feature has been checked, whether true or not # proc feature-checked {name} { is-defined [feature-define-name $name] } # @feature-define-name name ?prefix=HAVE_? # -# Converts a "feature" name to the corresponding "define", -# e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'. +# Converts a name to the corresponding define, +# e.g. sys/stat.h becomes HAVE_SYS_STAT_H. # -# Converts '*' to 'P' and all non-alphanumeric to underscore. +# Converts * to P and all non-alphanumeric to underscore. # proc feature-define-name {name {prefix HAVE_}} { string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] } -# @write-if-changed filename contents ?script? -# -# If '$filename' doesn't exist, or it's contents are different to '$contents', -# the file is written and '$script' is evaluated. -# +# If $file doesn't exist, or it's contents are different than $buf, +# the file is written and $script is executed. # Otherwise a "file is unchanged" message is displayed. proc write-if-changed {file buf {script {}}} { set old [readfile $file ""] if {$old eq $buf && [file exists $file]} { msg-result "$file is unchanged" @@ -131,141 +111,41 @@ writefile $file $buf\n uplevel 1 $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' -# (unless unchanged). -# If '$outfile' is blank/omitted, '$template' should end with '.in' which +# Reads the input file /$template and writes the output file $outfile. +# If $outfile is blank/omitted, $template should end with ".in" which # is removed to create the output file name. # -# Each pattern of the form '@define@' is replaced with the corresponding -# "define", if it exists, or left unchanged if not. -# -# The special value '@srcdir@' is substituted with the relative +# 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 +# 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 eq "value" +## @if name == value ## lines ## @else ## lines ## @endif # -# Where 'NAME' is a defined variable name and '@else' is optional. -# Note that variables names *must* start with an uppercase letter. +# Where 'name' is a defined variable name and @else is optional. # If the expression does not match, all lines through '@endif' are ignored. # # The alternative forms may also be used: -## @if NAME (true if the variable is defined, but not empty and not "0") -## @if !NAME (opposite of the form above) -## @if -# -# In the general Tcl expression, any words beginning with an uppercase letter -# are translated into [get-define NAME] -# -# Expressions may be nested +## @if name +## @if name != value +# +# Where the first form is true if the variable is defined, but not empty or 0 +# +# Currently these expressions can't be nested. # proc make-template {template {out {}}} { set infile [file join $::autosetup(srcdir) $template] if {![file exists $infile]} { @@ -289,42 +169,61 @@ # Set up srcdir and top_srcdir to be relative to the target dir define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] define top_srcdir [relative-path $::autosetup(srcdir) $outdir] - # 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 - } - 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]" - } + 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 + } + 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 + } + write-if-changed $out [string map $mapping [join $result \n]]\n { + msg-result "Created [relative-path $out] from [relative-path $template]" + } } # build/host tuples and cross-compilation prefix -opt-str build build "" +set build [opt-val build] define build_alias $build if {$build eq ""} { define build [config_guess] } else { define build [config_sub $build] } -opt-str host host "" +set host [opt-val host] define host_alias $host if {$host eq ""} { define host [get-define build] set cross "" } else { @@ -331,68 +230,45 @@ define host [config_sub $host] set cross $host- } define cross [get-env CROSS $cross] -# build/host _cpu, _vendor and _os -foreach type {build host} { - set v [get-define $type] - if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { - user-error "Invalid canonical $type: $v" - } - define ${type}_cpu $cpu - define ${type}_vendor $vendor - define ${type}_os $os -} - -opt-str prefix prefix /usr/local +set prefix [opt-val prefix $defaultprefix] # These are for compatibility with autoconf define target [get-define host] define prefix $prefix define builddir $autosetup(builddir) define srcdir $autosetup(srcdir) -define top_srcdir $autosetup(srcdir) -define abs_top_srcdir [file-normalize $autosetup(srcdir)] -define abs_top_builddir [file-normalize $autosetup(builddir)] +# Allow this to come from the environment +define top_srcdir [get-env top_srcdir [get-define srcdir]] # autoconf supports all of these -define exec_prefix [opt-str exec-prefix exec_prefix $prefix] +set exec_prefix [opt-val exec-prefix $prefix] +define exec_prefix $exec_prefix foreach {name defpath} { bindir /bin sbindir /sbin libexecdir /libexec libdir /lib } { - define $name [opt-str $name o $exec_prefix$defpath] + define $name [opt-val $name $exec_prefix$defpath] } foreach {name defpath} { datadir /share + sysconfdir /etc sharedstatedir /com + localstatedir /var infodir /share/info mandir /share/man includedir /include } { - define $name [opt-str $name o $prefix$defpath] -} -if {$prefix ne {/usr}} { - opt-str sysconfdir sysconfdir $prefix/etc -} else { - opt-str sysconfdir sysconfdir /etc -} -define sysconfdir $sysconfdir - -define localstatedir [opt-str localstatedir o /var] -define runstatedir [opt-str runstatedir o /run] + define $name [opt-val $name $prefix$defpath] +} define SHELL [get-env SHELL [find-an-executable sh bash ksh]] -# These could be used to generate Makefiles following some automake conventions -define AM_SILENT_RULES [opt-bool silent-rules] -define AM_MAINTAINER_MODE [opt-bool maintainer-mode] -define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] - # Windows vs. non-Windows switch -glob -- [get-define host] { *-*-ming* - *-*-cygwin - *-*-msys { define-feature windows define EXEEXT .exe ADDED autosetup/test-tclsh Index: autosetup/test-tclsh ================================================================== --- autosetup/test-tclsh +++ autosetup/test-tclsh @@ -0,0 +1,20 @@ +# A small Tcl script to verify that the chosen +# interpreter works. Sometimes we might e.g. pick up +# an interpreter for a different arch. +# Outputs the full path to the interpreter + +if {[catch {info version} version] == 0} { + # This is Jim Tcl + if {$version >= 0.72} { + # Ensure that regexp works + regexp (a.*?) a + puts [info nameofexecutable] + exit 0 + } +} elseif {[catch {info tclversion} version] == 0} { + if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { + puts [info nameofexecutable] + exit 0 + } +} +exit 1 Index: autosetup/tmake.auto ================================================================== --- autosetup/tmake.auto +++ autosetup/tmake.auto @@ -21,35 +21,46 @@ cc-check-tools ar ranlib set objdir [get-env BUILDDIR objdir] make-config-header $objdir/include/autoconf.h -make-tmake-settings $objdir/settings.conf {[A-Z]*} *dir lib_* +make-tmake-settings $objdir/settings.conf {[A-Z]*} } autosetup_check_create project.spec \ {# Initial project.spec created by 'autosetup --init=tmake' -tmake-require-version 0.7.3 - # vim:set syntax=tcl: define? DESTDIR _install # XXX If configure creates additional/different files than include/autoconf.h # that should be reflected here -Autosetup include/autoconf.h + +# We use [set AUTOREMAKE] here to avoid rebuilding settings.conf +# if the AUTOREMAKE command changes +Depends {settings.conf include/autoconf.h} auto.def -msg {note Configuring...} -do { + run [set AUTOREMAKE] >$build/config.out +} -onerror {puts [readfile $build/config.out]} -fatal +Clean config.out +DistClean --source config.log +DistClean settings.conf include/autoconf.h + +# If not configured, configure with default options +# Note that it is expected that configure will normally be run +# separately. This is just a convenience for a host build +define? AUTOREMAKE configure TOPBUILDDIR=$TOPBUILDDIR --conf=auto.def + +Load settings.conf -# e.g. for autoconf.h +# e.g. for up autoconf.h IncludePaths include -ifconfig !CONFIGURED { - # Not configured, so don't process subdirs - AutoSubDirs off - # And don't process this file any further - ifconfig false -} +ifconfig CONFIGURED + +# Hmmm, but should we turn off AutoSubDirs? +#AutoSubDirs off } if {![file exists build.spec]} { puts "Note: I don't see build.spec. Try running: tmake --genie" } } Index: autosetup/tmake.tcl ================================================================== --- autosetup/tmake.tcl +++ autosetup/tmake.tcl @@ -15,21 +15,21 @@ define CONFIGURED # @make-tmake-settings outfile patterns ... # -# Examines all defined variables which match the given patterns (defaults to '*') +# Examines all defined variables which match the given patterns (defaults to "*") # and writes a tmake-compatible .conf file defining those variables. -# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include: +# For example, if ABC is "3 monkeys" and ABC matches a pattern, then the file will include: # ## define ABC {3 monkeys} # # If the file would be unchanged, it is not written. # # Typical usage is: # -## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} +# make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} proc make-tmake-settings {file args} { file mkdir [file dirname $file] set lines {} if {[llength $args] == 0} { Index: compat/zlib/CMakeLists.txt ================================================================== --- compat/zlib/CMakeLists.txt +++ compat/zlib/CMakeLists.txt @@ -1,11 +1,14 @@ cmake_minimum_required(VERSION 2.4.4) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) -set(VERSION "1.2.13") +set(VERSION "1.2.11") + +option(ASM686 "Enable building i686 assembly implementation") +option(AMD64 "Enable building amd64 assembly implementation") set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") @@ -123,10 +126,43 @@ if(NOT MINGW) set(ZLIB_DLL_SRCS win32/zlib1.rc # If present will override custom build rule below. ) endif() + +if(CMAKE_COMPILER_IS_GNUCC) + if(ASM686) + set(ZLIB_ASMS contrib/asm686/match.S) + elseif (AMD64) + set(ZLIB_ASMS contrib/amd64/amd64-match.S) + endif () + + if(ZLIB_ASMS) + add_definitions(-DASMV) + set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) + endif() +endif() + +if(MSVC) + if(ASM686) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx86/inffas32.asm + contrib/masmx86/match686.asm + ) + elseif (AMD64) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx64/gvmat64.asm + contrib/masmx64/inffasx64.asm + ) + endif() + + if(ZLIB_ASMS) + add_definitions(-DASMV -DASMINF) + endif() +endif() # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) @@ -145,12 +181,12 @@ -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) endif(MINGW) -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) set_target_properties(zlib PROPERTIES SOVERSION 1) if(NOT CYGWIN) # This property causes shared libraries on Linux to have the full version Index: compat/zlib/ChangeLog ================================================================== --- compat/zlib/ChangeLog +++ compat/zlib/ChangeLog @@ -1,83 +1,8 @@ ChangeLog file for zlib -Changes in 1.2.13 (13 Oct 2022) -- Fix configure issue that discarded provided CC definition -- Correct incorrect inputs provided to the CRC functions -- Repair prototypes and exporting of new CRC functions -- Fix inflateBack to detect invalid input with distances too far -- Have infback() deliver all of the available output up to any error -- Fix a bug when getting a gzip header extra field with inflate() -- Fix bug in block type selection when Z_FIXED used -- Tighten deflateBound bounds -- Remove deleted assembler code references -- Various portability and appearance improvements - -Changes in 1.2.12 (27 Mar 2022) -- Cygwin does not have _wopen(), so do not create gzopen_w() there -- Permit a deflateParams() parameter change as soon as possible -- Limit hash table inserts after switch from stored deflate -- Fix bug when window full in deflate_stored() -- Fix CLEAR_HASH macro to be usable as a single statement -- Avoid a conversion error in gzseek when off_t type too small -- Have Makefile return non-zero error code on test failure -- Avoid some conversion warnings in gzread.c and gzwrite.c -- Update use of errno for newer Windows CE versions -- Small speedup to inflate [psumbera] -- Return an error if the gzputs string length can't fit in an int -- Add address checking in clang to -w option of configure -- Don't compute check value for raw inflate if asked to validate -- Handle case where inflateSync used when header never processed -- Avoid the use of ptrdiff_t -- Avoid an undefined behavior of memcpy() in gzappend() -- Avoid undefined behaviors of memcpy() in gz*printf() -- Avoid an undefined behavior of memcpy() in _tr_stored_block() -- Make the names in functions declarations identical to definitions -- Remove old assembler code in which bugs have manifested -- Fix deflateEnd() to not report an error at start of raw deflate -- Add legal disclaimer to README -- Emphasize the need to continue decompressing gzip members -- Correct the initialization requirements for deflateInit2() -- Fix a bug that can crash deflate on some input when using Z_FIXED -- Assure that the number of bits for deflatePrime() is valid -- Use a structure to make globals in enough.c evident -- Use a macro for the printf format of big_t in enough.c -- Clean up code style in enough.c, update version -- Use inline function instead of macro for index in enough.c -- Clarify that prefix codes are counted in enough.c -- Show all the codes for the maximum tables size in enough.c -- Add gznorm.c example, which normalizes gzip files -- Fix the zran.c example to work on a multiple-member gzip file -- Add tables for crc32_combine(), to speed it up by a factor of 200 -- Add crc32_combine_gen() and crc32_combine_op() for fast combines -- Speed up software CRC-32 computation by a factor of 1.5 to 3 -- Use atomic test and set, if available, for dynamic CRC tables -- Don't bother computing check value after successful inflateSync() -- Correct comment in crc32.c -- Add use of the ARMv8 crc32 instructions when requested -- Use ARM crc32 instructions if the ARM architecture has them -- Explicitly note that the 32-bit check values are 32 bits -- Avoid adding empty gzip member after gzflush with Z_FINISH -- Fix memory leak on error in gzlog.c -- Fix error in comment on the polynomial representation of a byte -- Clarify gz* function interfaces, referring to parameter names -- Change macro name in inflate.c to avoid collision in VxWorks -- Correct typo in blast.c -- Improve portability of contrib/minizip -- Fix indentation in minizip's zip.c -- Replace black/white with allow/block. (theresa-m) -- minizip warning fix if MAXU32 already defined. (gvollant) -- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner) -- Clean up minizip to reduce warnings for testing -- Add fallthrough comments for gcc -- Eliminate use of ULL constants -- Separate out address sanitizing from warnings in configure -- Remove destructive aspects of make distclean -- Check for cc masquerading as gcc or clang in configure -- Fix crc32.c to compile local functions only if used - Changes in 1.2.11 (15 Jan 2017) - Fix deflate stored bug when pulling last block from window - Permit immediate deflateParams changes before any deflate input Changes in 1.2.10 (2 Jan 2017) @@ -169,11 +94,11 @@ - Don't specify --version-script on Apple platforms in CMakeLists.txt - Fix casting error in contrib/testzlib/testzlib.c - Fix types in contrib/minizip to match result of get_crc_table() - Simplify contrib/vstudio/vc10 with 'd' suffix - Add TOP support to win32/Makefile.msc -- Support i686 and amd64 assembler builds in CMakeLists.txt +- Suport i686 and amd64 assembler builds in CMakeLists.txt - Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h - Add vc11 and vc12 build files to contrib/vstudio - Add gzvprintf() as an undocumented function in zlib - Fix configure for Sun shell - Remove runtime check in configure for four-byte integer type @@ -369,18 +294,18 @@ - Clarify the use of Z_FINISH with deflateBound() amount of space - Set binary for output file in puff.c - Use u4 type for crc_table to avoid conversion warnings - Apply casts in zlib.h to avoid conversion warnings - Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminacy +- Improve inflateSync() documentation to note indeterminancy - Add deflatePending() function to return the amount of pending output - Correct the spelling of "specification" in FAQ [Randers-Pehrson] - Add a check in configure for stdarg.h, use for gzprintf() - Check that pointers fit in ints when gzprint() compiled old style - Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] - Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assembler code [Londer] +- Add debug records in assmebler code [Londer] - Update RFC references to use http://tools.ietf.org/html/... [Li] - Add --archs option, use of libtool to configure for Mac OS X [Borstel] Changes in 1.2.5 (19 Apr 2010) - Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] @@ -584,11 +509,11 @@ - Replace use of errno in gz* with functions, support WinCE [Alves] - Provide alternative to perror() in minigzip.c for WinCE [Alves] - Don't use _vsnprintf on later versions of MSVC [Lowman] - Add CMake build script and input file [Lowman] - Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to root +- Moved nintendods directory from contrib to . - Replace gzio.c with a new set of routines with the same functionality - Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above - Update contrib/minizip to 1.1b - Change gzeof() to return 0 on error instead of -1 to agree with zlib.h @@ -758,11 +683,11 @@ - Update make_vms.com [Zinser] - Initialize state->write in inflateReset() since copied in inflate_fast() - Be more strict on incomplete code sets in inflate_table() and increase ENOUGH and MAXD -- this repairs a possible security vulnerability for invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases + discovering the vulnerability and providing test cases. - Add ia64 support to configure for HP-UX [Smith] - Add error return to gzread() for format or i/o error [Levin] - Use malloc.h for OS/2 [Necasek] Changes in 1.2.2.3 (27 May 2005) @@ -794,11 +719,11 @@ - Improve WinCE errno handling and comments [Chang] - Remove comment about no gzip header processing in FAQ - Add Z_FIXED strategy option to deflateInit2() to force fixed trees - Add updated make_vms.com [Coghlan], update README - Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. - Add FAQ entry and comments in deflate.c on uninitialized memory access - Add Solaris 9 make options in configure [Gilbert] - Allow strerror() usage in gzio.c for STDC - Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] - Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] @@ -865,11 +790,11 @@ - Update email address in README - Several FAQ updates - Fix a big fat bug in inftrees.c that prevented decoding valid dynamic blocks with only literals and no distance codes -- Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case +- Add a note to puff.c on no distance codes case. Changes in 1.2.1 (17 November 2003) - Remove a tab in contrib/gzappend/gzappend.c - Update some interfaces in contrib for new zlib functions - Update zlib version number in some contrib entries @@ -1043,11 +968,11 @@ - Refine detection of Turbo C need for dummy returns - Refine ZLIB_DLL compilation - Include additional header file on VMS for off_t typedef - Try to use _vsnprintf where it supplants vsprintf [Vollant] - Add some casts in inffast.c -- Enhance comments in zlib.h on what happens if gzprintf() tries to +- Enchance comments in zlib.h on what happens if gzprintf() tries to write more than 4095 bytes before compression - Remove unused state from inflateBackEnd() - Remove exit(0) from minigzip.c, example.c - Get rid of all those darn tabs - Add "check" target to Makefile.in that does the same thing as "test" @@ -1109,18 +1034,18 @@ - Add contrib/inflate86/ for x86 faster inflate - Add contrib/blast/ for PKWare Data Compression Library decompression - Add contrib/puff/ simple inflate for deflate format description Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions +- ZFREE was repeated on same allocation on some error conditions. This creates a security problem described in http://www.zlib.org/advisory-2002-03-11.txt - Returned incorrect error (Z_MEM_ERROR) on some invalid data - Avoid accesses before window for invalid distances with inflate window - less than 32K + less than 32K. - force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5) + of 256 bytes. (A complete fix will be available in 1.1.5). Changes in 1.1.3 (9 July 1998) - fix "an inflate input buffer bug that shows up on rare but persistent occasions" (Mark) - fix gzread and gztell for concatenated .gz files (Didier Le Botlan) @@ -1190,11 +1115,11 @@ Changes in 1.1.1 (27 Feb 98) - fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) - remove block truncation heuristic which had very marginal effect for zlib (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow + matches in deflate_slow. - added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) Changes in 1.1.0 (24 Feb 98) - do not return STREAM_END prematurely in inflate (John Bowler) - revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) @@ -1221,11 +1146,11 @@ . Simplify Z_FINISH check in inflate() - Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 - in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) - in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles Vollant) + the declaration of FAR (Gilles VOllant) - install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) - read_buf buf parameter of type Bytef* instead of charf* - zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) - do not redeclare unlink in minigzip.c for WIN32 (John Bowler) - fix check for presence of directories in "make install" (Ian Willis) @@ -1235,11 +1160,11 @@ - fix gzgetc and gzputc for big endian systems (Markus Oberhumer) - added compress2() to allow setting the compression level - include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) - use constant arrays for the static trees in trees.c instead of computing them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test" + trees.h, compile with GEN_TREES_H and run "make test". - check return code of example in "make test" and display result - pass minigzip command line options to file_compress - simplifying code of inflateSync to avoid gcc 2.8 bug - support CC="gcc -Wall" in configure -s (QingLong) @@ -1274,16 +1199,16 @@ Changes in 1.0.6 (19 Jan 1998) - add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) - Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one) -- In minigzip, pass transparently also the first byte for .Z files + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. - return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() - check Z_FINISH in inflate (thanks to Marc Schluper) - Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option +- make static libraries by default in configure, add --shared option. - move MSDOS or Windows specific files to directory msdos - suppress the notion of partial flush to simplify the interface (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) - suppress history buffer provided by application to simplify the interface (this feature was not implemented anyway in 1.0.4) @@ -1291,29 +1216,29 @@ inflateInit2 - add EXPORT in all exported functions (for Windows DLL) - added Makefile.nt (thanks to Stephen Williams) - added the unsupported "contrib" directory: contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match() + 386 asm code replacing longest_match(). contrib/iostream/ by Kevin Ruland A C++ I/O streams interface to the zlib gz* functions contrib/iostream2/ by Tyge Løvset Another C++ I/O streams interface contrib/untgz/ by "Pedro A. Aranda Guti\irrez" A very simple tar.gz file extractor using zlib contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB + How to use compress(), uncompress() and the gz* functions from VB. - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression level) in minigzip (thanks to Tom Lane) - use const for rommable constants in deflate - added test for gzseek and gztell in example.c - add undocumented function inflateSyncPoint() (hack for Paul Mackerras) - add undocumented function zError to convert error code to string (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code -- Use default memcpy for Symantec MSDOS compiler +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. - Add EXPORT keyword for check_func (needed for Windows DLL) - add current directory to LD_LIBRARY_PATH for "make test" - create also a link for libz.so.1 - added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) - use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) @@ -1322,21 +1247,21 @@ - add advice in zlib.h for best usage of deflateSetDictionary - work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) - allow compilation with ANSI keywords only enabled for TurboC in large model - avoid "versionString"[0] (Borland bug) - add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch) +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). - allow compilation with CC - defined STDC for OS/2 (David Charlap) - limit external names to 8 chars for MVS (Thomas Lund) - in minigzip.c, use static buffers only for 16-bit systems - fix suffix check for "minigzip -d foo.gz" - do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) - added makelcc.bat for lcc-win32 (Tom St Denis) - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. - check for unistd.h in configure (for off_t) - remove useless check parameter in inflate_blocks_free - avoid useless assignment of s->check to itself in inflate_blocks_new - do not flush twice in gzclose (thanks to Ken Raeburn) - rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h @@ -1353,11 +1278,11 @@ - Update web address in README Changes in 1.0.4 (24 Jul 96) - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too + on to attempt decompressing extra garbage data. This affected minigzip too. - zlibVersion and gzerror return const char* (needed for DLL) - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) - use z_error only for DEBUG (avoid problem with DLLs) Changes in 1.0.3 (2 Jul 96) @@ -1383,11 +1308,11 @@ Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] - fix array overlay in deflate.c which sometimes caused bad compressed data - fix inflate bug with empty stored block - fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generate bad compressed data +- fix deflateParams() which could generate bad compressed data. - Bytef is define'd instead of typedef'ed (work around Borland bug) - added an INDEX file - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) - speed up adler32 for modern machines without auto-increment @@ -1404,11 +1329,11 @@ Changes in 0.99 (27 Jan 96) - allow preset dictionary shared between compressor and decompressor - allow compression level 0 (no compression) - add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy + and compression strategy. - test large buffers and deflateParams in example.c - add optional "configure" to build zlib as a shared library - suppress Makefile.qnx, use configure instead - fixed deflate for 64-bit systems (detected on Cray) - fixed inflate_blocks for 64-bit systems (detected on Alpha) @@ -1446,48 +1