diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2013-04-05 08:46:23 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2013-04-05 08:46:23 (GMT) |
commit | 859eff84db9b495f0a1b3f31891771cf97ef84b0 (patch) | |
tree | f5f6fac2cbc9a9062c2bd4baabdf6ade4b560dd3 | |
parent | 38dfb78b4e41733a7390a1c787ea7ab0fd95c8d1 (diff) | |
parent | e6f4d201ce9edec15fbdefbf5f3711afee040743 (diff) | |
download | tcl-859eff84db9b495f0a1b3f31891771cf97ef84b0.zip tcl-859eff84db9b495f0a1b3f31891771cf97ef84b0.tar.gz tcl-859eff84db9b495f0a1b3f31891771cf97ef84b0.tar.bz2 |
merge trunk
173 files changed, 5021 insertions, 3624 deletions
diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob new file mode 100644 index 0000000..ca85874 --- /dev/null +++ b/.fossil-settings/binary-glob @@ -0,0 +1,3 @@ +*.bmp +*.gif +*.png diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.fossil-settings/crnl-glob diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob new file mode 100644 index 0000000..9ed86b1 --- /dev/null +++ b/.fossil-settings/ignore-glob @@ -0,0 +1,24 @@ +*.a +*.dll +*.dylib +*.exe +*.exp +*.lib +*.o +*.obj +*.res +*.sl +*.so +*/Makefile +*/config.cache +*/config.log +*/config.status +*/tclConfig.sh +*/tclsh* +*/tcltest* +*/versions.vc +unix/dltest.marker +unix/tcl.pc +unix/pkgs/* +win/pkgs/* +win/tcl.hpj diff --git a/.project b/.project new file mode 100644 index 0000000..358cc74 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>tcl8.6</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + </buildSpec> + <natures> + </natures> +</projectDescription> diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/<project>=UTF-8 diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 0000000..5a0ad22 --- /dev/null +++ b/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n @@ -1,16 +1,304 @@ +2013-04-04 Reinhard Max <max@suse.de> + + * library/http/http.tcl (http::geturl): Allow URLs that don't have + a path, but a query query, e.g. http://example.com?foo=bar . + * Bump the http package to 2.8.7. + +2013-03-22 Venkat Iyer <venkat@comit.com> + * library/tzdata/Africa/Cairo: Update to tzdata2013b. + * library/tzdata/Africa/Casablanca: + * library/tzdata/Africa/Gaborone: + * library/tzdata/Africa/Tripoli: + * library/tzdata/America/Asuncion: + * library/tzdata/America/Barbados: + * library/tzdata/America/Bogota: + * library/tzdata/America/Costa_Rica: + * library/tzdata/America/Curacao: + * library/tzdata/America/Nassau: + * library/tzdata/America/Port-au-Prince: + * library/tzdata/America/Santiago: + * library/tzdata/Antarctica/Palmer: + * library/tzdata/Asia/Aden: + * library/tzdata/Asia/Hong_Kong: + * library/tzdata/Asia/Muscat: + * library/tzdata/Asia/Rangoon: + * library/tzdata/Asia/Shanghai: + * library/tzdata/Atlantic/Bermuda: + * library/tzdata/Europe/Vienna: + * library/tzdata/Pacific/Easter: + * library/tzdata/Pacific/Fiji: + * library/tzdata/Asia/Khandyga: (new) + * library/tzdata/Asia/Ust-Nera: (new) + * library/tzdata/Europe/Busingen: (new) + +2013-03-21 Don Porter <dgp@users.sourceforge.net> + + * library/auto.tcl: [Bug 2102614] Add ensemble indexing support + * tests/autoMkindex.test: to [auto_mkindex]. Thanks Brian Griffin. + +2013-03-19 Don Porter <dgp@users.sourceforge.net> + + * generic/tclFCmd.c: [Bug 3597000] Consistent [file copy] result. + * tests/fileSystem.test: + +2013-03-19 Jan Nijtmans <nijtmans@users.sf.net> + + * win/tclWinFile.c: [Bug 3608360]: Incompatible behaviour of "file + exists". + +2013-03-18 Donal K. Fellows <dkf@users.sf.net> + + * tests/cmdAH.test (cmdAH-19.12): [Bug 3608360]: Added test to ensure + that we never ever allow [file exists] to do globbing. + +2013-03-12 Jan Nijtmans <nijtmans@users.sf.net> + + * unix/tcl.m4: Patch by Andrew Shadura, providing better support for + three architectures they have in Debian. + +2013-03-11 Don Porter <dgp@users.sourceforge.net> + + * generic/tclCompile.c: [Bugs 3607246,3607372] Unbalanced refcounts + * generic/tclLiteral.c: of literals in the global literal table. + +2013-03-06 Don Porter <dgp@users.sourceforge.net> + + * generic/regc_nfa.c: [Bugs 3604074,3606683] Rewrite of the + * generic/regcomp.c: fixempties() routine (and supporting + routines) to completely eliminate the infinite loop hazard. + Thanks to Tom Lane for the much improved solution. + +2013-02-28 Don Porter <dgp@users.sourceforge.net> + + * generic/tclLiteral.c: Revise TclReleaseLiteral() to tolerate a + NULL interp argument. + + * generic/tclCompile.c: Update callers and revise mistaken comments. + * generic/tclProc.c: + +2013-02-27 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/regcomp.c: [Bug 3606139]: missing error check allows + * tests/regexp.test: regexp to crash Tcl. Thanks to Tom Lane for + providing the test-case and the patch. + +2013-02-26 Donal K. Fellows <dkf@users.sf.net> + + * tests/chanio.test (chan-io-28.7): [Bug 3605120]: Stop test from + hanging when run standalone. + +2013-02-26 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclObj.c: Don't panic if Tcl_ConvertToType is called for a + type that doesn't have a setFromAnyProc, create a proper error message. + +2013-02-25 Donal K. Fellows <dkf@users.sf.net> + + * tests/binary.test (binary-41.*): [Bug 3605721]: Test independence + fixes. Thanks to Rolf Ade for pointing out the problem. + +2013-02-25 Don Porter <dgp@users.sourceforge.net> + + * tests/assocd.test: [Bugs 3605719,3605720]: Test independence. + * tests/basic.test: Thanks Rolf Ade for patches. + +2013-02-23 Jan Nijtmans <nijtmans@users.sf.net> + + * compat/fake-rfc2553.c: [Bug 3599194]: compat/fake-rfc2553.c is + broken. + +2013-02-22 Don Porter <dgp@users.sourceforge.net> + + * generic/tclAssembly.c: Shift more burden of smart cleanup + * generic/tclCompile.c: onto the TclFreeCompileEnv() routine. + Stop crashes when the hookProc raises an error. + +2013-02-20 Don Porter <dgp@users.sourceforge.net> + + * generic/tclNamesp.c: [Bug 3605447]: Make sure the -clear option + * tests/namespace.test: to [namespace export] always clears, whether + or not new export patterns are specified. + +2013-02-20 Jan Nijtmans <nijtmans@users.sf.net> + + * win/tclWinDde.c: [Bug 3605401]: Compiler error with latest mingw-w64 + headers. + +2013-02-19 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclTrace.c: [Bug 2438181]: Incorrect error reporting in + * tests/trace.test: traces. Test-case and fix provided by Poor + Yorick. + +2013-02-15 Don Porter <dgp@users.sourceforge.net> + + * generic/regc_nfa.c: [Bug 3604074]: Fix regexp optimization to + * tests/regexp.test: stop hanging on the expression + ((((((((a)*)*)*)*)*)*)*)* . Thanks to Bjørn Grathwohl for discovery. + +2013-02-14 Harald Oehlmann <oehhar@users.sf.net> + + * library/msgcat/msgcat.tcl: [Bug 3604576]: Catch missing registry + entry "HCU\Control Panel\International". + Bumped msgcat version to 1.5.1 + +2013-02-11 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclZlib.c (ZlibTransformOutput): [Bug 3603553]: Ensure that + data gets written to the underlying stream by compressing transforms + when the amount of data to be written is one buffer's-worth; problem + was particularly likely to occur when compressing large quantities of + not-very-compressible data. Many thanks to Piera Poggio (vampiera) for + reporting. + +2013-02-09 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclOOBasic.c (TclOO_Object_VarName): [Bug 3603695]: Change + the way that the 'varname' method is implemented so that there are no + longer problems with interactions due to the resolver. Thanks to + Taylor Venable <tcvena@gmail.com> for identifying the problem. + +2013-02-08 Donal K. Fellows <dkf@users.sf.net> + + * generic/regc_nfa.c (duptraverse): [Bug 3603557]: Increase the + maximum depth of recursion used when duplicating an automaton in + response to encountering a "wild" RE that hit the previous limit. + Allow the limit (DUPTRAVERSE_MAX_DEPTH) to be set by defining its + value in the Makefile. Problem reported by Jonathan Mills. + +2013-02-05 Don Porter <dgp@users.sourceforge.net> + + * win/tclWinFile.c: [Bug 3603434]: Make sure TclpObjNormalizePath() + properly declares "a:/" to be normalized, even when no "A:" drive is + present on the system. + +2013-02-05 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclLoadNone.c (TclpLoadMemory): [Bug 3433012]: Added dummy + version of this function to use in the event that a platform thinks it + can load from memory but cannot actually do so due to it being + disabled at configuration time. + +2013-02-04 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclCompCmds.c (TclCompileArraySetCmd): [Bug 3603163]: Stop + crash in weird case where [eval] is used to make [array set] get + confused about whether there is a local variable table or not. Thanks + to Poor Yorick for identifying a reproducible crashing case. + +2013-01-30 Andreas Kupries <andreask@activestate.com> + + * library/platform/platform.tcl (::platform::LibcVersion): See + * library/platform/pkgIndex.tcl: [Bug 3599098]: Fixed the RE + * unix/Makefile.in: extracting the version to avoid issues with + * win/Makefile.in: recent changes to the glibc banner. Now targeting a + less variable part of the string. Bumped package to version 1.0.11. + +2013-01-28 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclCompCmds.c (TclCompileArraySetCmd) + (TclCompileArrayUnsetCmd, TclCompileDictAppendCmd) + (TclCompileDictCreateCmd, CompileDictEachCmd, TclCompileDictIncrCmd) + (TclCompileDictLappendCmd, TclCompileDictMergeCmd) + (TclCompileDictUnsetCmd, TclCompileDictUpdateCmd) + (TclCompileDictWithCmd, TclCompileInfoCommandsCmd): + * generic/tclCompCmdsSZ.c (TclCompileStringMatchCmd) + (TclCompileStringMapCmd): Improve the code generation in cases where + full compilation is impossible but a full ensemble invoke is provably + not necessary. + +2013-01-26 Jan Nijtmans <nijtmans@users.sf.net> + + * unix/tclUnixCompat.c: [Bug 3601804]: platformCPUID segmentation + fault on Darwin. + +2013-01-23 Donal K. Fellows <dkf@users.sf.net> + + * library/http/http.tcl (http::geturl): [Bug 2911139]: Do not do vwait + for connect to avoid reentrancy problems (except when operating + without a -command option). Internally, this means that all sockets + created by the http package will always be operated in asynchronous + mode. + +2013-01-21 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclInt.decls: Put back Tcl[GS]etStartupScript(Path|FileName) + in private stub table, so extensions using this (like Tk 8.4) will + continue to work in all Tcl 8.x versions. Extensions using this + still cannot be compiled against Tcl 8.6 headers. + +2013-01-18 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclPort.h: [Bug 3598300]: unix: tcl.h does not include + sys/stat.h + +2013-01-17 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclCompCmds.c (PushVarName): [Bug 3600328]: Added mechanism + for suppressing compilation of variables when we couldn't cope with + the results. Useful for some [array] subcommands. + * generic/tclEnsemble.c (CompileToCompiledCommand): Must restore the + compilation environment when a command compiler fails. + +2013-01-16 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclZlib.c (TclZlibInit): [Bug 3601086]: Register the config + info in the iso8859-1 encoding as that is guaranteed to be present. + +2013-01-16 Jan Nijtmans <nijtmans@users.sf.net> + + * Makefile.in: Allow win32 build with -DTCL_NO_DEPRECATED, just as + * generic/tcl.h: in the UNIX build. Define Tcl_EvalObj and + * generic/tclDecls.h: Tcl_GlobalEvalObj as macros, even when + * generic/tclBasic.c: TCL_NO_DEPRECATED is defined, so Tk can benefit + from it too. + +2013-01-14 Jan Nijtmans <nijtmans@users.sf.net> + + * win/tcl.m4: More flexible search for win32 tclConfig.sh, backported + from TEA (not actually used in Tcl, only for Tk) + +2013-01-14 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclInt.decls: Put back Tcl_[GS]etStartupScript in internal + stub table, so extensions using this, compiled against 8.5 headers + still run in Tcl 8.6. + +2013-01-13 Alexandre Ferrieux <ferrieux@users.sourceforge.net> + + * doc/fileevent.n: [Bug 3436609]: Clarify readable fileevent "false + positives" in the case of multibyte encodings/transforms. + +2013-01-13 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclIntDecls.h: If TCL_NO_DEPRECATED is defined, make sure + that TIP #139 functions all are taken from the public stub table, even + if the inclusion is through tclInt.h. + +2013-01-12 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclInt.decls: Put back TclBackgroundException in internal + stub table, so extensions using this, compiled against 8.5 headers + still run in Tcl 8.6. + +2013-01-09 Jan Nijtmans <nijtmans@users.sf.net> + + * library/http/http.tcl: [Bug 3599395]: http assumes status line is a + proper Tcl list. + 2013-01-08 Jan Nijtmans <nijtmans@users.sf.net> * win/tclWinFile.c: [Bug 3092089]: [file normalize] can remove path - components. [Bug 3587096] win vista/7: "can't find init.tcl" when - called via junction. + components. [Bug 3587096]: win vista/7: "can't find init.tcl" when + called via junction without folder list access. 2013-01-07 Jan Nijtmans <nijtmans@users.sf.net> * generic/tclOOStubLib.c: Restrict the stub library to only use - * generic/tclTomMathStubLib.c: Tcl_PkgRequireEx, Tcl_ResetResult - and Tcl_AppendResult, not any other function. This puts least - restrictions on eventual Tcl 9 stubs re-organization, and it - works on the widest range of Tcl versions. + * generic/tclTomMathStubLib.c: Tcl_PkgRequireEx, Tcl_ResetResult and + Tcl_AppendResult, not any other function. This puts least restrictions + on eventual Tcl 9 stubs re-organization, and it works on the widest + range of Tcl versions. 2013-01-06 Jan Nijtmans <nijtmans@users.sf.net> @@ -66,8 +354,8 @@ 2012-12-22 Alexandre Ferrieux <ferrieux@users.sourceforge.net> - * generic/tclUtil.c: Stop leaking allocated space when objifying a - zero-length DString. [Bug 3598150] spotted by afredd. + * generic/tclUtil.c: [Bug 3598150]: Stop leaking allocated space when + objifying a zero-length DString. Spotted by afredd. 2012-12-21 Jan Nijtmans <nijtmans@users.sf.net> @@ -4107,6 +4395,7 @@ * generic/*Decls.h: (regenerated) 2010-08-18 Miguel Sofer <msofer@users.sf.net> + * generic/tclBasic.c: New redesign of [tailcall]: find * generic/tclExecute.c: errors early on, so that errorInfo * generic/tclInt.h: contains the proper info [Bug 3047235] diff --git a/compat/fake-rfc2553.c b/compat/fake-rfc2553.c index 666144f..3b91041 100644 --- a/compat/fake-rfc2553.c +++ b/compat/fake-rfc2553.c @@ -84,7 +84,7 @@ int fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, if (host != NULL) { if (flags & NI_NUMERICHOST) { - int len; + size_t len; Tcl_MutexLock(&netdbMutex); len = strlcpy(host, inet_ntoa(sin->sin_addr), hostlen); Tcl_MutexUnlock(&netdbMutex); @@ -135,7 +135,7 @@ fake_gai_strerror(int err) #ifndef HAVE_FREEADDRINFO void -freeaddrinfo(struct addrinfo *ai) +fake_freeaddrinfo(struct addrinfo *ai) { struct addrinfo *next; @@ -199,7 +199,7 @@ fake_getaddrinfo(const char *hostname, const char *servname, port = strtol(servname, &cp, 10); if (port > 0 && port <= 65535 && *cp == '\0') - port = htons(port); + port = htons((unsigned short)port); else if ((sp = getservbyname(servname, NULL)) != NULL) port = sp->s_port; else diff --git a/doc/fileevent.n b/doc/fileevent.n index df48d2a..e453748 100644 --- a/doc/fileevent.n +++ b/doc/fileevent.n @@ -80,13 +80,16 @@ A channel is considered to be writable if at least one byte of data can be written to the underlying file or device without blocking, or if an error condition is present on the underlying file or device. .PP -Event-driven I/O works best for channels that have been -placed into nonblocking mode with the \fBfconfigure\fR command. -In blocking mode, a \fBputs\fR command may block if you give it -more data than the underlying file or device can accept, and a -\fBgets\fR or \fBread\fR command will block if you attempt to read -more data than is ready; no events will be processed while the -commands block. +Event-driven I/O works best for channels that have been placed into +nonblocking mode with the \fBfconfigure\fR command. In blocking mode, +a \fBputs\fR command may block if you give it more data than the +underlying file or device can accept, and a \fBgets\fR or \fBread\fR +command will block if you attempt to read more data than is ready; a +readable underlying file or device may not even guarantee that a +blocking [read 1] will succeed (counter-examples being multi-byte +encodings, compression or encryption transforms ). In all such cases, +no events will be processed while the commands block. +.PP In nonblocking mode \fBputs\fR, \fBread\fR, and \fBgets\fR never block. See the documentation for the individual commands for information on how they handle blocking and nonblocking channels. diff --git a/doc/msgcat.n b/doc/msgcat.n index 57fbb78..47b6bf7 100644 --- a/doc/msgcat.n +++ b/doc/msgcat.n @@ -13,7 +13,7 @@ msgcat \- Tcl message catalog .SH SYNOPSIS \fBpackage require Tcl 8.5\fR .sp -\fBpackage require msgcat 1.5.0\fR +\fBpackage require msgcat 1.5\fR .sp \fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR? .sp diff --git a/doc/namespace.n b/doc/namespace.n index b06d27a..f2812b2 100644 --- a/doc/namespace.n +++ b/doc/namespace.n @@ -287,7 +287,7 @@ This command is the complement of the \fBnamespace qualifiers\fR command. It does not check whether the namespace names are, in fact, the names of currently defined namespaces. .TP -\fBnamespace upvar\fR \fInamespace\fR ?\fIotherVar myVar \fR... +\fBnamespace upvar\fR \fInamespace\fR ?\fIotherVar myVar \fR...? . This command arranges for zero or more local variables in the current procedure to refer to variables in \fInamespace\fR. The namespace name is diff --git a/doc/string.n b/doc/string.n index f5eae39..351c865 100644 --- a/doc/string.n +++ b/doc/string.n @@ -19,7 +19,7 @@ string \- Manipulate strings Performs one of several string operations, depending on \fIoption\fR. The legal \fIoption\fRs (which may be abbreviated) are: .TP -\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR +\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR . Perform a character-by-character comparison of strings \fIstring1\fR and \fIstring2\fR. Returns \-1, 0, or 1, depending on whether @@ -29,7 +29,7 @@ first \fIlength\fR characters are used in the comparison. If \fB\-length\fR is negative, it is ignored. If \fB\-nocase\fR is specified, then the strings are compared in a case-insensitive manner. .TP -\fBstring equal\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR +\fBstring equal\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR . Perform a character-by-character comparison of strings \fIstring1\fR and \fIstring2\fR. Returns 1 if \fIstring1\fR and \fIstring2\fR are @@ -87,7 +87,7 @@ Handle different reasons for a file to not be openable for reading: .PP .CS \fBtry\fR { - set f [open /some/file/name] + set f [open /some/file/name w] } \fBtrap\fR {POSIX EISDIR} {} { puts "failed to open /some/file/name: it's a directory" } \fBtrap\fR {POSIX ENOENT} {} { diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c index 4fb3ea6..fc0c823 100644 --- a/generic/regc_nfa.c +++ b/generic/regc_nfa.c @@ -497,6 +497,62 @@ freearc( } /* + - hasnonemptyout - Does state have a non-EMPTY out arc? + ^ static int hasnonemptyout(struct state *); + */ +static int +hasnonemptyout( + struct state *s) +{ + struct arc *a; + + for (a = s->outs; a != NULL; a = a->outchain) { + if (a->type != EMPTY) { + return 1; + } + } + return 0; +} + +/* + - nonemptyouts - count non-EMPTY out arcs of a state + ^ static int nonemptyouts(struct state *); + */ +static int +nonemptyouts( + struct state *s) +{ + int n = 0; + struct arc *a; + + for (a = s->outs; a != NULL; a = a->outchain) { + if (a->type != EMPTY) { + n++; + } + } + return n; +} + +/* + - nonemptyins - count non-EMPTY in arcs of a state + ^ static int nonemptyins(struct state *); + */ +static int +nonemptyins( + struct state *s) +{ + int n = 0; + struct arc *a; + + for (a = s->ins; a != NULL; a = a->inchain) { + if (a->type != EMPTY) { + n++; + } + } + return n; +} + +/* - findarc - find arc, if any, from given source with given type and color * If there is more than one such arc, the result is random. ^ static struct arc *findarc(struct state *, int, pcolor); @@ -559,21 +615,25 @@ moveins( } /* - - copyins - copy all in arcs of a state to another state - ^ static void copyins(struct nfa *, struct state *, struct state *); + - copyins - copy in arcs of a state to another state + * Either all arcs, or only non-empty ones as determined by all value. + ^ static VOID copyins(struct nfa *, struct state *, struct state *, int); */ static void copyins( struct nfa *nfa, struct state *oldState, - struct state *newState) + struct state *newState, + int all) { struct arc *a; assert(oldState != newState); for (a=oldState->ins ; a!=NULL ; a=a->inchain) { - cparc(nfa, a, a->from, newState); + if (all || a->type != EMPTY) { + cparc(nfa, a, a->from, newState); + } } } @@ -598,21 +658,25 @@ moveouts( } /* - - copyouts - copy all out arcs of a state to another state - ^ static void copyouts(struct nfa *, struct state *, struct state *); + - copyouts - copy out arcs of a state to another state + * Either all arcs, or only non-empty ones as determined by all value. + ^ static VOID copyouts(struct nfa *, struct state *, struct state *, int); */ static void copyouts( struct nfa *nfa, struct state *oldState, - struct state *newState) + struct state *newState, + int all) { struct arc *a; assert(oldState != newState); for (a=oldState->outs ; a!=NULL ; a=a->outchain) { - cparc(nfa, a, newState, a->to); + if (all || a->type != EMPTY) { + cparc(nfa, a, newState, a->to); + } } } @@ -759,7 +823,9 @@ duptraverse( * Arbitrary depth limit. Needs tuning, but this value is sufficient to * make all normal tests (not reg-33.14) pass. */ -#define DUPTRAVERSE_MAX_DEPTH 500 +#ifndef DUPTRAVERSE_MAX_DEPTH +#define DUPTRAVERSE_MAX_DEPTH 700 +#endif if (depth++ > DUPTRAVERSE_MAX_DEPTH) { NERR(REG_ESPACE); @@ -968,9 +1034,9 @@ pull( if (NISERR()) { return 0; } - assert(to != from); /* con is not an inarc */ - copyins(nfa, from, s); /* duplicate inarcs */ - cparc(nfa, con, s, to); /* move constraint arc */ + assert(to != from); /* con is not an inarc */ + copyins(nfa, from, s, 1); /* duplicate inarcs */ + cparc(nfa, con, s, to); /* move constraint arc */ freearc(nfa, con); from = s; con = from->outs; @@ -1128,7 +1194,7 @@ push( if (NISERR()) { return 0; } - copyouts(nfa, to, s); /* duplicate outarcs */ + copyouts(nfa, to, s, 1); /* duplicate outarcs */ cparc(nfa, con, from, s); /* move constraint */ freearc(nfa, con); to = s; @@ -1245,100 +1311,209 @@ fixempties( FILE *f) /* for debug output; NULL none */ { struct state *s; + struct state *s2; struct state *nexts; struct arc *a; struct arc *nexta; - int progress; /* - * Find and eliminate empties until there are no more. + * First, get rid of any states whose sole out-arc is an EMPTY, + * since they're basically just aliases for their successor. The + * parsing algorithm creates enough of these that it's worth + * special-casing this. */ + for (s = nfa->states; s != NULL && !NISERR(); s = nexts) { + nexts = s->next; + if (s->flag || s->nouts != 1) { + continue; + } + a = s->outs; + assert(a != NULL && a->outchain == NULL); + if (a->type != EMPTY) { + continue; + } + if (s != a->to) { + moveins(nfa, s, a->to); + } + dropstate(nfa, s); + } - do { - progress = 0; - for (s = nfa->states; s != NULL && !NISERR() - && s->no != FREESTATE; s = nexts) { - nexts = s->next; - for (a = s->outs; a != NULL && !NISERR(); a = nexta) { - nexta = a->outchain; - if (a->type == EMPTY && unempty(nfa, a)) { - progress = 1; - } - assert(nexta == NULL || s->no != FREESTATE); + /* + * Similarly, get rid of any state with a single EMPTY in-arc, by + * folding it into its predecessor. + */ + for (s = nfa->states; s != NULL && !NISERR(); s = nexts) { + nexts = s->next; + /* Ensure tmp fields are clear for next step */ + assert(s->tmp = NULL); + if (s->flag || s->nins != 1) { + continue; + } + a = s->ins; + assert(a != NULL && a->inchain == NULL); + if (a->type != EMPTY) { + continue; + } + if (s != a->from) { + moveouts(nfa, s, a->from); + } + dropstate(nfa, s); + } + + /* + * For each remaining NFA state, find all other states that are + * reachable from it by a chain of one or more EMPTY arcs. Then + * generate new arcs that eliminate the need for each such chain. + * + * If we just do this straightforwardly, the algorithm gets slow in + * complex graphs, because the same arcs get copied to all + * intermediate states of an EMPTY chain, and then uselessly pushed + * repeatedly to the chain's final state; we waste a lot of time in + * newarc's duplicate checking. To improve matters, we decree that + * any state with only EMPTY out-arcs is "doomed" and will not be + * part of the final NFA. That can be ensured by not adding any new + * out-arcs to such a state. Having ensured that, we need not update + * the state's in-arcs list either; all arcs that might have gotten + * pushed forward to it will just get pushed directly to successor + * states. This eliminates most of the useless duplicate arcs. + */ + for (s = nfa->states; s != NULL && !NISERR(); s = s->next) { + for (s2 = emptyreachable(s, s); s2 != s && !NISERR(); + s2 = nexts) { + /* + * If s2 is doomed, we decide that (1) we will always push + * arcs forward to it, not pull them back to s; and (2) we + * can optimize away the push-forward, per comment above. + * So do nothing. + */ + if (s2->flag || hasnonemptyout(s2)) { + replaceempty(nfa, s, s2); } + + /* Reset the tmp fields as we walk back */ + nexts = s2->tmp; + s2->tmp = NULL; } - if (progress && f != NULL) { - dumpnfa(nfa, f); + s->tmp = NULL; + } + if (NISERR()) { + return; + } + + /* + * Remove all the EMPTY arcs, since we don't need them anymore. + */ + for (s = nfa->states; s != NULL; s = s->next) { + for (a = s->outs; a != NULL; a = nexta) { + nexta = a->outchain; + if (a->type == EMPTY) { + freearc(nfa, a); + } } - } while (progress && !NISERR()); + } + + /* + * And remove any states that have become useless. (This cleanup is + * not very thorough, and would be even less so if we tried to + * combine it with the previous step; but cleanup() will take care + * of anything we miss.) + */ + for (s = nfa->states; s != NULL; s = nexts) { + nexts = s->next; + if ((s->nins == 0 || s->nouts == 0) && !s->flag) { + dropstate(nfa, s); + } + } + + if (f != NULL) { + dumpnfa(nfa, f); + } } /* - - unempty - optimize out an EMPTY arc, if possible - * Actually, as it stands this function always succeeds, but the return value - * is kept with an eye on possible future changes. - ^ static int unempty(struct nfa *, struct arc *); + - emptyreachable - recursively find all states reachable from s by EMPTY arcs + * The return value is the last such state found. Its tmp field links back + * to the next-to-last such state, and so on back to s, so that all these + * states can be located without searching the whole NFA. + * The maximum recursion depth here is equal to the length of the longest + * loop-free chain of EMPTY arcs, which is surely no more than the size of + * the NFA, and in practice will be a lot less than that. + ^ static struct state *emptyreachable(struct state *, struct state *); */ -static int /* 0 couldn't, 1 could */ -unempty( - struct nfa *nfa, - struct arc *a) +static struct state * +emptyreachable( + struct state *s, + struct state *lastfound) { - struct state *from = a->from; - struct state *to = a->to; - int usefrom; /* work on from, as opposed to to? */ - - assert(a->type == EMPTY); - assert(from != nfa->pre && to != nfa->post); + struct arc *a; - if (from == to) { /* vacuous loop */ - freearc(nfa, a); - return 1; + s->tmp = lastfound; + lastfound = s; + for (a = s->outs; a != NULL; a = a->outchain) { + if (a->type == EMPTY && a->to->tmp == NULL) { + lastfound = emptyreachable(a->to, lastfound); + } } + return lastfound; +} + +/* + - replaceempty - replace an EMPTY arc chain with some non-empty arcs + * The EMPTY arc(s) should be deleted later, but we can't do it here because + * they may still be needed to identify other arc chains during fixempties(). + ^ static void replaceempty(struct nfa *, struct state *, struct state *); + */ +static void +replaceempty( + struct nfa *nfa, + struct state *from, + struct state *to) +{ + int fromouts; + int toins; + + assert(from != to); /* - * Decide which end to work on. + * Create replacement arcs that bypass the need for the EMPTY chain. We + * can do this either by pushing arcs forward (linking directly from + * "from"'s predecessors to "to") or by pulling them back (linking + * directly from "from" to "to"'s successors). In general, we choose + * whichever way creates greater fan-out or fan-in, so as to improve the + * odds of reducing the other state to zero in-arcs or out-arcs and + * thereby being able to delete it. However, if "from" is doomed (has no + * non-EMPTY out-arcs), we must keep it so, so always push forward in that + * case. + * + * The fan-out/fan-in comparison should count only non-EMPTY arcs. If + * "from" is doomed, we can skip counting "to"'s arcs, since we want to + * force taking the copynonemptyins path in that case. */ + fromouts = nonemptyouts(from); + toins = (fromouts == 0) ? 1 : nonemptyins(to); - usefrom = 1; /* default: attack from */ - if (from->nouts > to->nins) { - usefrom = 0; - } else if (from->nouts == to->nins) { - /* - * Decide on secondary issue: move/copy fewest arcs. - */ - - if (from->nins > to->nouts) { - usefrom = 0; - } + if (fromouts > toins) { + copyouts(nfa, to, from, 0); + return; + } + if (fromouts < toins) { + copyins(nfa, from, to, 0); + return; } - freearc(nfa, a); - if (usefrom) { - if (from->nouts == 0) { - /* - * Was the state's only outarc. - */ - - moveins(nfa, from, to); - freestate(nfa, from); - } else { - copyins(nfa, from, to); - } - } else { - if (to->nins == 0) { - /* - * Was the state's only inarc. - */ - - moveouts(nfa, to, from); - freestate(nfa, to); - } else { - copyouts(nfa, to, from); - } + /* + * fromouts == toins. Decide on secondary issue: copy fewest arcs. + * + * Doesn't seem to be worth the trouble to exclude empties from these + * comparisons; that takes extra time and doesn't seem to improve the + * resulting graph much. + */ + if (from->nins > to->nouts) { + copyouts(nfa, to, from, 0); + return; } - return 1; + copyins(nfa, from, to, 0); } /* diff --git a/generic/regcomp.c b/generic/regcomp.c index 65555aa..c93eb24 100644 --- a/generic/regcomp.c +++ b/generic/regcomp.c @@ -121,12 +121,15 @@ static void destroystate(struct nfa *, struct state *); static void newarc(struct nfa *, int, pcolor, struct state *, struct state *); static struct arc *allocarc(struct nfa *, struct state *); static void freearc(struct nfa *, struct arc *); +static int hasnonemptyout(struct state *); +static int nonemptyouts(struct state *); +static int nonemptyins(struct state *); static struct arc *findarc(struct state *, int, pcolor); static void cparc(struct nfa *, struct arc *, struct state *, struct state *); static void moveins(struct nfa *, struct state *, struct state *); -static void copyins(struct nfa *, struct state *, struct state *); +static void copyins(struct nfa *, struct state *, struct state *, int); static void moveouts(struct nfa *, struct state *, struct state *); -static void copyouts(struct nfa *, struct state *, struct state *); +static void copyouts(struct nfa *, struct state *, struct state *, int); static void cloneouts(struct nfa *, struct state *, struct state *, struct state *, int); static void delsub(struct nfa *, struct state *, struct state *); static void deltraverse(struct nfa *, struct state *, struct state *); @@ -144,7 +147,8 @@ static int push(struct nfa *, struct arc *); #define COMPATIBLE 3 /* compatible but not satisfied yet */ static int combine(struct arc *, struct arc *); static void fixempties(struct nfa *, FILE *); -static int unempty(struct nfa *, struct arc *); +static struct state *emptyreachable(struct state *, struct state *); +static void replaceempty(struct nfa *, struct state *, struct state *); static void cleanup(struct nfa *); static void markreachable(struct nfa *, struct state *, struct state *, struct state *); static void markcanreach(struct nfa *, struct state *, struct state *, struct state *); @@ -607,7 +611,7 @@ makesearch( for (s=slist ; s!=NULL ; s=s2) { s2 = newstate(nfa); - copyouts(nfa, s, s2); + copyouts(nfa, s, s2, 1); for (a=s->ins ; a!=NULL ; a=b) { b = a->inchain; @@ -738,6 +742,7 @@ parsebranch( /* NB, recursion in parseqatom() may swallow rest of branch */ parseqatom(v, stopper, type, lp, right, t); + NOERRN(); } if (!seencontent) { /* empty branch */ @@ -1234,6 +1239,7 @@ parseqatom( EMPTYARC(atom->end, rp); t->right = subre(v, '=', 0, atom->end, rp); } + NOERR(); assert(SEE('|') || SEE(stopper) || SEE(EOS)); t->flags |= COMBINE(t->flags, t->right->flags); top->flags |= COMBINE(top->flags, t->flags); diff --git a/generic/regguts.h b/generic/regguts.h index e57b8f8..67f9625 100644 --- a/generic/regguts.h +++ b/generic/regguts.h @@ -366,7 +366,7 @@ struct subre { */ struct fns { - VOID FUNCPTR(free, (regex_t *)); + void FUNCPTR(free, (regex_t *)); }; /* diff --git a/generic/tcl.h b/generic/tcl.h index 3003abf..4de18f0 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -472,7 +472,7 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; struct {long tv_sec;} st_ctim; /* Here is a 4-byte gap */ } Tcl_StatBuf; -#elif defined(HAVE_STRUCT_STAT64) +#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__) typedef struct stat64 Tcl_StatBuf; #else typedef struct stat Tcl_StatBuf; @@ -504,11 +504,11 @@ typedef struct Tcl_Interp /* TIP #330: Strongly discourage extensions from using the string * result. */ #ifdef USE_INTERP_RESULT - char *result TCL_DEPRECATED_API("use Tcl_GetResult/Tcl_SetResult"); + char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult"); /* If the last command returned a string * result, this points to it. */ void (*freeProc) (char *blockPtr) - TCL_DEPRECATED_API("use Tcl_GetResult/Tcl_SetResult"); + TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult"); /* Zero means the string result is statically * allocated. TCL_DYNAMIC means it was * allocated with ckalloc and should be freed @@ -2449,15 +2449,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); #ifdef TCL_MEM_DEBUG # define ckalloc(x) \ - ((VOID *) Tcl_DbCkalloc((unsigned)(x), __FILE__, __LINE__)) + ((void *) Tcl_DbCkalloc((unsigned)(x), __FILE__, __LINE__)) # define ckfree(x) \ Tcl_DbCkfree((char *)(x), __FILE__, __LINE__) # define ckrealloc(x,y) \ - ((VOID *) Tcl_DbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__)) + ((void *) Tcl_DbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__)) # define attemptckalloc(x) \ - ((VOID *) Tcl_AttemptDbCkalloc((unsigned)(x), __FILE__, __LINE__)) + ((void *) Tcl_AttemptDbCkalloc((unsigned)(x), __FILE__, __LINE__)) # define attemptckrealloc(x,y) \ - ((VOID *) Tcl_AttemptDbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__)) + ((void *) Tcl_AttemptDbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__)) #else /* !TCL_MEM_DEBUG */ @@ -2468,15 +2468,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); */ # define ckalloc(x) \ - ((VOID *) Tcl_Alloc((unsigned)(x))) + ((void *) Tcl_Alloc((unsigned)(x))) # define ckfree(x) \ Tcl_Free((char *)(x)) # define ckrealloc(x,y) \ - ((VOID *) Tcl_Realloc((char *)(x), (unsigned)(y))) + ((void *) Tcl_Realloc((char *)(x), (unsigned)(y))) # define attemptckalloc(x) \ - ((VOID *) Tcl_AttemptAlloc((unsigned)(x))) + ((void *) Tcl_AttemptAlloc((unsigned)(x))) # define attemptckrealloc(x,y) \ - ((VOID *) Tcl_AttemptRealloc((char *)(x), (unsigned)(y))) + ((void *) Tcl_AttemptRealloc((char *)(x), (unsigned)(y))) # undef Tcl_InitMemory # define Tcl_InitMemory(x) # undef Tcl_DumpActiveMemory @@ -2602,13 +2602,6 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); */ #ifndef TCL_NO_DEPRECATED -# undef Tcl_EvalObj -# define Tcl_EvalObj(interp,objPtr) \ - Tcl_EvalObjEx((interp),(objPtr),0) -# undef Tcl_GlobalEvalObj -# define Tcl_GlobalEvalObj(interp,objPtr) \ - Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL) - /* * These function have been renamed. The old names are deprecated, but we * define these macros for backwards compatibilty. diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 7833105..5786975 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -798,12 +798,10 @@ TclNRAssembleObjCmd( if (codePtr == NULL) { Tcl_AddErrorInfo(interp, "\n (\""); - Tcl_AddErrorInfo(interp, Tcl_GetString(objv[0])); + Tcl_AppendObjToErrorInfo(interp, objv[0]); Tcl_AddErrorInfo(interp, "\" body, line "); backtrace = Tcl_NewIntObj(Tcl_GetErrorLine(interp)); - Tcl_IncrRefCount(backtrace); - Tcl_AddErrorInfo(interp, Tcl_GetString(backtrace)); - Tcl_DecrRefCount(backtrace); + Tcl_AppendObjToErrorInfo(interp, backtrace); Tcl_AddErrorInfo(interp, ")"); return TCL_ERROR; } @@ -841,16 +839,11 @@ CompileAssembleObj( CompileEnv compEnv; /* Compilation environment structure */ register ByteCode *codePtr = NULL; /* Bytecode resulting from the assembly */ - register const AuxData * auxDataPtr; - /* Pointer to an auxiliary data element - * in a compilation environment being - * destroyed. */ Namespace* namespacePtr; /* Namespace in which variable and command * names in the bytecode resolve */ int status; /* Status return from Tcl_AssembleCode */ const char* source; /* String representation of the source code */ int sourceLen; /* Length of the source code in bytes */ - int i; /* @@ -860,7 +853,7 @@ CompileAssembleObj( if (objPtr->typePtr == &assembleCodeType) { namespacePtr = iPtr->varFramePtr->nsPtr; - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (((Interp *) *codePtr->interpHandle == iPtr) && (codePtr->compileEpoch == iPtr->compileEpoch) && (codePtr->nsPtr == namespacePtr) @@ -888,44 +881,6 @@ CompileAssembleObj( /* * Assembly failed. Clean up and report the error. */ - - /* - * Free any literals that were constructed for the assembly. - */ - for (i = 0; i < compEnv.literalArrayNext; i++) { - TclReleaseLiteral(interp, compEnv.literalArrayPtr[i].objPtr); - } - - /* - * Free any auxiliary data that was attached to the bytecode - * under construction. - */ - - for (i = 0; i < compEnv.auxDataArrayNext; i++) { - auxDataPtr = compEnv.auxDataArrayPtr + i; - if (auxDataPtr->type->freeProc != NULL) { - (auxDataPtr->type->freeProc)(auxDataPtr->clientData); - } - } - - /* - * TIP 280. If there is extended command line information, - * we need to clean it up. - */ - - if (compEnv.extCmdMapPtr != NULL) { - if (compEnv.extCmdMapPtr->type == TCL_LOCATION_SOURCE) { - Tcl_DecrRefCount(compEnv.extCmdMapPtr->path); - } - for (i = 0; i < compEnv.extCmdMapPtr->nuloc; ++i) { - ckfree(compEnv.extCmdMapPtr->loc[i].line); - } - if (compEnv.extCmdMapPtr->loc != NULL) { - ckfree(compEnv.extCmdMapPtr->loc); - } - Tcl_DeleteHashTable(&(compEnv.extCmdMapPtr->litInfo)); - } - TclFreeCompileEnv(&compEnv); return NULL; } @@ -945,7 +900,7 @@ CompileAssembleObj( * Record the local variable context to which the bytecode pertains */ - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (iPtr->varFramePtr->localCachePtr) { codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; @@ -4270,11 +4225,11 @@ AddBasicBlockRangeToErrorInfo( Tcl_AddErrorInfo(interp, "\n in assembly code between lines "); lineNo = Tcl_NewIntObj(bbPtr->startLine); Tcl_IncrRefCount(lineNo); - Tcl_AddErrorInfo(interp, Tcl_GetString(lineNo)); + Tcl_AppendObjToErrorInfo(interp, lineNo); Tcl_AddErrorInfo(interp, " and "); if (bbPtr->successor1 != NULL) { Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine); - Tcl_AddErrorInfo(interp, Tcl_GetString(lineNo)); + Tcl_AppendObjToErrorInfo(interp, lineNo); } else { Tcl_AddErrorInfo(interp, "end of assembly code"); } @@ -4338,14 +4293,13 @@ static void FreeAssembleCodeInternalRep( Tcl_Obj *objPtr) { - ByteCode *codePtr = objPtr->internalRep.otherValuePtr; + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; codePtr->refCount--; if (codePtr->refCount <= 0) { TclCleanupByteCode(codePtr); } objPtr->typePtr = NULL; - objPtr->internalRep.otherValuePtr = NULL; } /* diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 562cca6..cde1cb9 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -160,10 +160,7 @@ static Tcl_NRPostProc TEOV_Exception; static Tcl_NRPostProc TEOV_NotFoundCallback; static Tcl_NRPostProc TEOV_RestoreVarFrame; static Tcl_NRPostProc TEOV_RunLeaveTraces; -static Tcl_NRPostProc YieldToCallback; -static void ClearTailcall(Tcl_Interp *interp, - struct NRE_callback *tailcallPtr); static Tcl_ObjCmdProc NRCoroInjectObjCmd; MODULE_SCOPE const TclStubs tclStubs; @@ -4161,7 +4158,8 @@ TclNREvalObjv( int result; Namespace *lookupNsPtr = iPtr->lookupNsPtr; Command **cmdPtrPtr; - + NRE_callback *callbackPtr; + iPtr->lookupNsPtr = NULL; /* @@ -4174,15 +4172,14 @@ TclNREvalObjv( * finishes the source command and not just the target. */ - if (iPtr->evalFlags & TCL_EVAL_REDIRECT) { - TclNRAddCallback(interp, NRCommand, NULL, INT2PTR(1), INT2PTR(objc), objv); - iPtr->evalFlags &= ~TCL_EVAL_REDIRECT; + if (iPtr->deferredCallbacks) { + callbackPtr = iPtr->deferredCallbacks; + iPtr->deferredCallbacks = NULL; } else { - TclNRAddCallback(interp, NRCommand, NULL, NULL, INT2PTR(objc), objv); + TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); + callbackPtr = TOP_CB(interp); } - cmdPtrPtr = (Command **) &(TOP_CB(interp)->data[0]); - - TclNRSpliceDeferred(interp); + cmdPtrPtr = (Command **) &(callbackPtr->data[0]); iPtr->numLevels++; result = TclInterpReady(interp); @@ -4309,14 +4306,6 @@ TclNREvalObjv( } } -void -TclPushTailcallPoint( - Tcl_Interp *interp) -{ - TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); - ((Interp *) interp)->numLevels++; -} - int TclNRRunCallbacks( Tcl_Interp *interp, @@ -4368,6 +4357,14 @@ NRCommand( } ((Interp *)interp)->numLevels--; + /* + * If there is a tailcall, schedule it + */ + + if (data[1] && (data[1] != INT2PTR(1))) { + TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL); + } + /* OPT ?? * Do not interrupt a series of cleanups with async or limit checks: * just check at the end? @@ -4625,9 +4622,9 @@ TEOV_NotFound( savedNsPtr = varFramePtr->nsPtr; varFramePtr->nsPtr = lookupNsPtr; } - TclNRDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc), + TclSkipTailcall(interp); + TclNRAddCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc), newObjv, savedNsPtr, NULL); - iPtr->evalFlags |= TCL_EVAL_REDIRECT; return TclNREvalObjv(interp, newObjc, newObjv, TCL_EVAL_NOERR, NULL); } @@ -5814,6 +5811,7 @@ TclArgumentGet( *---------------------------------------------------------------------- */ +#undef Tcl_Eval int Tcl_Eval( Tcl_Interp *interp, /* Token for command interpreter (returned by @@ -6012,7 +6010,8 @@ TclNREvalObjEx( iPtr->cmdFramePtr = eoFramePtr; } - TclNRDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr, + TclMarkTailcall(interp); + TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr, NULL, NULL); ListObjGetElements(listPtr, objc, objv); @@ -6745,6 +6744,7 @@ Tcl_ExprString( *---------------------------------------------------------------------- */ +#undef Tcl_AddObjErrorInfo void Tcl_AppendObjToErrorInfo( Tcl_Interp *interp, /* Interpreter to which error information @@ -6778,6 +6778,7 @@ Tcl_AppendObjToErrorInfo( *---------------------------------------------------------------------- */ +#undef Tcl_AddErrorInfo void Tcl_AddErrorInfo( Tcl_Interp *interp, /* Interpreter to which error information @@ -6958,6 +6959,7 @@ Tcl_VarEval( *---------------------------------------------------------------------- */ +#undef Tcl_GlobalEval int Tcl_GlobalEval( Tcl_Interp *interp, /* Interpreter in which to evaluate @@ -8269,29 +8271,58 @@ Tcl_NRCmdSwap( */ void -TclSpliceTailcall( +TclMarkTailcall( + Tcl_Interp *interp) +{ + Interp *iPtr = (Interp *) interp; + + if (iPtr->deferredCallbacks == NULL) { + TclNRAddCallback(interp, NRCommand, NULL, NULL, + NULL, NULL); + iPtr->deferredCallbacks = TOP_CB(interp); + } +} + +void +TclSkipTailcall( + Tcl_Interp *interp) +{ + Interp *iPtr = (Interp *) interp; + + TclMarkTailcall(interp); + iPtr->deferredCallbacks->data[1] = INT2PTR(1); +} + +void +TclPushTailcallPoint( + Tcl_Interp *interp) +{ + TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL); + ((Interp *) interp)->numLevels++; +} + +void +TclSetTailcall( Tcl_Interp *interp, - NRE_callback *tailcallPtr) + Tcl_Obj *listPtr) { /* * Find the splicing spot: right before the NRCommand of the thing - * being tailcalled. Note that we skip NRCommands marked in data[1] + * being tailcalled. Note that we skip NRCommands marked by a 1 in data[1] * (used by command redirectors). */ NRE_callback *runPtr; for (runPtr = TOP_CB(interp); runPtr; runPtr = runPtr->nextPtr) { - if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) { + if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) { break; } } if (!runPtr) { Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!"); } - - tailcallPtr->nextPtr = runPtr->nextPtr; - runPtr->nextPtr = tailcallPtr; + runPtr->data[1] = listPtr; } int @@ -8321,7 +8352,7 @@ TclNRTailcallObjCmd( */ if (iPtr->varFramePtr->tailcallPtr) { - ClearTailcall(interp, iPtr->varFramePtr->tailcallPtr); + Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr); iPtr->varFramePtr->tailcallPtr = NULL; } @@ -8336,23 +8367,20 @@ TclNRTailcallObjCmd( Tcl_Obj *listPtr, *nsObjPtr; Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr; Tcl_Namespace *ns1Ptr; - NRE_callback *tailcallPtr; - listPtr = Tcl_NewListObj(objc-1, objv+1); - Tcl_IncrRefCount(listPtr); + /* The tailcall data is in a Tcl list: the first element is the + * namespace, the rest the command to be tailcalled. */ + + listPtr = Tcl_NewListObj(objc, objv); nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1); if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) || (nsPtr != ns1Ptr)) { Tcl_Panic("Tailcall failed to find the proper namespace"); } - Tcl_IncrRefCount(nsObjPtr); - - TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsObjPtr, - NULL, NULL); - tailcallPtr = TOP_CB(interp); - TOP_CB(interp) = tailcallPtr->nextPtr; - iPtr->varFramePtr->tailcallPtr = tailcallPtr; + TclListObjSetElement(interp, listPtr, 0, nsObjPtr); + + iPtr->varFramePtr->tailcallPtr = listPtr; } return TCL_RETURN; } @@ -8364,12 +8392,14 @@ TclNRTailcallEval( int result) { Interp *iPtr = (Interp *) interp; - Tcl_Obj *listPtr = data[0]; - Tcl_Obj *nsObjPtr = data[1]; + Tcl_Obj *listPtr = data[0], *nsObjPtr; Tcl_Namespace *nsPtr; int objc; Tcl_Obj **objv; + Tcl_ListObjGetElements(interp, listPtr, &objc, &objv); + nsObjPtr = objv[0]; + if (result == TCL_OK) { result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr); } @@ -8388,10 +8418,10 @@ TclNRTailcallEval( * Perform the tailcall */ - TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsObjPtr, NULL,NULL); + TclMarkTailcall(interp); + TclNRAddCallback(interp, TailcallCleanup, listPtr, NULL, NULL,NULL); iPtr->lookupNsPtr = (Namespace *) nsPtr; - ListObjGetElements(listPtr, objc, objv); - return TclNREvalObjv(interp, objc, objv, 0, NULL); + return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL); } static int @@ -8401,19 +8431,9 @@ TailcallCleanup( int result) { Tcl_DecrRefCount((Tcl_Obj *) data[0]); - Tcl_DecrRefCount((Tcl_Obj *) data[1]); return result; } -static void -ClearTailcall( - Tcl_Interp *interp, - NRE_callback *tailcallPtr) -{ - TailcallCleanup(tailcallPtr->data, interp, TCL_OK); - TCLNR_FREE(interp, tailcallPtr); -} - void Tcl_NRAddCallback( @@ -8515,50 +8535,32 @@ TclNRYieldToObjCmd( * This is essentially code from TclNRTailcallObjCmd */ - listPtr = Tcl_NewListObj(objc-1, objv+1); - Tcl_IncrRefCount(listPtr); + /* + * Add the tailcall in the caller env, then just yield. + * + * This is essentially code from TclNRTailcallObjCmd + */ + + listPtr = Tcl_NewListObj(objc, objv); nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1); if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) || (nsPtr != ns1Ptr)) { Tcl_Panic("yieldto failed to find the proper namespace"); } - Tcl_IncrRefCount(nsObjPtr); + TclListObjSetElement(interp, listPtr, 0, nsObjPtr); + /* * Add the callback in the caller's env, then instruct TEBC to yield. */ iPtr->execEnvPtr = corPtr->callerEEPtr; - TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, nsObjPtr, - NULL); + TclSetTailcall(interp, listPtr); iPtr->execEnvPtr = corPtr->eePtr; return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv); } - -static int -YieldToCallback( - ClientData data[], - Tcl_Interp *interp, - int result) -{ - /* CoroutineData *corPtr = data[0];*/ - Tcl_Obj *listPtr = data[1]; - ClientData nsPtr = data[2]; - NRE_callback *cbPtr; - - /* - * yieldTo: invoke the command using tailcall tech. - */ - - TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsPtr, NULL, NULL); - cbPtr = TOP_CB(interp); - TOP_CB(interp) = cbPtr->nextPtr; - - TclSpliceTailcall(interp, cbPtr); - return TCL_OK; -} static int RewindCoroutineCallback( diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 455b5a6..901237b 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -204,9 +204,10 @@ typedef struct ByteArray { #define BYTEARRAY_SIZE(len) \ ((unsigned) (TclOffset(ByteArray, bytes) + (len))) #define GET_BYTEARRAY(objPtr) \ - ((ByteArray *) (objPtr)->internalRep.otherValuePtr) + ((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_BYTEARRAY(objPtr, baPtr) \ - (objPtr)->internalRep.otherValuePtr = (void *) (baPtr) + (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr) + /* *---------------------------------------------------------------------- @@ -325,7 +326,7 @@ Tcl_SetByteArrayObj( Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj"); } TclFreeIntRep(objPtr); - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); if (length < 0) { length = 0; @@ -420,7 +421,7 @@ Tcl_SetByteArrayLength( byteArrayPtr->allocated = length; SET_BYTEARRAY(objPtr, byteArrayPtr); } - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); byteArrayPtr->used = length; return byteArrayPtr->bytes; } @@ -691,7 +692,7 @@ TclAppendBytesToByteArray( if (len > 0) { memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len); byteArrayPtr->used += len; - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); } } diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index ab977cb..70e64f0 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -156,6 +156,10 @@ TclInitDbCkalloc(void) if (!ckallocInit) { ckallocInit = 1; ckallocMutexPtr = Tcl_GetAllocMutex(); +#ifndef TCL_THREADS + /* Silence compiler warning */ + (void)ckallocMutexPtr; +#endif } } diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 95debf8..f9f2a28 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1540,7 +1540,8 @@ StringIsCmd( case STR_IS_BOOL: case STR_IS_TRUE: case STR_IS_FALSE: - if (TCL_OK != Tcl_ConvertToType(NULL, objPtr, &tclBooleanType)) { + if ((objPtr->typePtr != &tclBooleanType) + && (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) { if (strict) { result = 0; } else { diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 752db93..40348fa 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -107,6 +107,7 @@ static int CompileDictEachCmd(Tcl_Interp *interp, */ #define TCL_NO_LARGE_INDEX 1 /* Do not return localIndex value > 255 */ +#define TCL_NO_ELEMENT 2 /* Do not push the array element. */ /* * The structures below define the AuxData types defined in this file. @@ -259,7 +260,7 @@ TclCompileArrayExistsCmd( } tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, 0, + PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &simpleVarName, &isScalar, 1); if (!isScalar) { return TCL_ERROR; @@ -283,7 +284,7 @@ TclCompileArraySetCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { DefineLineInformation; /* TIP #280 */ - Tcl_Token *tokenPtr; + Tcl_Token *varTokenPtr, *dataTokenPtr; int simpleVarName, isScalar, localIndex; int dataVar, iterVar, keyVar, valVar, infoIndex; int back, fwd, offsetBack, offsetFwd, savedStackDepth; @@ -293,20 +294,21 @@ TclCompileArraySetCmd( return TCL_ERROR; } - tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, 0, + varTokenPtr = TokenAfter(parsePtr->tokenPtr); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &simpleVarName, &isScalar, 1); + dataTokenPtr = TokenAfter(varTokenPtr); if (!isScalar) { return TCL_ERROR; } - tokenPtr = TokenAfter(tokenPtr); /* * Special case: literal empty value argument is just an "ensure array" * operation. */ - if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD && tokenPtr[1].size == 0) { + if (dataTokenPtr->type == TCL_TOKEN_SIMPLE_WORD + && dataTokenPtr[1].size == 0) { if (localIndex >= 0) { TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr); TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr); @@ -329,14 +331,37 @@ TclCompileArraySetCmd( * Prepare for the internal foreach. */ - if (envPtr->procPtr == NULL) { - return TCL_ERROR; - } dataVar = TclFindCompiledLocal(NULL, 0, 1, envPtr); iterVar = TclFindCompiledLocal(NULL, 0, 1, envPtr); keyVar = TclFindCompiledLocal(NULL, 0, 1, envPtr); valVar = TclFindCompiledLocal(NULL, 0, 1, envPtr); + if (dataVar < 0) { + /* + * Right number of arguments, but not compilable as we can't allocate + * (unnamed) local variables to manage the internal iteration. + */ + + Tcl_Obj *objPtr = Tcl_NewObj(); + char *bytes; + int length, cmdLit; + + Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr); + bytes = Tcl_GetStringFromObj(objPtr, &length); + cmdLit = TclRegisterNewCmdLiteral(envPtr, bytes, length); + TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLit), cmdPtr); + TclEmitPush(cmdLit, envPtr); + TclDecrRefCount(objPtr); + if (localIndex >= 0) { + CompileWord(envPtr, varTokenPtr, interp, 1); + } else { + TclEmitInstInt4(INST_REVERSE, 2, envPtr); + } + CompileWord(envPtr, dataTokenPtr, interp, 2); + TclEmitInstInt1(INST_INVOKE_STK1, 3, envPtr); + return TCL_OK; + } + infoPtr = ckalloc(sizeof(ForeachInfo) + sizeof(ForeachVarList *)); infoPtr->numLists = 1; infoPtr->firstValueTemp = dataVar; @@ -351,7 +376,7 @@ TclCompileArraySetCmd( * Start issuing instructions to write to the array. */ - CompileWord(envPtr, tokenPtr, interp, 2); + CompileWord(envPtr, dataTokenPtr, interp, 2); TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); PushLiteral(envPtr, "1", 1); @@ -434,10 +459,10 @@ TclCompileArrayUnsetCmd( int simpleVarName, isScalar, localIndex, savedStackDepth; if (parsePtr->numWords != 2) { - return TCL_ERROR; + return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } - PushVarNameWord(interp, tokenPtr, envPtr, 0, + PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT, &localIndex, &simpleVarName, &isScalar, 1); if (!isScalar) { return TCL_ERROR; @@ -928,7 +953,7 @@ TclCompileDictIncrCmd( incrTokenPtr = TokenAfter(keyTokenPtr); if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr); } word = incrTokenPtr[1].start; numBytes = incrTokenPtr[1].size; @@ -938,7 +963,7 @@ TclCompileDictIncrCmd( code = TclGetIntFromObj(NULL, intObj, &incrAmount); TclDecrRefCount(intObj); if (code != TCL_OK) { - return TCL_ERROR; + return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr); } } else { incrAmount = 1; @@ -951,16 +976,16 @@ TclCompileDictIncrCmd( */ if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasic2Or3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } name = varTokenPtr[1].start; nameChars = varTokenPtr[1].size; if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; + return TclCompileBasic2Or3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); if (dictVarIndex < 0) { - return TCL_ERROR; + return TclCompileBasic2Or3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1078,16 +1103,16 @@ TclCompileDictUnsetCmd( tokenPtr = TokenAfter(parsePtr->tokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } name = tokenPtr[1].start; nameChars = tokenPtr[1].size; if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); if (dictVarIndex < 0) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1178,7 +1203,7 @@ TclCompileDictCreateCmd( nonConstant: worker = TclFindCompiledLocal(NULL, 0, 1, envPtr); if (worker < 0) { - return TCL_ERROR; + return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr); } PushLiteral(envPtr, "", 0); @@ -1239,7 +1264,7 @@ TclCompileDictMergeCmd( workerIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr); if (workerIndex < 0) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } infoIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr); @@ -1365,11 +1390,11 @@ CompileDictEachCmd( Tcl_DString buffer; /* - * There must be at least three argument after the command. + * There must be three arguments after the command. */ if (parsePtr->numWords != 4) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } varsTokenPtr = TokenAfter(parsePtr->tokenPtr); @@ -1377,7 +1402,7 @@ CompileDictEachCmd( bodyTokenPtr = TokenAfter(dictTokenPtr); if (varsTokenPtr->type != TCL_TOKEN_SIMPLE_WORD || bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1389,7 +1414,7 @@ CompileDictEachCmd( collectVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, envPtr); if (collectVar < 0) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } } @@ -1403,31 +1428,31 @@ CompileDictEachCmd( if (Tcl_SplitList(NULL, Tcl_DStringValue(&buffer), &numVars, &argv) != TCL_OK) { Tcl_DStringFree(&buffer); - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } Tcl_DStringFree(&buffer); if (numVars != 2) { ckfree(argv); - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } nameChars = strlen(argv[0]); if (!TclIsLocalScalar(argv[0], nameChars)) { ckfree(argv); - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } keyVarIndex = TclFindCompiledLocal(argv[0], nameChars, 1, envPtr); nameChars = strlen(argv[1]); if (!TclIsLocalScalar(argv[1], nameChars)) { ckfree(argv); - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } valueVarIndex = TclFindCompiledLocal(argv[1], nameChars, 1, envPtr); ckfree(argv); if ((keyVarIndex < 0) || (valueVarIndex < 0)) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1439,7 +1464,7 @@ CompileDictEachCmd( infoIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr); if (infoIndex < 0) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1636,16 +1661,16 @@ TclCompileDictUpdateCmd( dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); if (dictVarTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } name = dictVarTokenPtr[1].start; nameChars = dictVarTokenPtr[1].size; if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } dictIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); if (dictIndex < 0) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1696,7 +1721,7 @@ TclCompileDictUpdateCmd( failedUpdateInfoAssembly: ckfree(duiPtr); TclStackFree(interp, keyTokenPtrs); - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } bodyTokenPtr = tokenPtr; @@ -1794,17 +1819,17 @@ TclCompileDictAppendCmd( tokenPtr = TokenAfter(parsePtr->tokenPtr); if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } else { register const char *name = tokenPtr[1].start; register int nameChars = tokenPtr[1].size; if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr,cmdPtr, envPtr); } dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); if (dictVarIndex < 0) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr,cmdPtr, envPtr); } } @@ -1855,16 +1880,16 @@ TclCompileDictLappendCmd( keyTokenPtr = TokenAfter(varTokenPtr); valueTokenPtr = TokenAfter(keyTokenPtr); if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } name = varTokenPtr[1].start; nameChars = varTokenPtr[1].size; if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); if (dictVarIndex < 0) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } CompileWord(envPtr, keyTokenPtr, interp, 3); CompileWord(envPtr, valueTokenPtr, interp, 4); @@ -1908,7 +1933,7 @@ TclCompileDictWithCmd( tokenPtr = TokenAfter(tokenPtr); } if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1920,7 +1945,8 @@ TclCompileDictWithCmd( for (ptr=tokenPtr[1].start,end=ptr+tokenPtr[1].size ; ptr!=end ; ptr++) { if (*ptr!=' ' && *ptr!='\t' && *ptr!='\n' && *ptr!='\r') { if (envPtr->procPtr == NULL) { - return TCL_ERROR; + return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, + envPtr); } bodyIsEmpty = 0; break; @@ -3747,7 +3773,9 @@ TclCompileInfoCommandsCmd( * We require one compile-time known argument for the case we can compile. */ - if (parsePtr->numWords != 2) { + if (parsePtr->numWords == 1) { + return TclCompileBasic0ArgCmd(interp, parsePtr, cmdPtr, envPtr); + } else if (parsePtr->numWords != 2) { return TCL_ERROR; } tokenPtr = TokenAfter(parsePtr->tokenPtr); @@ -3784,7 +3812,7 @@ TclCompileInfoCommandsCmd( notCompilable: Tcl_DecrRefCount(objPtr); - return TCL_ERROR; + return TclCompileBasic1ArgCmd(interp, parsePtr, cmdPtr, envPtr); } int @@ -6006,7 +6034,7 @@ PushVarName( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Token *varTokenPtr, /* Points to a variable token. */ CompileEnv *envPtr, /* Holds resulting instructions. */ - int flags, /* TCL_NO_LARGE_INDEX. */ + int flags, /* TCL_NO_LARGE_INDEX | TCL_NO_ELEMENT. */ int *localIndexPtr, /* Must not be NULL. */ int *simpleVarNamePtr, /* Must not be NULL. */ int *isScalarPtr, /* Must not be NULL. */ @@ -6187,10 +6215,11 @@ PushVarName( } /* - * Compile the element script, if any. + * Compile the element script, if any, and only if not inhibited. [Bug + * 3600328] */ - if (elName != NULL) { + if (elName != NULL && !(flags & TCL_NO_ELEMENT)) { if (elNameChars) { envPtr->line = line; envPtr->clNext = clNext; diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 1d04d8b..f73beca 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -448,7 +448,7 @@ TclCompileStringMatchCmd( if (parsePtr->numWords == 4) { if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } str = tokenPtr[1].start; length = tokenPtr[1].size; @@ -457,7 +457,7 @@ TclCompileStringMatchCmd( * Fail at run time, not in compilation. */ - return TCL_ERROR; + return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr); } nocase = 1; tokenPtr = TokenAfter(tokenPtr); @@ -578,13 +578,13 @@ TclCompileStringMapCmd( Tcl_IncrRefCount(mapObj); if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) { Tcl_DecrRefCount(mapObj); - return TCL_ERROR; + return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } else if (Tcl_ListObjGetElements(NULL, mapObj, &len, &objv) != TCL_OK) { Tcl_DecrRefCount(mapObj); - return TCL_ERROR; + return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } else if (len != 2) { Tcl_DecrRefCount(mapObj); - return TCL_ERROR; + return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); } /* @@ -1953,11 +1953,13 @@ TclCompileTailcallCmd( return TCL_ERROR; } + /* make room for the nsObjPtr */ + CompileWord(envPtr, tokenPtr, interp, 0); for (i=1 ; i<parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); CompileWord(envPtr, tokenPtr, interp, i); } - TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords-1, envPtr); + TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords, envPtr); return TCL_OK; } diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 890d518..3597abe 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2207,7 +2207,7 @@ ExecConstantExprTree( TclInitByteCodeObj(byteCodeObj, envPtr); TclFreeCompileEnv(envPtr); TclStackFree(interp, envPtr); - byteCodePtr = byteCodeObj->internalRep.otherValuePtr; + byteCodePtr = byteCodeObj->internalRep.twoPtrValue.ptr1; TclNRExecuteByteCode(interp, byteCodePtr); code = TclNRRunCallbacks(interp, TCL_OK, rootPtr); Tcl_DecrRefCount(byteCodeObj); @@ -2445,14 +2445,11 @@ CompileExprTree( Tcl_Obj *literal = *litObjv; if (optimize) { - int length, index; + int length; const char *bytes = TclGetStringFromObj(literal, &length); - LiteralEntry *lePtr; - Tcl_Obj *objPtr; - - index = TclRegisterNewLiteral(envPtr, bytes, length); - lePtr = envPtr->literalArrayPtr + index; - objPtr = lePtr->objPtr; + int index = TclRegisterNewLiteral(envPtr, bytes, length); + Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index); + if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) { /* * Would like to do this: @@ -2511,7 +2508,7 @@ CompileExprTree( index = TclRegisterNewLiteral(envPtr, objPtr->bytes, objPtr->length); - tableValue = envPtr->literalArrayPtr[index].objPtr; + tableValue = TclFetchLiteral(envPtr, index); if ((tableValue->typePtr == NULL) && (objPtr->typePtr != NULL)) { /* diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 45a74d7..0e98385 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -557,6 +557,7 @@ static int GetCmdLocEncodingSize(CompileEnv *envPtr); #ifdef TCL_COMPILE_STATS static void RecordByteCodeStats(ByteCode *codePtr); #endif /* TCL_COMPILE_STATS */ +static void RegisterAuxDataType(const AuxDataType *typePtr); static int SetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, @@ -573,6 +574,7 @@ static void EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset, Tcl_Token *tokenPtr, const char *cmd, int len, int numWords, int line, int *clNext, int **lines, CompileEnv *envPtr); +static void ReleaseCmdWordData(ExtCmdLoc *eclPtr); /* * The structure below defines the bytecode Tcl object type by means of @@ -650,9 +652,6 @@ TclSetByteCodeFromAny( Interp *iPtr = (Interp *) interp; CompileEnv compEnv; /* Compilation environment structure allocated * in frame. */ - register const AuxData *auxDataPtr; - LiteralEntry *entryPtr; - register int i; int length, result = TCL_OK; const char *stringPtr; ContLineLoc *clLocPtr; @@ -722,35 +721,14 @@ TclSetByteCodeFromAny( TclVerifyLocalLiteralTable(&compEnv); #endif /*TCL_COMPILE_DEBUG*/ - TclInitByteCodeObj(objPtr, &compEnv); -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ - - if (result != TCL_OK) { - /* - * Handle any error from the hookProc - */ - - entryPtr = compEnv.literalArrayPtr; - for (i = 0; i < compEnv.literalArrayNext; i++) { - TclReleaseLiteral(interp, entryPtr->objPtr); - entryPtr++; - } + if (result == TCL_OK) { + TclInitByteCodeObj(objPtr, &compEnv); #ifdef TCL_COMPILE_DEBUG - TclVerifyGlobalLiteralTable(iPtr); -#endif /*TCL_COMPILE_DEBUG*/ - - auxDataPtr = compEnv.auxDataArrayPtr; - for (i = 0; i < compEnv.auxDataArrayNext; i++) { - if (auxDataPtr->type->freeProc != NULL) { - auxDataPtr->type->freeProc(auxDataPtr->clientData); - } - auxDataPtr++; + if (tclTraceCompile >= 2) { + TclPrintByteCodeObj(interp, objPtr); + fflush(stdout); } +#endif /* TCL_COMPILE_DEBUG */ } TclFreeCompileEnv(&compEnv); @@ -789,8 +767,7 @@ SetByteCodeFromAny( if (interp == NULL) { return TCL_ERROR; } - TclSetByteCodeFromAny(interp, objPtr, NULL, NULL); - return TCL_OK; + return TclSetByteCodeFromAny(interp, objPtr, NULL, NULL); } /* @@ -844,10 +821,9 @@ static void FreeByteCodeInternalRep( register Tcl_Obj *objPtr) /* Object whose internal rep to free. */ { - register ByteCode *codePtr = objPtr->internalRep.otherValuePtr; + register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; objPtr->typePtr = NULL; - objPtr->internalRep.otherValuePtr = NULL; codePtr->refCount--; if (codePtr->refCount <= 0) { TclCleanupByteCode(codePtr); @@ -867,9 +843,8 @@ FreeByteCodeInternalRep( * None. * * Side effects: - * Frees objPtr's bytecode internal representation and sets its type and - * objPtr->internalRep.otherValuePtr NULL. Also releases its literals and - * frees its auxiliary data items. + * Frees objPtr's bytecode internal representation and sets its type NULL + * Also releases its literals and frees its auxiliary data items. * *---------------------------------------------------------------------- */ @@ -944,7 +919,7 @@ TclCleanupByteCode( * released. */ - if ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) || (interp == NULL)) { + if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) { objArrayPtr = codePtr->objArrayPtr; for (i = 0; i < numLitObjects; i++) { @@ -957,17 +932,9 @@ TclCleanupByteCode( codePtr->numLitObjects = 0; } else { objArrayPtr = codePtr->objArrayPtr; - for (i = 0; i < numLitObjects; i++) { - /* - * TclReleaseLiteral sets a ByteCode's object array entry NULL to - * indicate that it has already freed the literal. - */ - - objPtr = *objArrayPtr; - if (objPtr != NULL) { - TclReleaseLiteral(interp, objPtr); - } - objArrayPtr++; + while (numLitObjects--) { + /* TclReleaseLiteral calls Tcl_DecrRefCount() for us */ + TclReleaseLiteral(interp, *objArrayPtr++); } } @@ -992,22 +959,7 @@ TclCleanupByteCode( (char *) codePtr); if (hePtr) { - ExtCmdLoc *eclPtr = Tcl_GetHashValue(hePtr); - - if (eclPtr->type == TCL_LOCATION_SOURCE) { - Tcl_DecrRefCount(eclPtr->path); - } - for (i=0 ; i<eclPtr->nuloc ; i++) { - ckfree(eclPtr->loc[i].line); - } - - if (eclPtr->loc != NULL) { - ckfree(eclPtr->loc); - } - - Tcl_DeleteHashTable(&eclPtr->litInfo); - - ckfree(eclPtr); + ReleaseCmdWordData(Tcl_GetHashValue(hePtr)); Tcl_DeleteHashEntry(hePtr); } } @@ -1144,7 +1096,7 @@ CompileSubstObj( objPtr->typePtr = &substCodeType; TclFreeCompileEnv(&compEnv); - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; objPtr->internalRep.ptrAndLongRep.ptr = codePtr; objPtr->internalRep.ptrAndLongRep.value = flags; if (iPtr->varFramePtr->localCachePtr) { @@ -1183,12 +1135,33 @@ FreeSubstCodeInternalRep( register ByteCode *codePtr = objPtr->internalRep.ptrAndLongRep.ptr; objPtr->typePtr = NULL; - objPtr->internalRep.otherValuePtr = NULL; codePtr->refCount--; if (codePtr->refCount <= 0) { TclCleanupByteCode(codePtr); } } + +static void +ReleaseCmdWordData( + ExtCmdLoc *eclPtr) +{ + int i; + + if (eclPtr->type == TCL_LOCATION_SOURCE) { + Tcl_DecrRefCount(eclPtr->path); + } + for (i=0 ; i<eclPtr->nuloc ; i++) { + ckfree((char *) eclPtr->loc[i].line); + } + + if (eclPtr->loc != NULL) { + ckfree((char *) eclPtr->loc); + } + + Tcl_DeleteHashTable (&eclPtr->litInfo); + + ckfree((char *) eclPtr); +} /* *---------------------------------------------------------------------- @@ -1422,6 +1395,32 @@ TclFreeCompileEnv( ckfree(envPtr->localLitTable.buckets); envPtr->localLitTable.buckets = envPtr->localLitTable.staticBuckets; } + if (envPtr->iPtr) { + /* + * We never converted to Bytecode, so free the things we would + * have transferred to it. + */ + + int i; + LiteralEntry *entryPtr = envPtr->literalArrayPtr; + AuxData *auxDataPtr = envPtr->auxDataArrayPtr; + + for (i = 0; i < envPtr->literalArrayNext; i++) { + TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, entryPtr->objPtr); + entryPtr++; + } + +#ifdef TCL_COMPILE_DEBUG + TclVerifyGlobalLiteralTable(envPtr->iPtr); +#endif /*TCL_COMPILE_DEBUG*/ + + for (i = 0; i < envPtr->auxDataArrayNext; i++) { + if (auxDataPtr->type->freeProc != NULL) { + auxDataPtr->type->freeProc(auxDataPtr->clientData); + } + auxDataPtr++; + } + } if (envPtr->mallocedCodeArray) { ckfree(envPtr->codeStart); } @@ -1438,7 +1437,8 @@ TclFreeCompileEnv( ckfree(envPtr->auxDataArrayPtr); } if (envPtr->extCmdMapPtr) { - ckfree(envPtr->extCmdMapPtr); + ReleaseCmdWordData(envPtr->extCmdMapPtr); + envPtr->extCmdMapPtr = NULL; } /* @@ -1580,6 +1580,10 @@ TclCompileScript( int *wlines, wlineat, cmdLine, *clNext; Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); + if (envPtr->iPtr == NULL) { + Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv"); + } + Tcl_DStringInit(&ds); if (numBytes < 0) { @@ -1892,8 +1896,7 @@ TclCompileScript( tokenPtr[1].start, tokenPtr[1].size); if (cmdPtr != NULL) { TclSetCmdNameObj(interp, - envPtr->literalArrayPtr[objIndex].objPtr, - cmdPtr); + TclFetchLiteral(envPtr, objIndex), cmdPtr); } } else { /* @@ -1910,7 +1913,7 @@ TclCompileScript( if (envPtr->clNext) { TclContinuationsEnterDerived( - envPtr->literalArrayPtr[objIndex].objPtr, + TclFetchLiteral(envPtr, objIndex), tokenPtr[1].start - envPtr->source, eclPtr->loc[wlineat].next[wordIdx]); } @@ -2219,9 +2222,8 @@ TclCompileTokens( Tcl_DStringFree(&textBuffer); if (numCL) { - TclContinuationsEnter( - envPtr->literalArrayPtr[literal].objPtr, numCL, - clPosition); + TclContinuationsEnter(TclFetchLiteral(envPtr, literal), + numCL, clPosition); } numCL = 0; } @@ -2267,7 +2269,7 @@ TclCompileTokens( TclEmitPush(literal, envPtr); numObjsToConcat++; if (numCL) { - TclContinuationsEnter(envPtr->literalArrayPtr[literal].objPtr, + TclContinuationsEnter(TclFetchLiteral(envPtr, literal), numCL, clPosition); } numCL = 0; @@ -2514,6 +2516,10 @@ TclInitByteCodeObj( int i, isNew; Interp *iPtr; + if (envPtr->iPtr == NULL) { + Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv"); + } + iPtr = envPtr->iPtr; codeBytes = envPtr->codeNext - envPtr->codeStart; @@ -2571,7 +2577,9 @@ TclInitByteCodeObj( p += TCL_ALIGN(codeBytes); /* align object array */ codePtr->objArrayPtr = (Tcl_Obj **) p; for (i = 0; i < numLitObjects; i++) { - if (objPtr == envPtr->literalArrayPtr[i].objPtr) { + Tcl_Obj *fetched = TclFetchLiteral(envPtr, i); + + if (objPtr == fetched) { /* * Prevent circular reference where the bytecode intrep of * a value contains a literal which is that same value. @@ -2588,9 +2596,9 @@ TclInitByteCodeObj( codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes); Tcl_IncrRefCount(codePtr->objArrayPtr[i]); - Tcl_DecrRefCount(objPtr); + TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr); } else { - codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr; + codePtr->objArrayPtr[i] = fetched; } } @@ -2639,7 +2647,7 @@ TclInitByteCodeObj( */ TclFreeIntRep(objPtr); - objPtr->internalRep.otherValuePtr = codePtr; + objPtr->internalRep.twoPtrValue.ptr1 = codePtr; objPtr->typePtr = &tclByteCodeType; /* @@ -2651,6 +2659,9 @@ TclInitByteCodeObj( &isNew), envPtr->extCmdMapPtr); envPtr->extCmdMapPtr = NULL; + /* We've used up the CompileEnv. Mark as uninitialized. */ + envPtr->iPtr = NULL; + codePtr->localCachePtr = NULL; } @@ -3563,7 +3574,7 @@ TclGetInstructionTable(void) /* *-------------------------------------------------------------- * - * TclRegisterAuxDataType -- + * RegisterAuxDataType -- * * This procedure is called to register a new AuxData type in the table * of all AuxData types supported by Tcl. @@ -3579,8 +3590,8 @@ TclGetInstructionTable(void) *-------------------------------------------------------------- */ -void -TclRegisterAuxDataType( +static void +RegisterAuxDataType( const AuxDataType *typePtr) /* Information about object type; storage must * be statically allocated (must live forever; * will not be deallocated). */ @@ -3684,9 +3695,9 @@ TclInitAuxDataTypeTable(void) * There are only two AuxData type at this time, so register them here. */ - TclRegisterAuxDataType(&tclForeachInfoType); - TclRegisterAuxDataType(&tclJumptableInfoType); - TclRegisterAuxDataType(&tclDictUpdateInfoType); + RegisterAuxDataType(&tclForeachInfoType); + RegisterAuxDataType(&tclJumptableInfoType); + RegisterAuxDataType(&tclDictUpdateInfoType); } /* @@ -4058,7 +4069,7 @@ Tcl_Obj * TclDisassembleByteCodeObj( Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ { - ByteCode *codePtr = objPtr->internalRep.otherValuePtr; + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; unsigned char *codeStart, *codeLimit, *pc; unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; @@ -4563,7 +4574,11 @@ TclGetInnerContext( if (!objPtr) { Tcl_Panic("InnerContext: bad tos -- appending null object"); } - if (objPtr->refCount<=0 || objPtr->refCount==0x61616161) { + if ((objPtr->refCount<=0) +#ifdef TCL_MEM_DEBUG + || (objPtr->refCount==0x61616161) +#endif + ) { Tcl_Panic("InnerContext: bad tos -- appending freed object %p", objPtr); } diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 4d8ed65..79497d2 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -954,11 +954,10 @@ MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc, MODULE_SCOPE void TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE int TclNRExecuteByteCode(Tcl_Interp *interp, ByteCode *codePtr); +MODULE_SCOPE Tcl_Obj * TclFetchLiteral(CompileEnv *envPtr, unsigned int index); MODULE_SCOPE void TclFinalizeAuxDataTypeTable(void); MODULE_SCOPE int TclFindCompiledLocal(const char *name, int nameChars, int create, CompileEnv *envPtr); -MODULE_SCOPE LiteralEntry * TclLookupLiteralEntry(Tcl_Interp *interp, - Tcl_Obj *objPtr); MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, JumpFixup *jumpFixupPtr, int jumpDist, int distThreshold); @@ -967,7 +966,6 @@ MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); MODULE_SCOPE void TclInitAuxDataTypeTable(void); MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); -MODULE_SCOPE void TclInitCompilation(void); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, CompileEnv *envPtr, const char *string, int numBytes, const CmdFrame *invoker, int word); @@ -987,7 +985,6 @@ MODULE_SCOPE void TclPrintObject(FILE *outFile, Tcl_Obj *objPtr, int maxChars); MODULE_SCOPE void TclPrintSource(FILE *outFile, const char *string, int maxChars); -MODULE_SCOPE void TclRegisterAuxDataType(const AuxDataType *typePtr); MODULE_SCOPE int TclRegisterLiteral(CompileEnv *envPtr, char *bytes, int length, int flags); MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr); diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 2801102..a1c0bf4 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3783,6 +3783,7 @@ extern const TclStubs *tclStubsPtr; # undef Tcl_Init # undef Tcl_SetPanicProc # undef Tcl_SetVar +# undef Tcl_ObjSetVar2 # undef Tcl_StaticPackage # undef TclFSGetNativePath # define Tcl_CreateInterp() (tclStubsPtr->tcl_CreateInterp()) @@ -3791,6 +3792,8 @@ extern const TclStubs *tclStubsPtr; # define Tcl_SetPanicProc(proc) (tclStubsPtr->tcl_SetPanicProc(proc)) # define Tcl_SetVar(interp, varName, newValue, flags) \ (tclStubsPtr->tcl_SetVar(interp, varName, newValue, flags)) +# define Tcl_ObjSetVar2(interp, part1, part2, newValue, flags) \ + (tclStubsPtr->tcl_ObjSetVar2(interp, part1, part2, newValue, flags)) #endif #if defined(_WIN32) && defined(UNICODE) @@ -3803,4 +3806,17 @@ extern const TclStubs *tclStubsPtr; #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT +#undef Tcl_SeekOld +#undef Tcl_TellOld + +/* + * Deprecated Tcl procedures: + */ +#undef Tcl_EvalObj +#define Tcl_EvalObj(interp,objPtr) \ + Tcl_EvalObjEx((interp),(objPtr),0) +#undef Tcl_GlobalEvalObj +#define Tcl_GlobalEvalObj(interp,objPtr) \ + Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL) + #endif /* _TCLDECLS */ diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 170e744..e31d708 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -361,7 +361,7 @@ DupDictInternalRep( Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) { - Dict *oldDict = srcPtr->internalRep.otherValuePtr; + Dict *oldDict = srcPtr->internalRep.twoPtrValue.ptr1; Dict *newDict = ckalloc(sizeof(Dict)); ChainEntry *cPtr; @@ -396,7 +396,7 @@ DupDictInternalRep( * Store in the object. */ - copyPtr->internalRep.otherValuePtr = newDict; + copyPtr->internalRep.twoPtrValue.ptr1 = newDict; copyPtr->typePtr = &tclDictType; } @@ -422,14 +422,12 @@ static void FreeDictInternalRep( Tcl_Obj *dictPtr) { - Dict *dict = dictPtr->internalRep.otherValuePtr; + Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; dict->refcount--; if (dict->refcount <= 0) { DeleteDict(dict); } - - dictPtr->internalRep.otherValuePtr = NULL; /* Belt and braces! */ dictPtr->typePtr = NULL; } @@ -489,7 +487,7 @@ UpdateStringOfDict( { #define LOCAL_SIZE 20 int localFlags[LOCAL_SIZE], *flagPtr = NULL; - Dict *dict = dictPtr->internalRep.otherValuePtr; + Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; ChainEntry *cPtr; Tcl_Obj *keyPtr, *valuePtr; int i, length, bytesNeeded = 0; @@ -715,7 +713,7 @@ SetDictFromAny( dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - objPtr->internalRep.otherValuePtr = dict; + objPtr->internalRep.twoPtrValue.ptr1 = dict; objPtr->typePtr = &tclDictType; return TCL_OK; @@ -784,7 +782,7 @@ TclTraceDictPath( return NULL; } } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; if (flags & DICT_PATH_UPDATE) { dict->chain = NULL; } @@ -827,7 +825,7 @@ TclTraceDictPath( } } - newDict = tmpObj->internalRep.otherValuePtr; + newDict = tmpObj->internalRep.twoPtrValue.ptr1; if (flags & DICT_PATH_UPDATE) { if (Tcl_IsShared(tmpObj)) { TclDecrRefCount(tmpObj); @@ -835,7 +833,7 @@ TclTraceDictPath( Tcl_IncrRefCount(tmpObj); Tcl_SetHashValue(hPtr, tmpObj); dict->epoch++; - newDict = tmpObj->internalRep.otherValuePtr; + newDict = tmpObj->internalRep.twoPtrValue.ptr1; } newDict->chain = dictPtr; @@ -870,17 +868,17 @@ static void InvalidateDictChain( Tcl_Obj *dictObj) { - Dict *dict = dictObj->internalRep.otherValuePtr; + Dict *dict = dictObj->internalRep.twoPtrValue.ptr1; do { - Tcl_InvalidateStringRep(dictObj); + TclInvalidateStringRep(dictObj); dict->epoch++; dictObj = dict->chain; if (dictObj == NULL) { break; } dict->chain = NULL; - dict = dictObj->internalRep.otherValuePtr; + dict = dictObj->internalRep.twoPtrValue.ptr1; } while (dict != NULL); } @@ -927,9 +925,9 @@ Tcl_DictObjPut( } if (dictPtr->bytes != NULL) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; hPtr = CreateChainEntry(dict, keyPtr, &isNew); Tcl_IncrRefCount(valuePtr); if (!isNew) { @@ -980,7 +978,7 @@ Tcl_DictObjGet( } } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; hPtr = Tcl_FindHashEntry(&dict->table, keyPtr); if (hPtr == NULL) { *valuePtrPtr = NULL; @@ -1029,9 +1027,9 @@ Tcl_DictObjRemove( } if (dictPtr->bytes != NULL) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; if (DeleteChainEntry(dict, keyPtr)) { dict->epoch++; } @@ -1071,7 +1069,7 @@ Tcl_DictObjSize( } } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; *sizePtr = dict->table.numEntries; return TCL_OK; } @@ -1126,7 +1124,7 @@ Tcl_DictObjFirst( } } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; cPtr = dict->entryChainHead; if (cPtr == NULL) { searchPtr->epoch = -1; @@ -1301,7 +1299,7 @@ Tcl_DictObjPutKeyList( return TCL_ERROR; } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew); Tcl_IncrRefCount(valuePtr); if (!isNew) { @@ -1357,7 +1355,7 @@ Tcl_DictObjRemoveKeyList( return TCL_ERROR; } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; DeleteChainEntry(dict, keyv[keyc-1]); InvalidateDictChain(dictPtr); return TCL_OK; @@ -1397,13 +1395,13 @@ Tcl_NewDictObj(void) Dict *dict; TclNewObj(dictPtr); - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); dict = ckalloc(sizeof(Dict)); InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - dictPtr->internalRep.otherValuePtr = dict; + dictPtr->internalRep.twoPtrValue.ptr1 = dict; dictPtr->typePtr = &tclDictType; return dictPtr; #endif @@ -1446,13 +1444,13 @@ Tcl_DbNewDictObj( Dict *dict; TclDbNewObj(dictPtr, file, line); - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); dict = ckalloc(sizeof(Dict)); InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - dictPtr->internalRep.otherValuePtr = dict; + dictPtr->internalRep.twoPtrValue.ptr1 = dict; dictPtr->typePtr = &tclDictType; return dictPtr; #else /* !TCL_MEM_DEBUG */ @@ -2064,7 +2062,7 @@ DictInfoCmd( return result; } } - dict = dictPtr->internalRep.otherValuePtr; + dict = dictPtr->internalRep.twoPtrValue.ptr1; statsStr = Tcl_HashStats(&dict->table); Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1)); @@ -2179,7 +2177,7 @@ DictIncrCmd( } } if (code == TCL_OK) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); valuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr, TCL_LEAVE_ERR_MSG); if (valuePtr == NULL) { @@ -2268,7 +2266,7 @@ DictLappendCmd( if (allocatedValue) { Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr); } else if (dictPtr->bytes != NULL) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); } resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr, diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 7a55724..2cc55d6 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -270,7 +270,7 @@ static int Iso88591ToUtfProc(ClientData clientData, int *dstCharsPtr); /* - * A Tcl_ObjType for holding a cached Tcl_Encoding in the otherValuePtr field + * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field * of the intrep. This should help the lifetime of encodings be more useful. * See concerns raised in [Bug 1077262]. */ @@ -313,7 +313,7 @@ Tcl_GetEncodingFromObj( return TCL_ERROR; } TclFreeIntRep(objPtr); - objPtr->internalRep.otherValuePtr = encoding; + objPtr->internalRep.twoPtrValue.ptr1 = encoding; objPtr->typePtr = &encodingType; } *encodingPtr = Tcl_GetEncoding(NULL, name); @@ -334,7 +334,7 @@ static void FreeEncodingIntRep( Tcl_Obj *objPtr) { - Tcl_FreeEncoding(objPtr->internalRep.otherValuePtr); + Tcl_FreeEncoding(objPtr->internalRep.twoPtrValue.ptr1); objPtr->typePtr = NULL; } @@ -353,7 +353,7 @@ DupEncodingIntRep( Tcl_Obj *srcPtr, Tcl_Obj *dupPtr) { - dupPtr->internalRep.otherValuePtr = Tcl_GetEncoding(NULL, srcPtr->bytes); + dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes); } /* diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 9a2d598..813e056 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -1718,7 +1718,7 @@ NsEnsembleImplementationCmdNR( if (objv[1+ensemblePtr->numParameters]->typePtr==&tclEnsembleCmdType){ EnsembleCmdRep *ensembleCmd = objv[1+ensemblePtr->numParameters] - ->internalRep.otherValuePtr; + ->internalRep.twoPtrValue.ptr1; if (ensembleCmd->nsPtr == ensemblePtr->nsPtr && ensembleCmd->epoch == ensemblePtr->epoch && @@ -1914,7 +1914,7 @@ NsEnsembleImplementationCmdNR( * Hand off to the target command. */ - iPtr->evalFlags |= TCL_EVAL_REDIRECT; + TclSkipTailcall(interp); return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN); } @@ -2122,7 +2122,7 @@ EnsembleUnknownCallback( */ Tcl_Preserve(ensemblePtr); - ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT; + TclSkipTailcall(interp); result = Tcl_EvalObjv(interp, paramc, paramv, 0); if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) { if (!Tcl_InterpDeleted(interp)) { @@ -2196,7 +2196,7 @@ EnsembleUnknownCallback( } Tcl_AddErrorInfo(interp, "\n result of " "ensemble unknown subcommand handler: "); - Tcl_AddErrorInfo(interp, TclGetString(unknownCmd)); + Tcl_AppendObjToErrorInfo(interp, unknownCmd); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_RESULT", NULL); } else { @@ -2238,7 +2238,7 @@ MakeCachedEnsembleCommand( int length; if (objPtr->typePtr == &tclEnsembleCmdType) { - ensembleCmd = objPtr->internalRep.otherValuePtr; + ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; Tcl_DecrRefCount(ensembleCmd->realPrefixObj); TclNsDecrRefCount(ensembleCmd->nsPtr); ckfree(ensembleCmd->fullSubcmdName); @@ -2250,7 +2250,7 @@ MakeCachedEnsembleCommand( TclFreeIntRep(objPtr); ensembleCmd = ckalloc(sizeof(EnsembleCmdRep)); - objPtr->internalRep.otherValuePtr = ensembleCmd; + objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd; objPtr->typePtr = &tclEnsembleCmdType; } @@ -2645,7 +2645,7 @@ static void FreeEnsembleCmdRep( Tcl_Obj *objPtr) { - EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr; + EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; Tcl_DecrRefCount(ensembleCmd->realPrefixObj); ckfree(ensembleCmd->fullSubcmdName); @@ -2677,12 +2677,12 @@ DupEnsembleCmdRep( Tcl_Obj *objPtr, Tcl_Obj *copyPtr) { - EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr; + EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep)); int length = strlen(ensembleCmd->fullSubcmdName); copyPtr->typePtr = &tclEnsembleCmdType; - copyPtr->internalRep.otherValuePtr = ensembleCopy; + copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy; ensembleCopy->nsPtr = ensembleCmd->nsPtr; ensembleCopy->epoch = ensembleCmd->epoch; ensembleCopy->token = ensembleCmd->token; @@ -2715,7 +2715,7 @@ static void StringOfEnsembleCmdRep( Tcl_Obj *objPtr) { - EnsembleCmdRep *ensembleCmd = objPtr->internalRep.otherValuePtr; + EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1; int length = strlen(ensembleCmd->fullSubcmdName); objPtr->length = length; @@ -3056,6 +3056,9 @@ CompileToCompiledCommand( Tcl_Parse synthetic; Tcl_Token *tokenPtr; int result, i; + int savedNumCmds = envPtr->numCommands; + int savedStackDepth = envPtr->currStackDepth; + unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart; if (cmdPtr->compileProc == NULL) { return TCL_ERROR; @@ -3110,6 +3113,17 @@ CompileToCompiledCommand( result = cmdPtr->compileProc(interp, &synthetic, cmdPtr, envPtr); /* + * If our target fails to compile, revert the number of commands and the + * pointer to the place to issue the next instruction. [Bug 3600328] + */ + + if (result != TCL_OK) { + envPtr->numCommands = savedNumCmds; + envPtr->currStackDepth = savedStackDepth; + envPtr->codeNext = envPtr->codeStart + savedCodeNext; + } + + /* * Clean up if necessary. */ @@ -3153,7 +3167,7 @@ CompileToInvokedCommand( if (envPtr->clNext) { TclContinuationsEnterDerived( - envPtr->literalArrayPtr[literal].objPtr, + TclFetchLiteral(envPtr, literal), tokPtr[1].start - envPtr->source, mapPtr->loc[eclIndex].next[i]); } @@ -3176,7 +3190,7 @@ CompileToInvokedCommand( Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr); bytes = Tcl_GetStringFromObj(objPtr, &length); cmdLit = TclRegisterNewCmdLiteral(envPtr, bytes, length); - TclSetCmdNameObj(interp, envPtr->literalArrayPtr[cmdLit].objPtr, cmdPtr); + TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLit), cmdPtr); TclEmitPush(cmdLit, envPtr); TclDecrRefCount(objPtr); @@ -3225,7 +3239,7 @@ CompileBasicNArgCommand( Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr); bytes = Tcl_GetStringFromObj(objPtr, &length); literal = TclRegisterNewCmdLiteral(envPtr, bytes, length); - TclSetCmdNameObj(interp, envPtr->literalArrayPtr[literal].objPtr, cmdPtr); + TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, literal), cmdPtr); TclEmitPush(literal, envPtr); TclDecrRefCount(objPtr); diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 0b585b6..c8ba1e6 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1402,7 +1402,7 @@ Tcl_VwaitObjCmd( return TCL_ERROR; } nameString = Tcl_GetString(objv[1]); - if (Tcl_TraceVar(interp, nameString, + if (Tcl_TraceVar2(interp, nameString, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, &done) != TCL_OK) { return TCL_ERROR; @@ -1420,7 +1420,7 @@ Tcl_VwaitObjCmd( break; } } - Tcl_UntraceVar(interp, nameString, + Tcl_UntraceVar2(interp, nameString, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, &done); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 8759ec9..be2e3ca 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -259,8 +259,11 @@ VarHashCreateVar( #if TCL_COMPILE_DEBUG #define CHECK_STACK() \ - ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \ - /*checkStack*/ auxObjList == NULL) + do { \ + ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \ + /*checkStack*/ !(starting || auxObjList)); \ + starting = 0; \ + } while (0) #else #define CHECK_STACK() #endif @@ -1089,7 +1092,7 @@ GrowEvaluationStack( if (move) { moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1; } - needed = growth + moveWords + WALLOCALIGN - 1; + needed = growth + moveWords + WALLOCALIGN; /* @@ -1491,7 +1494,7 @@ CompileExprObj( if (objPtr->typePtr == &exprCodeType) { Namespace *namespacePtr = iPtr->varFramePtr->nsPtr; - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (((Interp *) *codePtr->interpHandle != iPtr) || (codePtr->compileEpoch != iPtr->compileEpoch) || (codePtr->nsPtr != namespacePtr) @@ -1531,7 +1534,7 @@ CompileExprObj( TclInitByteCodeObj(objPtr, &compEnv); objPtr->typePtr = &exprCodeType; TclFreeCompileEnv(&compEnv); - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (iPtr->varFramePtr->localCachePtr) { codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; @@ -1603,10 +1606,9 @@ static void FreeExprCodeInternalRep( Tcl_Obj *objPtr) { - ByteCode *codePtr = objPtr->internalRep.otherValuePtr; + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; objPtr->typePtr = NULL; - objPtr->internalRep.otherValuePtr = NULL; codePtr->refCount--; if (codePtr->refCount <= 0) { TclCleanupByteCode(codePtr); @@ -1664,7 +1666,7 @@ TclCompileObj( * here. */ - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (((Interp *) *codePtr->interpHandle != iPtr) || (codePtr->compileEpoch != iPtr->compileEpoch) || (codePtr->nsPtr != namespacePtr) @@ -1792,7 +1794,7 @@ TclCompileObj( iPtr->invokeWord = word; TclSetByteCodeFromAny(interp, objPtr, NULL, NULL); iPtr->invokeCmdFramePtr = NULL; - codePtr = objPtr->internalRep.otherValuePtr; + codePtr = objPtr->internalRep.twoPtrValue.ptr1; if (iPtr->varFramePtr->localCachePtr) { codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; @@ -2084,7 +2086,8 @@ TEBCresume( Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation * stack. */ const unsigned char *pc; /* The current program counter. */ - + unsigned char inst; /* The currently running instruction */ + /* * Transfer variables - needed only between opcodes, but not while * executing an instruction. @@ -2109,6 +2112,7 @@ TEBCresume( #endif #ifdef TCL_COMPILE_DEBUG + int starting = 1; traceInstructions = (tclTraceExec == 3); #endif @@ -2250,23 +2254,6 @@ TEBCresume( } cleanup0: -#ifdef TCL_COMPILE_DEBUG - /* - * Skip the stack depth check if an expansion is in progress. - */ - - CHECK_STACK(); - if (traceInstructions) { - fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH); - TclPrintInstruction(codePtr, pc); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ - -#ifdef TCL_COMPILE_STATS - iPtr->stats.instructionCount[*pc]++; -#endif - /* * Check for asynchronous handlers [Bug 746722]; we do the check every * ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1). @@ -2298,8 +2285,6 @@ TEBCresume( CACHE_STACK_INFO(); } - TCL_DTRACE_INST_NEXT(); - /* * These two instructions account for 26% of all instructions (according * to measurements on tclbench by Ben Vitale @@ -2309,13 +2294,53 @@ TEBCresume( * reduces total obj size. */ - if (*pc == INST_LOAD_SCALAR1) { - goto instLoadScalar1; - } else if (*pc == INST_PUSH1) { - goto instPush1Peephole; + inst = *pc; + + peepholeStart: +#ifdef TCL_COMPILE_STATS + iPtr->stats.instructionCount[*pc]++; +#endif + +#ifdef TCL_COMPILE_DEBUG + /* + * Skip the stack depth check if an expansion is in progress. + */ + + CHECK_STACK(); + if (traceInstructions) { + fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH); + TclPrintInstruction(codePtr, pc); + fflush(stdout); } +#endif /* TCL_COMPILE_DEBUG */ - switch (*pc) { + TCL_DTRACE_INST_NEXT(); + + if (inst == INST_LOAD_SCALAR1) { + goto instLoadScalar1; + } else if (inst == INST_PUSH1) { + PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]); + TRACE_WITH_OBJ(("%u => ", TclGetInt1AtPtr(pc+1)), OBJ_AT_TOS); + inst = *(pc += 2); + goto peepholeStart; + } else if (inst == INST_START_CMD) { + /* + * Peephole: do not run INST_START_CMD, just skip it + */ + + iPtr->cmdCount += TclGetUInt4AtPtr(pc+5); + if (checkInterp) { + checkInterp = 0; + if ((codePtr->compileEpoch != iPtr->compileEpoch) + || (codePtr->nsEpoch != iPtr->varFramePtr->nsPtr->resolverEpoch)) { + goto instStartCmdFailed; + } + } + inst = *(pc += 9); + goto peepholeStart; + } + + switch (inst) { case INST_SYNTAX: case INST_RETURN_IMM: { int code = TclGetInt4AtPtr(pc+1); @@ -2399,7 +2424,6 @@ TEBCresume( case INST_TAILCALL: { Tcl_Obj *listPtr, *nsObjPtr; - NRE_callback *tailcallPtr; opnd = TclGetUInt1AtPtr(pc+1); @@ -2433,18 +2457,12 @@ TEBCresume( listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1)); nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1); - Tcl_IncrRefCount(listPtr); - Tcl_IncrRefCount(nsObjPtr); - TclNRAddCallback(interp, TclNRTailcallEval, listPtr, nsObjPtr, - NULL, NULL); - - /* - * Unstitch ourselves and do a [return]. - */ + TclListObjSetElement(interp, listPtr, 0, nsObjPtr); + if (iPtr->varFramePtr->tailcallPtr) { + Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr); + } + iPtr->varFramePtr->tailcallPtr = listPtr; - tailcallPtr = TOP_CB(interp); - TOP_CB(interp) = tailcallPtr->nextPtr; - iPtr->varFramePtr->tailcallPtr = tailcallPtr; result = TCL_RETURN; cleanup = opnd; goto processExceptionReturn; @@ -2472,23 +2490,6 @@ TEBCresume( (void) POP_OBJECT(); goto abnormalReturn; - case INST_PUSH1: - instPush1Peephole: - PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]); - TRACE_WITH_OBJ(("%u => ", TclGetInt1AtPtr(pc+1)), OBJ_AT_TOS); - pc += 2; -#if !TCL_COMPILE_DEBUG - /* - * Runtime peephole optimisation: check if we are pushing again. - */ - - if (*pc == INST_PUSH1) { - TCL_DTRACE_INST_NEXT(); - goto instPush1Peephole; - } -#endif - NEXT_INST_F(0, 0, 0); - case INST_PUSH4: objResultPtr = codePtr->objArrayPtr[TclGetUInt4AtPtr(pc+1)]; TRACE_WITH_OBJ(("%u => ", TclGetUInt4AtPtr(pc+1)), objResultPtr); @@ -2498,68 +2499,10 @@ TEBCresume( TRACE_WITH_OBJ(("=> discarding "), OBJ_AT_TOS); objPtr = POP_OBJECT(); TclDecrRefCount(objPtr); - - /* - * Runtime peephole optimisation: an INST_POP is scheduled at the end - * of most commands. If the next instruction is an INST_START_CMD, - * fall through to it. - */ - - pc++; -#if !TCL_COMPILE_DEBUG - if (*pc == INST_START_CMD) { - TCL_DTRACE_INST_NEXT(); - goto instStartCmdPeephole; - } -#endif - NEXT_INST_F(0, 0, 0); - - case INST_START_CMD: -#if !TCL_COMPILE_DEBUG - instStartCmdPeephole: -#endif - /* - * Remark that if the interpreter is marked for deletion its - * compileEpoch is modified, so that the epoch check also verifies - * that the interp is not deleted. If no outside call has been made - * since the last check, it is safe to omit the check. - */ - - iPtr->cmdCount += TclGetUInt4AtPtr(pc+5); - if (!checkInterp) { - goto instStartCmdOK; - } else if (((codePtr->compileEpoch == iPtr->compileEpoch) - && (codePtr->nsEpoch == iPtr->varFramePtr->nsPtr->resolverEpoch)) - || (codePtr->flags & TCL_BYTECODE_PRECOMPILED)) { - checkInterp = 0; - instStartCmdOK: - NEXT_INST_F(9, 0, 0); - } else { - const char *bytes; - - length = 0; - - /* - * We used to switch to direct eval; for NRE-awareness we now - * compile and eval the command so that this evaluation does not - * add a new TEBC instance. [Bug 2910748] - */ - - if (TclInterpReady(interp) == TCL_ERROR) { - goto gotError; - } - - codePtr->flags |= TCL_BYTECODE_RECOMPILE; - bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL); - opnd = TclGetUInt4AtPtr(pc+1); - pc += (opnd-1); - PUSH_OBJECT(Tcl_NewStringObj(bytes, length)); - goto instEvalStk; - } + NEXT_INST_F(1, 0, 0); case INST_NOP: - pc += 1; - goto cleanup0; + NEXT_INST_F(1, 0, 0); case INST_DUP: objResultPtr = OBJ_AT_TOS; @@ -3054,8 +2997,9 @@ TEBCresume( DECACHE_STACK_INFO(); pc += 6; TEBC_YIELD(); + TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); - iPtr->evalFlags |= TCL_EVAL_REDIRECT; + TclSkipTailcall(interp); return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN); /* @@ -3519,8 +3463,8 @@ TEBCresume( varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr, TCL_LEAVE_ERR_MSG, "read", 1, 1, &arrayPtr); if (!varPtr) { - Tcl_AddObjErrorInfo(interp, - "\n (reading value of variable to increment)", -1); + Tcl_AddErrorInfo(interp, + "\n (reading value of variable to increment)"); TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); Tcl_DecrRefCount(incrPtr); goto gotError; @@ -7108,6 +7052,42 @@ TEBCresume( TclStackFree(interp, TD); /* free my stack */ return result; + + /* + * INST_START_CMD failure case removed where it doesn't bother that much + * + * Remark that if the interpreter is marked for deletion its + * compileEpoch is modified, so that the epoch check also verifies + * that the interp is not deleted. If no outside call has been made + * since the last check, it is safe to omit the check. + + * case INST_START_CMD: + */ + + instStartCmdFailed: + { + const char *bytes; + + checkInterp = 1; + length = 0; + + /* + * We used to switch to direct eval; for NRE-awareness we now + * compile and eval the command so that this evaluation does not + * add a new TEBC instance. [Bug 2910748] + */ + + if (TclInterpReady(interp) == TCL_ERROR) { + goto gotError; + } + + codePtr->flags |= TCL_BYTECODE_RECOMPILE; + bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL); + opnd = TclGetUInt4AtPtr(pc+1); + pc += (opnd-1); + PUSH_OBJECT(Tcl_NewStringObj(bytes, length)); + goto instEvalStk; + } } #undef codePtr diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c index 33c1496..13377d3 100644 --- a/generic/tclFCmd.c +++ b/generic/tclFCmd.c @@ -734,17 +734,14 @@ CopyRenameOneFile( */ errfile = target; - - /* - * We now need to reset the result, because the above call, if it - * failed, may have put an error message in place. (Ideally we - * would prefer not to pass an interpreter in above, but the - * channel IO code used by TclCrossFilesystemCopy currently - * requires one). - */ - - Tcl_ResetResult(interp); } + /* + * We now need to reset the result, because the above call, + * may have left set it. (Ideally we would prefer not to pass + * an interpreter in above, but the channel IO code used by + * TclCrossFilesystemCopy currently requires one) + */ + Tcl_ResetResult(interp); } if ((copyFlag == 0) && (result == TCL_OK)) { if (S_ISDIR(sourceStatBuf.st_mode)) { diff --git a/generic/tclGet.c b/generic/tclGet.c index 4c19b55..97e8c7b 100644 --- a/generic/tclGet.c +++ b/generic/tclGet.c @@ -137,7 +137,7 @@ Tcl_GetBoolean( obj.length = strlen(src); obj.typePtr = NULL; - code = Tcl_ConvertToType(interp, &obj, &tclBooleanType); + code = TclSetBooleanFromAny(interp, &obj); if (obj.refCount > 1) { Tcl_Panic("invalid sharing of Tcl_Obj on C stack"); } diff --git a/generic/tclIO.c b/generic/tclIO.c index 715c1ef..f1d85bf 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -16,6 +16,108 @@ #include <assert.h> /* + * For each channel handler registered in a call to Tcl_CreateChannelHandler, + * there is one record of the following type. All of records for a specific + * channel are chained together in a singly linked list which is stored in + * the channel structure. + */ + +typedef struct ChannelHandler { + Channel *chanPtr; /* The channel structure for this channel. */ + int mask; /* Mask of desired events. */ + Tcl_ChannelProc *proc; /* Procedure to call in the type of + * Tcl_CreateChannelHandler. */ + ClientData clientData; /* Argument to pass to procedure. */ + struct ChannelHandler *nextPtr; + /* Next one in list of registered handlers. */ +} ChannelHandler; + +/* + * This structure keeps track of the current ChannelHandler being invoked in + * the current invocation of ChannelHandlerEventProc. There is a potential + * problem if a ChannelHandler is deleted while it is the current one, since + * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this + * problem, structures of the type below indicate the next handler to be + * processed for any (recursively nested) dispatches in progress. The + * nextHandlerPtr field is updated if the handler being pointed to is deleted. + * The nextPtr field is used to chain together all recursive invocations, so + * that Tcl_DeleteChannelHandler can find all the recursively nested + * invocations of ChannelHandlerEventProc and compare the handler being + * deleted against the NEXT handler to be invoked in that invocation; when it + * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr + * field of the structure to the next handler. + */ + +typedef struct NextChannelHandler { + ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in + * this invocation. */ + struct NextChannelHandler *nestedHandlerPtr; + /* Next nested invocation of + * ChannelHandlerEventProc. */ +} NextChannelHandler; + +/* + * The following structure describes the event that is added to the Tcl + * event queue by the channel handler check procedure. + */ + +typedef struct ChannelHandlerEvent { + Tcl_Event header; /* Standard header for all events. */ + Channel *chanPtr; /* The channel that is ready. */ + int readyMask; /* Events that have occurred. */ +} ChannelHandlerEvent; + +/* + * The following structure is used by Tcl_GetsObj() to encapsulates the + * state for a "gets" operation. + */ + +typedef struct GetsState { + Tcl_Obj *objPtr; /* The object to which UTF-8 characters + * will be appended. */ + char **dstPtr; /* Pointer into objPtr's string rep where + * next character should be stored. */ + Tcl_Encoding encoding; /* The encoding to use to convert raw bytes + * to UTF-8. */ + ChannelBuffer *bufPtr; /* The current buffer of raw bytes being + * emptied. */ + Tcl_EncodingState state; /* The encoding state just before the last + * external to UTF-8 conversion in + * FilterInputBytes(). */ + int rawRead; /* The number of bytes removed from bufPtr + * in the last call to FilterInputBytes(). */ + int bytesWrote; /* The number of bytes of UTF-8 data + * appended to objPtr during the last call to + * FilterInputBytes(). */ + int charsWrote; /* The corresponding number of UTF-8 + * characters appended to objPtr during the + * last call to FilterInputBytes(). */ + int totalChars; /* The total number of UTF-8 characters + * appended to objPtr so far, just before the + * last call to FilterInputBytes(). */ +} GetsState; + +/* + * The following structure encapsulates the state for a background channel + * copy. Note that the data buffer for the copy will be appended to this + * structure. + */ + +typedef struct CopyState { + struct Channel *readPtr; /* Pointer to input channel. */ + struct Channel *writePtr; /* Pointer to output channel. */ + int readFlags; /* Original read channel flags. */ + int writeFlags; /* Original write channel flags. */ + Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */ + Tcl_WideInt total; /* Total bytes transferred (written). */ + Tcl_Interp *interp; /* Interp that started the copy. */ + Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ + int bufSize; /* Size of appended buffer. */ + char buffer[1]; /* Copy buffer, this must be the last + * field. */ +} CopyState; + +/* * All static variables used in this file are collected into a single instance * of the following structure. For multi-threaded implementations, there is * one instance of this structure for each thread. @@ -44,6 +146,18 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; /* + * Structure to record a close callback. One such record exists for + * each close callback registered for a channel. + */ + +typedef struct CloseCallback { + Tcl_CloseProc *proc; /* The procedure to call. */ + ClientData clientData; /* Arbitrary one-word data to pass + * to the callback. */ + struct CloseCallback *nextPtr; /* For chaining close callbacks. */ +} CloseCallback; + +/* * Static functions in this file: */ @@ -221,9 +335,9 @@ static const Tcl_ObjType tclChannelType = { }; #define GET_CHANNELSTATE(objPtr) \ - ((ChannelState *) (objPtr)->internalRep.otherValuePtr) + ((ChannelState *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_CHANNELSTATE(objPtr, storePtr) \ - ((objPtr)->internalRep.otherValuePtr = (void *) (storePtr)) + ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (storePtr)) #define GET_CHANNELINTERP(objPtr) \ ((Interp *) (objPtr)->internalRep.twoPtrValue.ptr2) #define SET_CHANNELINTERP(objPtr, storePtr) \ @@ -695,6 +809,8 @@ Tcl_DeleteCloseHandler( if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == NULL) { statePtr->closeCbPtr = cbPtr->nextPtr; + } else { + cbPrevPtr->nextPtr = cbPtr->nextPtr; } ckfree(cbPtr); break; diff --git a/generic/tclIO.h b/generic/tclIO.h index 1e89878..e84f300 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -30,26 +30,6 @@ #endif /* - * The following structure encapsulates the state for a background channel - * copy. Note that the data buffer for the copy will be appended to this - * structure. - */ - -typedef struct CopyState { - struct Channel *readPtr; /* Pointer to input channel. */ - struct Channel *writePtr; /* Pointer to output channel. */ - int readFlags; /* Original read channel flags. */ - int writeFlags; /* Original write channel flags. */ - Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */ - Tcl_WideInt total; /* Total bytes transferred (written). */ - Tcl_Interp *interp; /* Interp that started the copy. */ - Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ - int bufSize; /* Size of appended buffer. */ - char buffer[1]; /* Copy buffer, this must be the last - * field. */ -} CopyState; - -/* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. @@ -86,19 +66,6 @@ typedef struct ChannelBuffer { #define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4) /* - * Structure to record a close callback. One such record exists for each close - * callback registered for a channel. - */ - -typedef struct CloseCallback { - Tcl_CloseProc *proc; /* The procedure to call. */ - ClientData clientData; /* Arbitrary one-word data to pass to the - * callback. */ - struct CloseCallback *nextPtr; - /* For chaining close callbacks. */ -} CloseCallback; - -/* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to invoke * the saved script in the interpreter designed in this record. @@ -195,7 +162,8 @@ typedef struct ChannelState { * value is the POSIX error code. */ int refCount; /* How many interpreters hold references to * this IO channel? */ - CloseCallback *closeCbPtr; /* Callbacks registered to be called when the + struct CloseCallback *closeCbPtr; + /* Callbacks registered to be called when the * channel is closed. */ char *outputStage; /* Temporary staging buffer used when * translating EOL before converting from @@ -217,8 +185,10 @@ typedef struct ChannelState { * handlers ("fileevent") on this channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ - CopyState *csPtrR; /* State of background copy for which channel is input, or NULL. */ - CopyState *csPtrW; /* State of background copy for which channel is output, or NULL. */ + struct CopyState *csPtrR; /* State of background copy for which channel + * is input, or NULL. */ + struct CopyState *csPtrW; /* State of background copy for which channel + * is output, or NULL. */ Channel *topChanPtr; /* Refers to topmost channel in a stack. Never * NULL. */ Channel *bottomChanPtr; /* Refers to bottommost channel in a stack. @@ -342,89 +312,6 @@ typedef struct ChannelState { * the channel is allowed. */ /* - * For each channel handler registered in a call to Tcl_CreateChannelHandler, - * there is one record of the following type. All of records for a specific - * channel are chained together in a singly linked list which is stored in the - * channel structure. - */ - -typedef struct ChannelHandler { - Channel *chanPtr; /* The channel structure for this channel. */ - int mask; /* Mask of desired events. */ - Tcl_ChannelProc *proc; /* Procedure to call in the type of - * Tcl_CreateChannelHandler. */ - ClientData clientData; /* Argument to pass to procedure. */ - struct ChannelHandler *nextPtr; - /* Next one in list of registered handlers. */ -} ChannelHandler; - -/* - * This structure keeps track of the current ChannelHandler being invoked in - * the current invocation of ChannelHandlerEventProc. There is a potential - * problem if a ChannelHandler is deleted while it is the current one, since - * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this - * problem, structures of the type below indicate the next handler to be - * processed for any (recursively nested) dispatches in progress. The - * nextHandlerPtr field is updated if the handler being pointed to is deleted. - * The nextPtr field is used to chain together all recursive invocations, so - * that Tcl_DeleteChannelHandler can find all the recursively nested - * invocations of ChannelHandlerEventProc and compare the handler being - * deleted against the NEXT handler to be invoked in that invocation; when it - * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr - * field of the structure to the next handler. - */ - -typedef struct NextChannelHandler { - ChannelHandler *nextHandlerPtr; - /* The next handler to be invoked in this - * invocation. */ - struct NextChannelHandler *nestedHandlerPtr; - /* Next nested invocation of - * ChannelHandlerEventProc. */ -} NextChannelHandler; - -/* - * The following structure describes the event that is added to the Tcl event - * queue by the channel handler check procedure. - */ - -typedef struct ChannelHandlerEvent { - Tcl_Event header; /* Standard header for all events. */ - Channel *chanPtr; /* The channel that is ready. */ - int readyMask; /* Events that have occurred. */ -} ChannelHandlerEvent; - -/* - * The following structure is used by Tcl_GetsObj() to encapsulates the state - * for a "gets" operation. - */ - -typedef struct GetsState { - Tcl_Obj *objPtr; /* The object to which UTF-8 characters will - * be appended. */ - char **dstPtr; /* Pointer into objPtr's string rep where next - * character should be stored. */ - Tcl_Encoding encoding; /* The encoding to use to convert raw bytes to - * UTF-8. */ - ChannelBuffer *bufPtr; /* The current buffer of raw bytes being - * emptied. */ - Tcl_EncodingState state; /* The encoding state just before the last - * external to UTF-8 conversion in - * FilterInputBytes(). */ - int rawRead; /* The number of bytes removed from bufPtr in - * the last call to FilterInputBytes(). */ - int bytesWrote; /* The number of bytes of UTF-8 data appended - * to objPtr during the last call to - * FilterInputBytes(). */ - int charsWrote; /* The corresponding number of UTF-8 - * characters appended to objPtr during the - * last call to FilterInputBytes(). */ - int totalChars; /* The total number of UTF-8 characters - * appended to objPtr so far, just before the - * last call to FilterInputBytes(). */ -} GetsState; - -/* * The length of time to wait between synthetic timer events. Must be zero or * bad things tend to happen. */ diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index ab08353..25ed57c 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -18,9 +18,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#if defined(HAVE_SYS_STAT_H) && !defined _WIN32 -# include <sys/stat.h> -#endif #include "tclInt.h" #ifdef __WIN32__ # include "tclWinInt.h" diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index 512f5ba..ce8b9fb 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -53,7 +53,7 @@ static const Tcl_ObjType indexType = { /* * The definition of the internal representation of the "index" object; The - * internalRep.otherValuePtr field of an object of "index" type will be a + * internalRep.twoPtrValue.ptr1 field of an object of "index" type will be a * pointer to one of these structures. * * Keep this structure declaration in sync with tclTestObj.c @@ -69,12 +69,12 @@ typedef struct { * The following macros greatly simplify moving through a table... */ -#define STRING_AT(table, offset, index) \ - (*((const char *const *)(((char *)(table)) + ((offset) * (index))))) +#define STRING_AT(table, offset) \ + (*((const char *const *)(((char *)(table)) + (offset)))) #define NEXT_ENTRY(table, offset) \ - (&(STRING_AT(table, offset, 1))) + (&(STRING_AT(table, offset))) #define EXPAND_OF(indexRep) \ - STRING_AT((indexRep)->tablePtr, (indexRep)->offset, (indexRep)->index) + STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index) /* *---------------------------------------------------------------------- @@ -101,6 +101,7 @@ typedef struct { *---------------------------------------------------------------------- */ +#undef Tcl_GetIndexFromObj int Tcl_GetIndexFromObj( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ @@ -121,7 +122,7 @@ Tcl_GetIndexFromObj( */ if (objPtr->typePtr == &indexType) { - IndexRep *indexRep = objPtr->internalRep.otherValuePtr; + IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1; /* * Here's hoping we don't get hit by unfortunate packing constraints @@ -238,7 +239,7 @@ GetIndexFromObjList( * a proper match, then TCL_ERROR is returned and an error message is * left in interp's result (unless interp is NULL). The msg argument is * used in the error message; for example, if msg has the value "option" - * then the error message will say something flag 'bad option "foo": must + * then the error message will say something like 'bad option "foo": must * be ...' * * Side effects: @@ -270,12 +271,16 @@ Tcl_GetIndexFromObjStruct( Tcl_Obj *resultPtr; IndexRep *indexRep; + /* Protect against invalid values, like -1 or 0. */ + if (offset < (int)sizeof(char *)) { + offset = (int)sizeof(char *); + } /* * See if there is a valid cached result from a previous lookup. */ if (objPtr->typePtr == &indexType) { - indexRep = objPtr->internalRep.otherValuePtr; + indexRep = objPtr->internalRep.twoPtrValue.ptr1; if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) { *indexPtr = indexRep->index; return TCL_OK; @@ -336,11 +341,11 @@ Tcl_GetIndexFromObjStruct( */ if (objPtr->typePtr == &indexType) { - indexRep = objPtr->internalRep.otherValuePtr; + indexRep = objPtr->internalRep.twoPtrValue.ptr1; } else { TclFreeIntRep(objPtr); indexRep = ckalloc(sizeof(IndexRep)); - objPtr->internalRep.otherValuePtr = indexRep; + objPtr->internalRep.twoPtrValue.ptr1 = indexRep; objPtr->typePtr = &indexType; } indexRep->tablePtr = (void *) tablePtr; @@ -443,7 +448,7 @@ static void UpdateStringOfIndex( Tcl_Obj *objPtr) { - IndexRep *indexRep = objPtr->internalRep.otherValuePtr; + IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1; register char *buf; register unsigned len; register const char *indexStr = EXPAND_OF(indexRep); @@ -478,11 +483,11 @@ DupIndex( Tcl_Obj *srcPtr, Tcl_Obj *dupPtr) { - IndexRep *srcIndexRep = srcPtr->internalRep.otherValuePtr; + IndexRep *srcIndexRep = srcPtr->internalRep.twoPtrValue.ptr1; IndexRep *dupIndexRep = ckalloc(sizeof(IndexRep)); memcpy(dupIndexRep, srcIndexRep, sizeof(IndexRep)); - dupPtr->internalRep.otherValuePtr = dupIndexRep; + dupPtr->internalRep.twoPtrValue.ptr1 = dupIndexRep; dupPtr->typePtr = &indexType; } @@ -507,7 +512,7 @@ static void FreeIndex( Tcl_Obj *objPtr) { - ckfree(objPtr->internalRep.otherValuePtr); + ckfree(objPtr->internalRep.twoPtrValue.ptr1); objPtr->typePtr = NULL; } @@ -948,13 +953,13 @@ Tcl_WrongNumArgs( if (origObjv[i]->typePtr == &indexType) { register IndexRep *indexRep = - origObjv[i]->internalRep.otherValuePtr; + origObjv[i]->internalRep.twoPtrValue.ptr1; elementStr = EXPAND_OF(indexRep); elemLen = strlen(elementStr); } else if (origObjv[i]->typePtr == &tclEnsembleCmdType) { register EnsembleCmdRep *ecrPtr = - origObjv[i]->internalRep.otherValuePtr; + origObjv[i]->internalRep.twoPtrValue.ptr1; elementStr = ecrPtr->fullSubcmdName; elemLen = strlen(elementStr); @@ -1003,12 +1008,12 @@ Tcl_WrongNumArgs( */ if (objv[i]->typePtr == &indexType) { - register IndexRep *indexRep = objv[i]->internalRep.otherValuePtr; + register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1; Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL); } else if (objv[i]->typePtr == &tclEnsembleCmdType) { register EnsembleCmdRep *ecrPtr = - objv[i]->internalRep.otherValuePtr; + objv[i]->internalRep.twoPtrValue.ptr1; Tcl_AppendStringsToObj(objPtr, ecrPtr->fullSubcmdName, NULL); } else { diff --git a/generic/tclInt.decls b/generic/tclInt.decls index f215d32..f0e907f 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -626,14 +626,14 @@ declare 156 { declare 157 { Var *TclVarTraceExists(Tcl_Interp *interp, const char *varName) } -# REMOVED - use public Tcl_SetStartupScript() -#declare 158 { -# void TclSetStartupScriptFileName(const char *filename) -#} -# REMOVED - use public Tcl_GetStartupScript() -#declare 159 { -# const char *TclGetStartupScriptFileName(void) -#} +# REMOVED (except from stub table) - use public Tcl_SetStartupScript() +declare 158 { + void TclSetStartupScriptFileName(const char *filename) +} +# REMOVED (except from stub table) - use public Tcl_GetStartupScript() +declare 159 { + const char *TclGetStartupScriptFileName(void) +} #declare 160 { # int TclpMatchFilesTypes(Tcl_Interp *interp, char *separators, # Tcl_DString *dirPtr, char *pattern, char *tail, @@ -678,14 +678,14 @@ declare 166 { } # VFS-aware versions of Tcl*StartupScriptFileName (158 and 159 above) -# REMOVED - use public Tcl_SetStartupScript() -#declare 167 { -# void TclSetStartupScriptPath(Tcl_Obj *pathPtr) -#} -# REMOVED - use public Tcl_GetStartupScript() -#declare 168 { -# Tcl_Obj *TclGetStartupScriptPath(void) -#} +# REMOVED (except from stub table) - use public Tcl_SetStartupScript() +declare 167 { + void TclSetStartupScriptPath(Tcl_Obj *pathPtr) +} +# REMOVED (except from stub table) - use public Tcl_GetStartupScript() +declare 168 { + Tcl_Obj *TclGetStartupScriptPath(void) +} # variant of Tcl_UtfNCmp that takes n as bytes, not chars declare 169 { int TclpUtfNcmp2(const char *s1, const char *s2, unsigned long n) @@ -731,13 +731,13 @@ declare 177 { void TclVarErrMsg(Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason) } -# TIP 338 made these public - now declared in tcl.h -#declare 178 { -# void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName) -#} -#declare 179 { -# Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr) -#} +# TIP 338 made these public - now declared in tcl.h too +declare 178 { + void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName) +} +declare 179 { + Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr) +} # REMOVED # Allocate lists without copying arrays @@ -941,9 +941,9 @@ declare 235 { # TIP 337 made this one public -#declare 236 { -# void TclBackgroundException(Tcl_Interp *interp, int code) -#} +declare 236 { + void TclBackgroundException(Tcl_Interp *interp, int code) +} # TIP #285: Script cancellation support. declare 237 { diff --git a/generic/tclInt.h b/generic/tclInt.h index 537afb3..1f939c0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -396,7 +396,7 @@ struct NamespacePathEntry { /* * The data cached in an ensemble subcommand's Tcl_Obj rep (reference in - * otherValuePtr field). This structure is not shared between Tcl_Objs + * twoPtrValue.ptr1 field). This structure is not shared between Tcl_Objs * referring to the same subcommand, even where one is a duplicate of another. */ @@ -589,30 +589,6 @@ typedef struct ActiveVarTrace { } ActiveVarTrace; /* - * The following structure describes an enumerative search in progress on an - * array variable; this are invoked with options to the "array" command. - */ - -typedef struct ArraySearch { - int id; /* Integer id used to distinguish among - * multiple concurrent searches for the same - * array. */ - struct Var *varPtr; /* Pointer to array variable that's being - * searched. */ - Tcl_HashSearch search; /* Info kept by the hash module about progress - * through the array. */ - Tcl_HashEntry *nextEntry; /* Non-null means this is the next element to - * be enumerated (it's leftover from the - * Tcl_FirstHashEntry call or from an "array - * anymore" command). NULL means must call - * Tcl_NextHashEntry to get value to - * return. */ - struct ArraySearch *nextPtr;/* Next in list of all active searches for - * this variable, or NULL if this is the last - * one. */ -} ArraySearch; - -/* * The structure below defines a variable, which associates a string name with * a Tcl_Obj value. These structures are kept in procedure call frames (for * local variables recognized by the compiler) or in the heap (for global @@ -1154,7 +1130,7 @@ typedef struct CallFrame { * meaning of the value is, which we do not * specify. */ LocalCache *localCachePtr; - struct NRE_callback *tailcallPtr; + Tcl_Obj *tailcallPtr; /* NULL if no tailcall is scheduled */ } CallFrame; @@ -2202,17 +2178,6 @@ typedef struct Interp { (iPtr)->flags &= (~(CANCELED | TCL_CANCEL_UNWIND)) /* - * General list of interpreters. Doubly linked for easier removal of items - * deep in the list. - */ - -typedef struct InterpList { - Interp *interpPtr; - struct InterpList *prevPtr; - struct InterpList *nextPtr; -} InterpList; - -/* * Macros for splicing into and out of doubly linked lists. They assume * existence of struct items 'prevPtr' and 'nextPtr'. * @@ -2250,7 +2215,6 @@ typedef struct InterpList { #define TCL_ALLOW_EXCEPTIONS 4 #define TCL_EVAL_FILE 2 #define TCL_EVAL_CTX 8 -#define TCL_EVAL_REDIRECT 16 /* * Flag bits for Interp structures: @@ -2318,35 +2282,6 @@ typedef struct InterpList { #define MAX_NESTING_DEPTH 1000 /* - * TIP#143 limit handler internal representation. - */ - -struct LimitHandler { - int flags; /* The state of this particular handler. */ - Tcl_LimitHandlerProc *handlerProc; - /* The handler callback. */ - ClientData clientData; /* Opaque argument to the handler callback. */ - Tcl_LimitHandlerDeleteProc *deleteProc; - /* How to delete the clientData. */ - LimitHandler *prevPtr; /* Previous item in linked list of - * handlers. */ - LimitHandler *nextPtr; /* Next item in linked list of handlers. */ -}; - -/* - * Values for the LimitHandler flags field. - * LIMIT_HANDLER_ACTIVE - Whether the handler is currently being - * processed; handlers are never to be entered reentrantly. - * LIMIT_HANDLER_DELETED - Whether the handler has been deleted. This - * should not normally be observed because when a handler is - * deleted it is also spliced out of the list of handlers, but - * even so we will be careful. - */ - -#define LIMIT_HANDLER_ACTIVE 0x01 -#define LIMIT_HANDLER_DELETED 0x02 - -/* * The macro below is used to modify a "char" value (e.g. by casting it to an * unsigned character) so that it can be used safely with macros such as * isspace. @@ -2805,8 +2740,12 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd; -MODULE_SCOPE void TclSpliceTailcall(Tcl_Interp *interp, - struct NRE_callback *tailcallPtr); +MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr); +MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); + +/* These two can be considered for the public api */ +MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp); +MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp); /* * This structure holds the data for the various iteration callbacks used to @@ -2881,7 +2820,6 @@ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, const unsigned char *bytes, int len); MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); -MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next, int loc); MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, @@ -3132,6 +3070,7 @@ MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp, Tcl_Obj *cmdPrefix); MODULE_SCOPE void TclSetBignumIntRep(Tcl_Obj *objPtr, mp_int *bignumValue); +MODULE_SCOPE int TclSetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE void TclSetCmdNameObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Command *cmdPtr); MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr); @@ -4086,7 +4025,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *); (objPtr) = TclThreadAllocObj(); \ } else { \ (objPtr) = cachePtr->firstObjPtr; \ - cachePtr->firstObjPtr = (objPtr)->internalRep.otherValuePtr; \ + cachePtr->firstObjPtr = (objPtr)->internalRep.twoPtrValue.ptr1; \ --cachePtr->numObjects; \ } \ } while (0) @@ -4099,7 +4038,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *); (cachePtr->numObjects >= ALLOC_NOBJHIGH))) { \ TclThreadFreeObj(objPtr); \ } else { \ - (objPtr)->internalRep.otherValuePtr = cachePtr->firstObjPtr; \ + (objPtr)->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; \ cachePtr->firstObjPtr = objPtr; \ ++cachePtr->numObjects; \ } \ @@ -4127,14 +4066,14 @@ MODULE_SCOPE Tcl_Mutex tclObjMutex; } \ (objPtr) = tclFreeObjList; \ tclFreeObjList = (Tcl_Obj *) \ - tclFreeObjList->internalRep.otherValuePtr; \ + tclFreeObjList->internalRep.twoPtrValue.ptr1; \ Tcl_MutexUnlock(&tclObjMutex); \ } while (0) # define TclFreeObjStorageEx(interp, objPtr) \ do { \ Tcl_MutexLock(&tclObjMutex); \ - (objPtr)->internalRep.otherValuePtr = (void *) tclFreeObjList; \ + (objPtr)->internalRep.twoPtrValue.ptr1 = (void *) tclFreeObjList; \ tclFreeObjList = (objPtr); \ Tcl_MutexUnlock(&tclObjMutex); \ } while (0) @@ -4808,35 +4747,6 @@ typedef struct NRE_callback { TOP_CB(interp) = callbackPtr; \ } while (0) -#define TclNRDeferCallback(interp,postProcPtr,data0,data1,data2,data3) \ - do { \ - NRE_callback *callbackPtr; \ - TCLNR_ALLOC((interp), (callbackPtr)); \ - callbackPtr->procPtr = (postProcPtr); \ - callbackPtr->data[0] = (ClientData)(data0); \ - callbackPtr->data[1] = (ClientData)(data1); \ - callbackPtr->data[2] = (ClientData)(data2); \ - callbackPtr->data[3] = (ClientData)(data3); \ - callbackPtr->nextPtr = ((Interp *)interp)->deferredCallbacks; \ - ((Interp *)interp)->deferredCallbacks = callbackPtr; \ - } while (0) - -#define TclNRSpliceCallbacks(interp, topPtr) \ - do { \ - NRE_callback *bottomPtr = topPtr; \ - while (bottomPtr->nextPtr) { \ - bottomPtr = bottomPtr->nextPtr; \ - } \ - bottomPtr->nextPtr = TOP_CB(interp); \ - TOP_CB(interp) = topPtr; \ - } while (0) - -#define TclNRSpliceDeferred(interp) \ - if (((Interp *)interp)->deferredCallbacks) { \ - TclNRSpliceCallbacks(interp, ((Interp *)interp)->deferredCallbacks); \ - ((Interp *)interp)->deferredCallbacks = NULL; \ - } - #if NRE_USE_SMALL_ALLOC #define TCLNR_ALLOC(interp, ptr) \ TclSmallAllocEx(interp, sizeof(NRE_callback), (ptr)) diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index df5ac97..533d6f4 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -29,19 +29,20 @@ #endif /* [Bug #803489] Tcl_FindNamespace problem in the Stubs table */ -#undef Tcl_AppendExportList #undef Tcl_CreateNamespace #undef Tcl_DeleteNamespace +#undef Tcl_AppendExportList #undef Tcl_Export -#undef Tcl_FindCommand -#undef Tcl_FindNamespace -#undef Tcl_FindNamespaceVar +#undef Tcl_Import #undef Tcl_ForgetImport -#undef Tcl_GetCommandFromObj -#undef Tcl_GetCommandFullName #undef Tcl_GetCurrentNamespace #undef Tcl_GetGlobalNamespace -#undef Tcl_Import +#undef Tcl_FindNamespace +#undef Tcl_FindCommand +#undef Tcl_GetCommandFromObj +#undef Tcl_GetCommandFullName +#undef Tcl_SetStartupScript +#undef Tcl_GetStartupScript /* * WARNING: This file is automatically generated by the tools/genStubs.tcl @@ -395,8 +396,10 @@ EXTERN void TclRegError(Tcl_Interp *interp, const char *msg, /* 157 */ EXTERN Var * TclVarTraceExists(Tcl_Interp *interp, const char *varName); -/* Slot 158 is reserved */ -/* Slot 159 is reserved */ +/* 158 */ +EXTERN void TclSetStartupScriptFileName(const char *filename); +/* 159 */ +EXTERN const char * TclGetStartupScriptFileName(void); /* Slot 160 is reserved */ /* 161 */ EXTERN int TclChannelTransform(Tcl_Interp *interp, @@ -414,8 +417,10 @@ EXTERN void TclpSetInitialEncodings(void); EXTERN int TclListObjSetElement(Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj *valuePtr); -/* Slot 167 is reserved */ -/* Slot 168 is reserved */ +/* 167 */ +EXTERN void TclSetStartupScriptPath(Tcl_Obj *pathPtr); +/* 168 */ +EXTERN Tcl_Obj * TclGetStartupScriptPath(void); /* 169 */ EXTERN int TclpUtfNcmp2(const char *s1, const char *s2, unsigned long n); @@ -447,8 +452,11 @@ EXTERN void TclCleanupVar(Var *varPtr, Var *arrayPtr); EXTERN void TclVarErrMsg(Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); -/* Slot 178 is reserved */ -/* Slot 179 is reserved */ +/* 178 */ +EXTERN void Tcl_SetStartupScript(Tcl_Obj *pathPtr, + const char *encodingName); +/* 179 */ +EXTERN Tcl_Obj * Tcl_GetStartupScript(const char **encodingNamePtr); /* Slot 180 is reserved */ /* Slot 181 is reserved */ /* 182 */ @@ -557,7 +565,8 @@ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr, /* 235 */ EXTERN void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr); -/* Slot 236 is reserved */ +/* 236 */ +EXTERN void TclBackgroundException(Tcl_Interp *interp, int code); /* 237 */ EXTERN int TclResetCancellation(Tcl_Interp *interp, int force); /* 238 */ @@ -764,8 +773,8 @@ typedef struct TclIntStubs { void (*reserved155)(void); void (*tclRegError) (Tcl_Interp *interp, const char *msg, int status); /* 156 */ Var * (*tclVarTraceExists) (Tcl_Interp *interp, const char *varName); /* 157 */ - void (*reserved158)(void); - void (*reserved159)(void); + void (*tclSetStartupScriptFileName) (const char *filename); /* 158 */ + const char * (*tclGetStartupScriptFileName) (void); /* 159 */ void (*reserved160)(void); int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */ void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */ @@ -773,8 +782,8 @@ typedef struct TclIntStubs { void (*tclExpandCodeArray) (void *envPtr); /* 164 */ void (*tclpSetInitialEncodings) (void); /* 165 */ int (*tclListObjSetElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj *valuePtr); /* 166 */ - void (*reserved167)(void); - void (*reserved168)(void); + void (*tclSetStartupScriptPath) (Tcl_Obj *pathPtr); /* 167 */ + Tcl_Obj * (*tclGetStartupScriptPath) (void); /* 168 */ int (*tclpUtfNcmp2) (const char *s1, const char *s2, unsigned long n); /* 169 */ int (*tclCheckInterpTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 170 */ int (*tclCheckExecutionTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 171 */ @@ -784,8 +793,8 @@ typedef struct TclIntStubs { int (*tclCallVarTraces) (Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 175 */ void (*tclCleanupVar) (Var *varPtr, Var *arrayPtr); /* 176 */ void (*tclVarErrMsg) (Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); /* 177 */ - void (*reserved178)(void); - void (*reserved179)(void); + void (*tcl_SetStartupScript) (Tcl_Obj *pathPtr, const char *encodingName); /* 178 */ + Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingNamePtr); /* 179 */ void (*reserved180)(void); void (*reserved181)(void); struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */ @@ -842,7 +851,7 @@ typedef struct TclIntStubs { void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */ Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */ void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */ - void (*reserved236)(void); + void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */ int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */ int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */ int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */ @@ -1130,8 +1139,10 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclRegError) /* 156 */ #define TclVarTraceExists \ (tclIntStubsPtr->tclVarTraceExists) /* 157 */ -/* Slot 158 is reserved */ -/* Slot 159 is reserved */ +#define TclSetStartupScriptFileName \ + (tclIntStubsPtr->tclSetStartupScriptFileName) /* 158 */ +#define TclGetStartupScriptFileName \ + (tclIntStubsPtr->tclGetStartupScriptFileName) /* 159 */ /* Slot 160 is reserved */ #define TclChannelTransform \ (tclIntStubsPtr->tclChannelTransform) /* 161 */ @@ -1145,8 +1156,10 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclpSetInitialEncodings) /* 165 */ #define TclListObjSetElement \ (tclIntStubsPtr->tclListObjSetElement) /* 166 */ -/* Slot 167 is reserved */ -/* Slot 168 is reserved */ +#define TclSetStartupScriptPath \ + (tclIntStubsPtr->tclSetStartupScriptPath) /* 167 */ +#define TclGetStartupScriptPath \ + (tclIntStubsPtr->tclGetStartupScriptPath) /* 168 */ #define TclpUtfNcmp2 \ (tclIntStubsPtr->tclpUtfNcmp2) /* 169 */ #define TclCheckInterpTraces \ @@ -1164,8 +1177,10 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclCleanupVar) /* 176 */ #define TclVarErrMsg \ (tclIntStubsPtr->tclVarErrMsg) /* 177 */ -/* Slot 178 is reserved */ -/* Slot 179 is reserved */ +#define Tcl_SetStartupScript \ + (tclIntStubsPtr->tcl_SetStartupScript) /* 178 */ +#define Tcl_GetStartupScript \ + (tclIntStubsPtr->tcl_GetStartupScript) /* 179 */ /* Slot 180 is reserved */ /* Slot 181 is reserved */ #define TclpLocaltime \ @@ -1252,7 +1267,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclVarHashCreateVar) /* 234 */ #define TclInitVarHashTable \ (tclIntStubsPtr->tclInitVarHashTable) /* 235 */ -/* Slot 236 is reserved */ +#define TclBackgroundException \ + (tclIntStubsPtr->tclBackgroundException) /* 236 */ #define TclResetCancellation \ (tclIntStubsPtr->tclResetCancellation) /* 237 */ #define TclNRInterpProc \ @@ -1289,4 +1305,58 @@ extern const TclIntStubs *tclIntStubsPtr; #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT +#undef TclGetStartupScriptFileName +#undef TclSetStartupScriptFileName +#undef TclGetStartupScriptPath +#undef TclSetStartupScriptPath +#undef TclBackgroundException + +#if defined(USE_TCL_STUBS) && defined(TCL_NO_DEPRECATED) +# undef Tcl_SetStartupScript +# define Tcl_SetStartupScript \ + (tclStubsPtr->tcl_SetStartupScript) /* 622 */ +# undef Tcl_GetStartupScript +# define Tcl_GetStartupScript \ + (tclStubsPtr->tcl_GetStartupScript) /* 623 */ +# undef Tcl_CreateNamespace +# define Tcl_CreateNamespace \ + (tclStubsPtr->tcl_CreateNamespace) /* 506 */ +# undef Tcl_DeleteNamespace +# define Tcl_DeleteNamespace \ + (tclStubsPtr->tcl_DeleteNamespace) /* 507 */ +# undef Tcl_AppendExportList +# define Tcl_AppendExportList \ + (tclStubsPtr->tcl_AppendExportList) /* 508 */ +# undef Tcl_Export +# define Tcl_Export \ + (tclStubsPtr->tcl_Export) /* 509 */ +# undef Tcl_Import +# define Tcl_Import \ + (tclStubsPtr->tcl_Import) /* 510 */ +# undef Tcl_ForgetImport +# define Tcl_ForgetImport \ + (tclStubsPtr->tcl_ForgetImport) /* 511 */ +# undef Tcl_GetCurrentNamespace +# define Tcl_GetCurrentNamespace \ + (tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */ +# undef Tcl_GetGlobalNamespace +# define Tcl_GetGlobalNamespace \ + (tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */ +# undef Tcl_FindNamespace +# define Tcl_FindNamespace \ + (tclStubsPtr->tcl_FindNamespace) /* 514 */ +# undef Tcl_FindCommand +# define Tcl_FindCommand \ + (tclStubsPtr->tcl_FindCommand) /* 515 */ +# undef Tcl_GetCommandFromObj +# define Tcl_GetCommandFromObj \ + (tclStubsPtr->tcl_GetCommandFromObj) /* 516 */ +# undef Tcl_GetCommandFullName +# define Tcl_GetCommandFullName \ + (tclStubsPtr->tcl_GetCommandFullName) /* 517 */ +#endif + +#undef TclCopyChannelOld +#undef TclSockMinimumBuffersOld + #endif /* _TCLINTDECLS */ diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 0b0f652..1a4297b 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -179,6 +179,37 @@ typedef struct ScriptLimitCallbackKey { } ScriptLimitCallbackKey; /* + * TIP#143 limit handler internal representation. + */ + +struct LimitHandler { + int flags; /* The state of this particular handler. */ + Tcl_LimitHandlerProc *handlerProc; + /* The handler callback. */ + ClientData clientData; /* Opaque argument to the handler callback. */ + Tcl_LimitHandlerDeleteProc *deleteProc; + /* How to delete the clientData. */ + LimitHandler *prevPtr; /* Previous item in linked list of + * handlers. */ + LimitHandler *nextPtr; /* Next item in linked list of handlers. */ +}; + +/* + * Values for the LimitHandler flags field. + * LIMIT_HANDLER_ACTIVE - Whether the handler is currently being + * processed; handlers are never to be entered reentrantly. + * LIMIT_HANDLER_DELETED - Whether the handler has been deleted. This + * should not normally be observed because when a handler is + * deleted it is also spliced out of the list of handlers, but + * even so we will be careful. + */ + +#define LIMIT_HANDLER_ACTIVE 0x01 +#define LIMIT_HANDLER_DELETED 0x02 + + + +/* * Prototypes for local static functions: */ @@ -1798,9 +1829,9 @@ AliasNRCmd( */ if (isRootEnsemble) { - TclNRDeferCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL); + TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL); } - iPtr->evalFlags |= TCL_EVAL_REDIRECT; + TclSkipTailcall(interp); return Tcl_NREvalObj(interp, listPtr, flags); } diff --git a/generic/tclLink.c b/generic/tclLink.c index a3b42bd..2735256 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -112,8 +112,8 @@ Tcl_LinkVar( Link *linkPtr; int code; - linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, TCL_GLOBAL_ONLY, - LinkTraceProc, (ClientData) NULL); + linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL, + TCL_GLOBAL_ONLY, LinkTraceProc, (ClientData) NULL); if (linkPtr != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "variable '%s' is already linked", varName)); @@ -138,8 +138,9 @@ Tcl_LinkVar( ckfree(linkPtr); return TCL_ERROR; } - code = Tcl_TraceVar(interp, varName, TCL_GLOBAL_ONLY|TCL_TRACE_READS - |TCL_TRACE_WRITES|TCL_TRACE_UNSETS, LinkTraceProc, linkPtr); + code = Tcl_TraceVar2(interp, varName, NULL, + TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + LinkTraceProc, linkPtr); if (code != TCL_OK) { Tcl_DecrRefCount(linkPtr->varName); ckfree(linkPtr); @@ -170,13 +171,13 @@ Tcl_UnlinkVar( Tcl_Interp *interp, /* Interpreter containing variable to unlink */ const char *varName) /* Global variable in interp to unlink. */ { - Link *linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, + Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL, TCL_GLOBAL_ONLY, LinkTraceProc, NULL); if (linkPtr == NULL) { return; } - Tcl_UntraceVar(interp, varName, + Tcl_UntraceVar2(interp, varName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, LinkTraceProc, linkPtr); Tcl_DecrRefCount(linkPtr->varName); @@ -207,7 +208,7 @@ Tcl_UpdateLinkedVar( Tcl_Interp *interp, /* Interpreter containing variable. */ const char *varName) /* Name of global variable that is linked. */ { - Link *linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, + Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL, TCL_GLOBAL_ONLY, LinkTraceProc, NULL); int savedFlag; @@ -221,8 +222,8 @@ Tcl_UpdateLinkedVar( /* * Callback may have unlinked the variable. [Bug 1740631] */ - linkPtr = (Link *) Tcl_VarTraceInfo(interp, varName, TCL_GLOBAL_ONLY, - LinkTraceProc, NULL); + linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL, + TCL_GLOBAL_ONLY, LinkTraceProc, NULL); if (linkPtr != NULL) { linkPtr->flags = (linkPtr->flags & ~LINK_BEING_UPDATED) | savedFlag; } @@ -278,7 +279,7 @@ LinkTraceProc( } else if (flags & TCL_TRACE_DESTROYED) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, Tcl_GetString(linkPtr->varName), + Tcl_TraceVar2(interp, Tcl_GetString(linkPtr->varName), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES |TCL_TRACE_UNSETS, LinkTraceProc, linkPtr); } diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 2d1defa..bd2dbc4 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -237,7 +237,7 @@ Tcl_NewListObj( * Now create the object. */ - Tcl_InvalidateStringRep(listPtr); + TclInvalidateStringRep(listPtr); ListSetIntRep(listPtr, listRepPtr); return listPtr; } @@ -302,7 +302,7 @@ Tcl_DbNewListObj( * Now create the object. */ - Tcl_InvalidateStringRep(listPtr); + TclInvalidateStringRep(listPtr); ListSetIntRep(listPtr, listRepPtr); return listPtr; @@ -362,7 +362,7 @@ Tcl_SetListObj( */ TclFreeIntRep(objPtr); - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); /* * Set the object's type to "list" and initialize the internal rep. @@ -697,7 +697,7 @@ Tcl_ListObjAppendElement( * representation has changed. */ - Tcl_InvalidateStringRep(listPtr); + TclInvalidateStringRep(listPtr); return TCL_OK; } @@ -1057,7 +1057,7 @@ Tcl_ListObjReplace( * reflects the list's internal representation. */ - Tcl_InvalidateStringRep(listPtr); + TclInvalidateStringRep(listPtr); return TCL_OK; } @@ -1523,7 +1523,7 @@ TclLsetFlat( * containing lists. */ - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); } /* @@ -1559,7 +1559,7 @@ TclLsetFlat( } else { TclListObjSetElement(NULL, subListPtr, index, valuePtr); } - Tcl_InvalidateStringRep(subListPtr); + TclInvalidateStringRep(subListPtr); Tcl_IncrRefCount(retValuePtr); return retValuePtr; } @@ -1736,8 +1736,6 @@ FreeListInternalRep( ckfree(listRepPtr); } - listPtr->internalRep.twoPtrValue.ptr1 = NULL; - listPtr->internalRep.twoPtrValue.ptr2 = NULL; listPtr->typePtr = NULL; } diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index 441ea91..11da6f8 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -32,6 +32,10 @@ static int AddLocalLiteralEntry(CompileEnv *envPtr, Tcl_Obj *objPtr, int localHash); static void ExpandLocalLiteralArray(CompileEnv *envPtr); static unsigned HashString(const char *string, int length); +#ifdef TCL_COMPILE_DEBUG +static LiteralEntry * LookupLiteralEntry(Tcl_Interp *interp, + Tcl_Obj *objPtr); +#endif static void RebuildLiteralTable(LiteralTable *tablePtr); /* @@ -239,7 +243,7 @@ TclCreateLiteral( } #ifdef TCL_COMPILE_DEBUG - if (TclLookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) { + if (LookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) { Tcl_Panic("%s: literal \"%.*s\" found globally but shouldn't be", "TclRegisterLiteral", (length>60? 60 : length), bytes); } @@ -301,6 +305,33 @@ TclCreateLiteral( /* *---------------------------------------------------------------------- * + * TclFetchLiteral -- + * + * Fetch from a CompileEnv the literal value identified by an index + * value, as returned by a prior call to TclRegisterLiteral(). + * + * Results: + * The literal value, or NULL if the index is out of range. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclFetchLiteral( + CompileEnv *envPtr, /* Points to the CompileEnv from which to + * fetch the registered literal value. */ + unsigned int index) /* Index of the desired literal, as returned + * by prior call to TclRegisterLiteral() */ +{ + if (index >= (unsigned int) envPtr->literalArrayNext) { + return NULL; + } + return envPtr->literalArrayPtr[index].objPtr; +} + +/* + *---------------------------------------------------------------------- + * * TclRegisterLiteral -- * * Find, or if necessary create, an object in a CompileEnv literal array @@ -414,10 +445,11 @@ TclRegisterLiteral( return objIndex; } +#ifdef TCL_COMPILE_DEBUG /* *---------------------------------------------------------------------- * - * TclLookupLiteralEntry -- + * LookupLiteralEntry -- * * Finds the LiteralEntry that corresponds to a literal Tcl object * holding a literal. @@ -431,8 +463,8 @@ TclRegisterLiteral( *---------------------------------------------------------------------- */ -LiteralEntry * -TclLookupLiteralEntry( +static LiteralEntry * +LookupLiteralEntry( Tcl_Interp *interp, /* Interpreter for which objPtr was created to * hold a literal. */ register Tcl_Obj *objPtr) /* Points to a Tcl object holding a literal @@ -456,6 +488,7 @@ TclLookupLiteralEntry( return NULL; } +#endif /* *---------------------------------------------------------------------- * @@ -750,11 +783,16 @@ TclReleaseLiteral( * TclRegisterLiteral. */ { Interp *iPtr = (Interp *) interp; - LiteralTable *globalTablePtr = &iPtr->literalTable; + LiteralTable *globalTablePtr; register LiteralEntry *entryPtr, *prevPtr; const char *bytes; int length, index; + if (iPtr == NULL) { + goto done; + } + + globalTablePtr = &iPtr->literalTable; bytes = TclGetStringFromObj(objPtr, &length); index = (HashString(bytes, length) & globalTablePtr->mask); @@ -798,6 +836,7 @@ TclReleaseLiteral( * Remove the reference corresponding to the local literal table entry. */ + done: Tcl_DecrRefCount(objPtr); } @@ -971,8 +1010,13 @@ TclInvalidateCmdLiteral( Tcl_Obj *literalObjPtr = TclCreateLiteral(iPtr, (char *) name, strlen(name), -1, NULL, nsPtr, 0, NULL); - if (literalObjPtr != NULL && literalObjPtr->typePtr == &tclCmdNameType) { - TclFreeIntRep(literalObjPtr); + if (literalObjPtr != NULL) { + if (literalObjPtr->typePtr == &tclCmdNameType) { + TclFreeIntRep(literalObjPtr); + } + /* Balance the refcount effects of TclCreateLiteral() above */ + Tcl_IncrRefCount(literalObjPtr); + TclReleaseLiteral(interp, literalObjPtr); } } @@ -1090,7 +1134,7 @@ TclVerifyLocalLiteralTable( "TclVerifyLocalLiteralTable", (length>60? 60 : length), bytes, localPtr->refCount); } - if (TclLookupLiteralEntry((Tcl_Interp *) envPtr->iPtr, + if (LookupLiteralEntry((Tcl_Interp *) envPtr->iPtr, localPtr->objPtr) == NULL) { bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length); Tcl_Panic("%s: local literal \"%.*s\" is not global", diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c index f030d89..c22c4c4 100644 --- a/generic/tclLoadNone.c +++ b/generic/tclLoadNone.c @@ -82,6 +82,39 @@ TclGuessPackageName( } /* + * These functions are fallbacks if we somehow determine that the platform can + * do loading from memory but the user wishes to disable it. They just report + * (gracefully) that they fail. + */ + +#ifdef TCL_LOAD_FROM_MEMORY + +MODULE_SCOPE void * +TclpLoadMemoryGetBuffer( + Tcl_Interp *interp, /* Dummy: unused by this implementation */ + int size) /* Dummy: unused by this implementation */ +{ + return NULL; +} + +MODULE_SCOPE int +TclpLoadMemory( + Tcl_Interp *interp, /* Used for error reporting. */ + void *buffer, /* Dummy: unused by this implementation */ + int size, /* Dummy: unused by this implementation */ + int codeSize, /* Dummy: unused by this implementation */ + Tcl_LoadHandle *loadHandle, /* Dummy: unused by this implementation */ + Tcl_FSUnloadFileProc **unloadProcPtr) + /* Dummy: unused by this implementation */ +{ + Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory " + "is not available on this system", -1)); + return TCL_ERROR; +} + +#endif /* TCL_LOAD_FROM_MEMORY */ + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 8da4b42..aed623a 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -423,7 +423,7 @@ Tcl_PopCallFrame( framePtr->nsPtr = NULL; if (framePtr->tailcallPtr) { - TclSpliceTailcall(interp, framePtr->tailcallPtr); + TclSetTailcall(interp, framePtr->tailcallPtr); } } @@ -505,9 +505,9 @@ EstablishErrorCodeTraces( const char *name2, int flags) { - Tcl_TraceVar(interp, "errorCode", TCL_GLOBAL_ONLY | TCL_TRACE_READS, + Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS, ErrorCodeRead, NULL); - Tcl_TraceVar(interp, "errorCode", TCL_GLOBAL_ONLY | TCL_TRACE_UNSETS, + Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS, EstablishErrorCodeTraces, NULL); return NULL; } @@ -579,9 +579,9 @@ EstablishErrorInfoTraces( const char *name2, int flags) { - Tcl_TraceVar(interp, "errorInfo", TCL_GLOBAL_ONLY | TCL_TRACE_READS, + Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS, ErrorInfoRead, NULL); - Tcl_TraceVar(interp, "errorInfo", TCL_GLOBAL_ONLY | TCL_TRACE_UNSETS, + Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS, EstablishErrorInfoTraces, NULL); return NULL; } @@ -697,8 +697,7 @@ Tcl_CreateNamespace( * Find the parent for the new namespace. */ - TclGetNamespaceForQualName(interp, name, NULL, - /*flags*/ (TCL_CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG), + TclGetNamespaceForQualName(interp, name, NULL, TCL_CREATE_NS_IF_UNKNOWN, &parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName); /* @@ -1330,8 +1329,7 @@ Tcl_Export( * Check that the pattern doesn't have namespace qualifiers. */ - TclGetNamespaceForQualName(interp, pattern, nsPtr, - /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), + TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY, &exportNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) { @@ -1545,8 +1543,7 @@ Tcl_Import( Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL); return TCL_ERROR; } - TclGetNamespaceForQualName(interp, pattern, nsPtr, - /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), + TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY, &importNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (importNsPtr == NULL) { @@ -1791,8 +1788,7 @@ Tcl_ForgetImport( * simple pattern. */ - TclGetNamespaceForQualName(interp, pattern, nsPtr, - /*flags*/ (TCL_LEAVE_ERR_MSG | TCL_NAMESPACE_ONLY), + TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY, &sourceNsPtr, &dummyPtr, &dummyPtr, &simplePattern); if (sourceNsPtr == NULL) { @@ -1945,7 +1941,7 @@ InvokeImportedNRCmd( ImportedCmdData *dataPtr = clientData; Command *realCmdPtr = dataPtr->realCmdPtr; - ((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT; + TclSkipTailcall(interp); return Tcl_NRCmdSwap(interp, (Tcl_Command) realCmdPtr, objc, objv, 0); } @@ -3435,10 +3431,7 @@ NamespaceExportCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp); - const char *pattern, *string; - int resetListFirst = 0; - int firstArg, patternCt, i, result; + int firstArg, i; if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?-clear? ?pattern pattern...?"); @@ -3446,42 +3439,27 @@ NamespaceExportCmd( } /* - * Process the optional "-clear" argument. + * If no pattern arguments are given, and "-clear" isn't specified, return + * the namespace's current export pattern list. */ - firstArg = 1; - if (firstArg < objc) { - string = TclGetString(objv[firstArg]); - if (strcmp(string, "-clear") == 0) { - resetListFirst = 1; - firstArg++; - } + if (objc == 1) { + Tcl_Obj *listPtr = Tcl_NewObj(); + + (void) Tcl_AppendExportList(interp, NULL, listPtr); + Tcl_SetObjResult(interp, listPtr); + return TCL_OK; } /* - * If no pattern arguments are given, and "-clear" isn't specified, return - * the namespace's current export pattern list. + * Process the optional "-clear" argument. */ - patternCt = objc - firstArg; - if (patternCt == 0) { - if (firstArg > 1) { - return TCL_OK; - } else { - /* - * Create list with export patterns. - */ - - Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL); - - result = Tcl_AppendExportList(interp, (Tcl_Namespace *) currNsPtr, - listPtr); - if (result != TCL_OK) { - return result; - } - Tcl_SetObjResult(interp, listPtr); - return TCL_OK; - } + firstArg = 1; + if (strcmp("-clear", Tcl_GetString(objv[firstArg])) == 0) { + Tcl_Export(interp, NULL, "::", 1); + Tcl_ResetResult(interp); + firstArg++; } /* @@ -3489,9 +3467,7 @@ NamespaceExportCmd( */ for (i = firstArg; i < objc; i++) { - pattern = TclGetString(objv[i]); - result = Tcl_Export(interp, (Tcl_Namespace *) currNsPtr, pattern, - ((i == firstArg)? resetListFirst : 0)); + int result = Tcl_Export(interp, NULL, Tcl_GetString(objv[i]), 0); if (result != TCL_OK) { return result; } diff --git a/generic/tclOO.c b/generic/tclOO.c index d6d2d6a..cb22de6 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -843,7 +843,7 @@ ObjectRenamedTrace( result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, 0, NULL); if (result != TCL_OK) { - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, result); } Tcl_RestoreInterpState(interp, state); TclOODeleteContext(contextPtr); diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 0676618..f8cd1a4 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -687,52 +687,51 @@ TclOO_Object_VarName( int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { - Interp *iPtr = (Interp *) interp; Var *varPtr, *aryVar; - Tcl_Obj *varNamePtr; + Tcl_Obj *varNamePtr, *argPtr; + const char *arg; if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, "varName"); return TCL_ERROR; } + argPtr = objv[objc-1]; + arg = Tcl_GetString(argPtr); /* - * Switch to the object's namespace for the duration of this call. Like - * this, the variable is looked up in the namespace of the object, and not - * in the namespace of the caller. Otherwise this would only work if the - * caller was a method of the object itself, which might not be true if - * the method was exported. This is a bit of a hack, but the simplest way - * to do this (pushing a stack frame would be horribly expensive by - * comparison, and is only done when we'd otherwise interfere with the - * global namespace). + * Convert the variable name to fully-qualified form if it wasn't already. + * This has to be done prior to lookup because we can run into problems + * with resolvers otherwise. [Bug 3603695] + * + * We still need to do the lookup; the variable could be linked to another + * variable and we want the target's name. */ - if (iPtr->varFramePtr == NULL) { - Tcl_CallFrame *dummyFrame; - - TclPushStackFrame(interp, &dummyFrame, - Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)),0); - varPtr = TclObjLookupVar(interp, objv[objc-1], NULL, - TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to",1,1,&aryVar); - TclPopStackFrame(interp); + if (arg[0] == ':' && arg[1] == ':') { + varNamePtr = argPtr; } else { - Namespace *savedNsPtr; - - savedNsPtr = iPtr->varFramePtr->nsPtr; - iPtr->varFramePtr->nsPtr = (Namespace *) + Tcl_Namespace *namespacePtr = Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)); - varPtr = TclObjLookupVar(interp, objv[objc-1], NULL, - TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to",1,1,&aryVar); - iPtr->varFramePtr->nsPtr = savedNsPtr; - } + varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1); + Tcl_AppendToObj(varNamePtr, "::", 2); + Tcl_AppendObjToObj(varNamePtr, argPtr); + } + Tcl_IncrRefCount(varNamePtr); + varPtr = TclObjLookupVar(interp, varNamePtr, NULL, + TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, &aryVar); + Tcl_DecrRefCount(varNamePtr); if (varPtr == NULL) { - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", - TclGetString(objv[objc-1]), NULL); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", arg, NULL); return TCL_ERROR; } + /* + * Now that we've pinned down what variable we're really talking about + * (including traversing variable links), convert back to a name. + */ + varNamePtr = Tcl_NewObj(); if (aryVar != NULL) { Tcl_HashEntry *hPtr; diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index a79e4fa..26fd09f 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -178,7 +178,7 @@ StashCallChain( callPtr->refCount++; TclFreeIntRep(objPtr); objPtr->typePtr = &methodNameType; - objPtr->internalRep.otherValuePtr = callPtr; + objPtr->internalRep.twoPtrValue.ptr1 = callPtr; } void @@ -205,10 +205,10 @@ DupMethodNameRep( Tcl_Obj *srcPtr, Tcl_Obj *dstPtr) { - register CallChain *callPtr = srcPtr->internalRep.otherValuePtr; + register CallChain *callPtr = srcPtr->internalRep.twoPtrValue.ptr1; dstPtr->typePtr = &methodNameType; - dstPtr->internalRep.otherValuePtr = callPtr; + dstPtr->internalRep.twoPtrValue.ptr1 = callPtr; callPtr->refCount++; } @@ -216,10 +216,9 @@ static void FreeMethodNameRep( Tcl_Obj *objPtr) { - register CallChain *callPtr = objPtr->internalRep.otherValuePtr; + register CallChain *callPtr = objPtr->internalRep.twoPtrValue.ptr1; TclOODeleteChain(callPtr); - objPtr->internalRep.otherValuePtr = NULL; objPtr->typePtr = NULL; } @@ -952,7 +951,7 @@ TclOOGetCallContext( const int reuseMask = ((flags & PUBLIC_METHOD) ? ~0 : ~PUBLIC_METHOD); if (cacheInThisObj->typePtr == &methodNameType) { - callPtr = cacheInThisObj->internalRep.otherValuePtr; + callPtr = cacheInThisObj->internalRep.twoPtrValue.ptr1; if (IsStillValid(callPtr, oPtr, flags, reuseMask)) { callPtr->refCount++; goto returnContext; diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index 28820e0..98b4078 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -860,7 +860,7 @@ PushMethodCallFrame( if (pmPtr->procPtr->bodyPtr->typePtr == &tclByteCodeType) { ByteCode *codePtr = - pmPtr->procPtr->bodyPtr->internalRep.otherValuePtr; + pmPtr->procPtr->bodyPtr->internalRep.twoPtrValue.ptr1; codePtr->nsPtr = nsPtr; } diff --git a/generic/tclObj.c b/generic/tclObj.c index 74cb29e..1bed667 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -208,7 +208,6 @@ static Tcl_ThreadDataKey pendingObjDataKey; */ static int ParseBoolean(Tcl_Obj *objPtr); -static int SetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int SetDoubleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static int SetIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfDouble(Tcl_Obj *objPtr); @@ -250,14 +249,14 @@ static const Tcl_ObjType oldBooleanType = { NULL, /* freeIntRepProc */ NULL, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetBooleanFromAny /* setFromAnyProc */ + TclSetBooleanFromAny /* setFromAnyProc */ }; const Tcl_ObjType tclBooleanType = { "booleanString", /* name */ NULL, /* freeIntRepProc */ NULL, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetBooleanFromAny /* setFromAnyProc */ + TclSetBooleanFromAny /* setFromAnyProc */ }; const Tcl_ObjType tclDoubleType = { "double", /* name */ @@ -1006,7 +1005,12 @@ Tcl_ConvertToType( */ if (typePtr->setFromAnyProc == NULL) { - Tcl_Panic("may not convert object to type %s", typePtr->name); + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't convert value to type %s", typePtr->name)); + Tcl_SetErrorCode(interp, "TCL", "API_ABUSE", NULL); + } + return TCL_ERROR; } return typePtr->setFromAnyProc(interp, objPtr); @@ -1255,7 +1259,7 @@ Tcl_DbNewObj( * Side effects: * tclFreeObjList, the head of the list of free Tcl_Objs, is set to the * first of a number of free Tcl_Obj's linked together by their - * internalRep.otherValuePtrs. + * internalRep.twoPtrValue.ptr1's. * *---------------------------------------------------------------------- */ @@ -1284,7 +1288,7 @@ TclAllocateFreeObjects(void) prevPtr = NULL; objPtr = (Tcl_Obj *) basePtr; for (i = 0; i < OBJS_TO_ALLOC_EACH_TIME; i++) { - objPtr->internalRep.otherValuePtr = prevPtr; + objPtr->internalRep.twoPtrValue.ptr1 = prevPtr; prevPtr = objPtr; objPtr++; } @@ -1329,9 +1333,21 @@ TclFreeObj( ObjInitDeletionContext(context); + /* + * Check for a double free of the same value. This is slightly tricky + * because it is customary to free a Tcl_Obj when its refcount falls + * either from 1 to 0, or from 0 to -1. Falling from -1 to -2, though, + * and so on, is always a sign of a botch in the caller. + */ if (objPtr->refCount < -1) { Tcl_Panic("Reference count for %p was negative", objPtr); } + /* + * Now, in case we just approved drop from 1 to 0 as acceptable, make + * sure we do not accept a second free when falling from 0 to -1. + * Skip that possibility so any double free will trigger the panic. + */ + objPtr->refCount = -1; /* * Invalidate the string rep first so we can use the bytes value for our @@ -1729,8 +1745,8 @@ Tcl_InvalidateStringRep( *---------------------------------------------------------------------- */ -#ifdef TCL_MEM_DEBUG #undef Tcl_NewBooleanObj +#ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_NewBooleanObj( @@ -1778,6 +1794,7 @@ Tcl_NewBooleanObj( *---------------------------------------------------------------------- */ +#undef Tcl_DbNewBooleanObj #ifdef TCL_MEM_DEBUG Tcl_Obj * @@ -1830,6 +1847,7 @@ Tcl_DbNewBooleanObj( *---------------------------------------------------------------------- */ +#undef Tcl_SetBooleanObj void Tcl_SetBooleanObj( register Tcl_Obj *objPtr, /* Object whose internal rep to init. */ @@ -1911,7 +1929,7 @@ Tcl_GetBooleanFromObj( /* *---------------------------------------------------------------------- * - * SetBooleanFromAny -- + * TclSetBooleanFromAny -- * * Attempt to generate a boolean internal form for the Tcl object * "objPtr". @@ -1928,8 +1946,8 @@ Tcl_GetBooleanFromObj( *---------------------------------------------------------------------- */ -static int -SetBooleanFromAny( +int +TclSetBooleanFromAny( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ register Tcl_Obj *objPtr) /* The object to convert. */ { @@ -2389,8 +2407,8 @@ UpdateStringOfDouble( *---------------------------------------------------------------------- */ -#ifdef TCL_MEM_DEBUG #undef Tcl_NewIntObj +#ifdef TCL_MEM_DEBUG Tcl_Obj * Tcl_NewIntObj( @@ -2430,6 +2448,7 @@ Tcl_NewIntObj( *---------------------------------------------------------------------- */ +#undef Tcl_SetIntObj void Tcl_SetIntObj( register Tcl_Obj *objPtr, /* Object whose internal rep to init. */ @@ -4171,7 +4190,7 @@ Tcl_GetCommandFromObj( * had is invalid one way or another. */ - if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) { + if (SetCmdNameFromAny(interp, objPtr) != TCL_OK) { return NULL; } resPtr = objPtr->internalRep.twoPtrValue.ptr1; @@ -4390,7 +4409,7 @@ SetCmdNameFromAny( if (cmdPtr) { cmdPtr->refCount++; - resPtr = objPtr->internalRep.otherValuePtr; + resPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((objPtr->typePtr == &tclCmdNameType) && resPtr && (resPtr->refCount == 1)) { /* diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 2b9ff87..b7f3dcf 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -109,9 +109,9 @@ typedef struct FsPath { * fields. */ -#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.otherValuePtr) +#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.twoPtrValue.ptr1) #define SETPATHOBJ(pathPtr,fsPathPtr) \ - ((pathPtr)->internalRep.otherValuePtr = (void *) (fsPathPtr)) + ((pathPtr)->internalRep.twoPtrValue.ptr1 = (void *) (fsPathPtr)) #define PATHFLAGS(pathPtr) (PATHOBJ(pathPtr)->flags) /* @@ -1156,7 +1156,7 @@ Tcl_FSConvertToPathType( FreeFsPathInternalRep(pathPtr); } - return Tcl_ConvertToType(interp, pathPtr, &tclFsPathType); + return SetFsPathFromAny(interp, pathPtr); /* * We used to have more complex code here: @@ -1873,7 +1873,7 @@ Tcl_FSGetNormalizedPath( UpdateStringOfFsPath(pathPtr); } FreeFsPathInternalRep(pathPtr); - if (Tcl_ConvertToType(interp, pathPtr, &tclFsPathType) != TCL_OK) { + if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) { return NULL; } fsPathPtr = PATHOBJ(pathPtr); diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 5b09ddb..07f62a4 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -106,6 +106,7 @@ static const char * PkgRequireCore(Tcl_Interp *interp, const char *name, *---------------------------------------------------------------------- */ +#undef Tcl_PkgProvide int Tcl_PkgProvide( Tcl_Interp *interp, /* Interpreter in which package is now @@ -188,6 +189,7 @@ Tcl_PkgProvideEx( *---------------------------------------------------------------------- */ +#undef Tcl_PkgRequire const char * Tcl_PkgRequire( Tcl_Interp *interp, /* Interpreter in which package is now @@ -670,6 +672,7 @@ PkgRequireCore( *---------------------------------------------------------------------- */ +#undef Tcl_PkgPresent const char * Tcl_PkgPresent( Tcl_Interp *interp, /* Interpreter in which package is now diff --git a/generic/tclPort.h b/generic/tclPort.h index 7021b8d..12a60db 100644 --- a/generic/tclPort.h +++ b/generic/tclPort.h @@ -19,11 +19,10 @@ #endif #if defined(_WIN32) # include "tclWinPort.h" -#endif -#include "tcl.h" -#if !defined(_WIN32) +#else # include "tclUnixPort.h" #endif +#include "tcl.h" #if !defined(LLONG_MIN) # ifdef TCL_WIDE_INT_IS_LONG diff --git a/generic/tclProc.c b/generic/tclProc.c index 933e7d2..13f6f8a 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -421,7 +421,7 @@ TclCreateProc( * will be holding a reference to it. */ - procPtr = bodyPtr->internalRep.otherValuePtr; + procPtr = bodyPtr->internalRep.twoPtrValue.ptr1; procPtr->iPtr = iPtr; procPtr->refCount++; precompiled = 1; @@ -1197,7 +1197,7 @@ TclInitCompiledLocals( if (bodyPtr->typePtr != &tclByteCodeType) { Tcl_Panic("body object for proc attached to frame is not a byte code type"); } - codePtr = bodyPtr->internalRep.otherValuePtr; + codePtr = bodyPtr->internalRep.twoPtrValue.ptr1; if (framePtr->numCompiledLocals) { if (!codePtr->localCachePtr) { @@ -1347,17 +1347,9 @@ TclFreeLocalCache( for (i = 0; i < localCachePtr->numVars; i++, namePtrPtr++) { register Tcl_Obj *objPtr = *namePtrPtr; - /* - * Note that this can be called with interp==NULL, on interp deletion. - * In that case, the literal table and objects go away on their own. - */ - if (objPtr) { - if (interp) { - TclReleaseLiteral(interp, objPtr); - } else { - Tcl_DecrRefCount(objPtr); - } + /* TclReleaseLiteral calls Tcl_DecrRefCount for us */ + TclReleaseLiteral(interp, objPtr); } } ckfree(localCachePtr); @@ -1368,7 +1360,7 @@ InitLocalCache( Proc *procPtr) { Interp *iPtr = procPtr->iPtr; - ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr; + ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1; int localCt = procPtr->numCompiledLocals; int numArgs = procPtr->numArgs, i = 0; @@ -1445,7 +1437,7 @@ InitArgsAndLocals( { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; register Proc *procPtr = framePtr->procPtr; - ByteCode *codePtr = procPtr->bodyPtr->internalRep.otherValuePtr; + ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1; register Var *varPtr, *defPtr; int localCt = procPtr->numCompiledLocals, numArgs, argCt, i, imax; Tcl_Obj *const *argObjs; @@ -1632,7 +1624,7 @@ PushProcCallFrame( * commands and/or resolver changes are considered). */ - codePtr = procPtr->bodyPtr->internalRep.otherValuePtr; + codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1; if (((Interp *) *codePtr->interpHandle != iPtr) || (codePtr->compileEpoch != iPtr->compileEpoch) || (codePtr->nsPtr != nsPtr) @@ -1833,7 +1825,7 @@ TclNRInterpProcCore( */ procPtr->refCount++; - codePtr = procPtr->bodyPtr->internalRep.otherValuePtr; + codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1; TclNRAddCallback(interp, InterpProcNR2, procNameObj, errorProc, NULL, NULL); @@ -1975,7 +1967,7 @@ TclProcCompileProc( { Interp *iPtr = (Interp *) interp; Tcl_CallFrame *framePtr; - ByteCode *codePtr = bodyPtr->internalRep.otherValuePtr; + ByteCode *codePtr = bodyPtr->internalRep.twoPtrValue.ptr1; /* * If necessary, compile the procedure's body. The compiler will allocate @@ -2095,7 +2087,7 @@ TclProcCompileProc( iPtr->invokeWord = 0; iPtr->invokeCmdFramePtr = (hePtr ? Tcl_GetHashValue(hePtr) : NULL); - tclByteCodeType.setFromAnyProc(interp, bodyPtr); + TclSetByteCodeFromAny(interp, bodyPtr, NULL, NULL); iPtr->invokeCmdFramePtr = NULL; TclPopStackFrame(interp); } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) { @@ -2365,7 +2357,7 @@ TclNewProcBodyObj( TclNewObj(objPtr); if (objPtr) { objPtr->typePtr = &tclProcBodyType; - objPtr->internalRep.otherValuePtr = procPtr; + objPtr->internalRep.twoPtrValue.ptr1 = procPtr; procPtr->refCount++; } @@ -2395,10 +2387,10 @@ ProcBodyDup( Tcl_Obj *srcPtr, /* Object to copy. */ Tcl_Obj *dupPtr) /* Target object for the duplication. */ { - Proc *procPtr = srcPtr->internalRep.otherValuePtr; + Proc *procPtr = srcPtr->internalRep.twoPtrValue.ptr1; dupPtr->typePtr = &tclProcBodyType; - dupPtr->internalRep.otherValuePtr = procPtr; + dupPtr->internalRep.twoPtrValue.ptr1 = procPtr; procPtr->refCount++; } @@ -2425,10 +2417,9 @@ static void ProcBodyFree( Tcl_Obj *objPtr) /* The object to clean up. */ { - Proc *procPtr = objPtr->internalRep.otherValuePtr; + Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1; - procPtr->refCount--; - if (procPtr->refCount <= 0) { + if (procPtr->refCount-- < 2) { TclProcCleanupProc(procPtr); } } @@ -2721,7 +2712,6 @@ TclNRApplyObjCmd( else { /* * Joe English's suggestion to allow cmdNames to function as lambdas. - * Also requires making tclCmdNameType non-static in tclObj.c */ Tcl_Obj *elemPtr; @@ -2961,10 +2951,9 @@ Tcl_DisassembleObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "script"); return TCL_ERROR; } - if (objv[2]->typePtr != &tclByteCodeType) { - if (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK){ - return TCL_ERROR; - } + if ((objv[2]->typePtr != &tclByteCodeType) + && (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) { + return TCL_ERROR; } codeObjPtr = objv[2]; break; @@ -3061,7 +3050,7 @@ Tcl_DisassembleObjCmd( * Do the actual disassembly. */ - if (((ByteCode *) codeObjPtr->internalRep.otherValuePtr)->flags + if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags & TCL_BYTECODE_PRECOMPILED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not disassemble prebuilt bytecode", -1)); diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c index 6c1dc08..6348e4a 100644 --- a/generic/tclRegexp.c +++ b/generic/tclRegexp.c @@ -578,7 +578,7 @@ Tcl_GetRegExpFromObj( * TclRegexp* when the type is tclRegexpType. */ - regexpPtr = objPtr->internalRep.otherValuePtr; + regexpPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((objPtr->typePtr != &tclRegexpType) || (regexpPtr->flags != flags)) { pattern = TclGetStringFromObj(objPtr, &length); @@ -601,7 +601,7 @@ Tcl_GetRegExpFromObj( */ TclFreeIntRep(objPtr); - objPtr->internalRep.otherValuePtr = regexpPtr; + objPtr->internalRep.twoPtrValue.ptr1 = regexpPtr; objPtr->typePtr = &tclRegexpType; } return (Tcl_RegExp) regexpPtr; @@ -749,7 +749,7 @@ static void FreeRegexpInternalRep( Tcl_Obj *objPtr) /* Regexp object with internal rep to free. */ { - TclRegexp *regexpRepPtr = objPtr->internalRep.otherValuePtr; + TclRegexp *regexpRepPtr = objPtr->internalRep.twoPtrValue.ptr1; /* * If this is the last reference to the regexp, free it. @@ -783,10 +783,10 @@ DupRegexpInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *copyPtr) /* Object with internal rep to set. */ { - TclRegexp *regexpPtr = srcPtr->internalRep.otherValuePtr; + TclRegexp *regexpPtr = srcPtr->internalRep.twoPtrValue.ptr1; regexpPtr->refCount++; - copyPtr->internalRep.otherValuePtr = srcPtr->internalRep.otherValuePtr; + copyPtr->internalRep.twoPtrValue.ptr1 = srcPtr->internalRep.twoPtrValue.ptr1; copyPtr->typePtr = &tclRegexpType; } diff --git a/generic/tclResult.c b/generic/tclResult.c index 9707f20..014ea1b 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -230,6 +230,7 @@ Tcl_DiscardInterpState( *---------------------------------------------------------------------- */ +#undef Tcl_SaveResult void Tcl_SaveResult( Tcl_Interp *interp, /* Interpreter to save. */ @@ -304,6 +305,7 @@ Tcl_SaveResult( *---------------------------------------------------------------------- */ +#undef Tcl_RestoreResult void Tcl_RestoreResult( Tcl_Interp *interp, /* Interpreter being restored. */ @@ -372,6 +374,7 @@ Tcl_RestoreResult( *---------------------------------------------------------------------- */ +#undef Tcl_DiscardResult void Tcl_DiscardResult( Tcl_SavedResult *statePtr) /* State returned by Tcl_SaveResult. */ @@ -1587,7 +1590,7 @@ Tcl_GetReturnOptions( } if (result == TCL_ERROR) { - Tcl_AddObjErrorInfo(interp, "", -1); + Tcl_AddErrorInfo(interp, ""); Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack); } if (iPtr->errorCode) { diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 04cf4ee..e495c2e 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -140,9 +140,9 @@ typedef struct String { #define stringAttemptRealloc(ptr, numChars) \ (String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars) ) #define GET_STRING(objPtr) \ - ((String *) (objPtr)->internalRep.otherValuePtr) + ((String *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_STRING(objPtr, stringPtr) \ - ((objPtr)->internalRep.otherValuePtr = (void *) (stringPtr)) + ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr)) /* * TCL STRING GROWTH ALGORITHM diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 88ada19..8bf4f9d 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -41,6 +41,8 @@ #undef Tcl_FindExecutable #undef TclpGetPid #undef TclSockMinimumBuffers +#define TclBackgroundException Tcl_BackgroundException +#undef Tcl_SetIntObj /* See bug 510001: TclSockMinimumBuffers needs plat imp */ #ifdef _WIN64 @@ -53,6 +55,31 @@ static int TclSockMinimumBuffersOld(int sock, int size) } #endif +#define TclSetStartupScriptPath setStartupScriptPath +static void TclSetStartupScriptPath(Tcl_Obj *path) +{ + Tcl_SetStartupScript(path, NULL); +} +#define TclGetStartupScriptPath getStartupScriptPath +static Tcl_Obj *TclGetStartupScriptPath(void) +{ + return Tcl_GetStartupScript(NULL); +} +#define TclSetStartupScriptFileName setStartupScriptFileName +static void TclSetStartupScriptFileName( + const char *fileName) +{ + Tcl_SetStartupScript(Tcl_NewStringObj(fileName,-1), NULL); +} +#define TclGetStartupScriptFileName getStartupScriptFileName +static const char *TclGetStartupScriptFileName(void) +{ + Tcl_Obj *path = Tcl_GetStartupScript(NULL); + if (path == NULL) { + return NULL; + } + return Tcl_GetStringFromObj(path, NULL); +} #if defined(_WIN32) || defined(__CYGWIN__) #undef TclWinNToHS @@ -347,8 +374,8 @@ static const TclIntStubs tclIntStubs = { 0, /* 155 */ TclRegError, /* 156 */ TclVarTraceExists, /* 157 */ - 0, /* 158 */ - 0, /* 159 */ + TclSetStartupScriptFileName, /* 158 */ + TclGetStartupScriptFileName, /* 159 */ 0, /* 160 */ TclChannelTransform, /* 161 */ TclChannelEventScriptInvoker, /* 162 */ @@ -356,8 +383,8 @@ static const TclIntStubs tclIntStubs = { TclExpandCodeArray, /* 164 */ TclpSetInitialEncodings, /* 165 */ TclListObjSetElement, /* 166 */ - 0, /* 167 */ - 0, /* 168 */ + TclSetStartupScriptPath, /* 167 */ + TclGetStartupScriptPath, /* 168 */ TclpUtfNcmp2, /* 169 */ TclCheckInterpTraces, /* 170 */ TclCheckExecutionTraces, /* 171 */ @@ -367,8 +394,8 @@ static const TclIntStubs tclIntStubs = { TclCallVarTraces, /* 175 */ TclCleanupVar, /* 176 */ TclVarErrMsg, /* 177 */ - 0, /* 178 */ - 0, /* 179 */ + Tcl_SetStartupScript, /* 178 */ + Tcl_GetStartupScript, /* 179 */ 0, /* 180 */ 0, /* 181 */ TclpLocaltime, /* 182 */ @@ -425,7 +452,7 @@ static const TclIntStubs tclIntStubs = { TclGetSrcInfoForPc, /* 233 */ TclVarHashCreateVar, /* 234 */ TclInitVarHashTable, /* 235 */ - 0, /* 236 */ + TclBackgroundException, /* 236 */ TclResetCancellation, /* 237 */ TclNRInterpProc, /* 238 */ TclNRInterpProcCore, /* 239 */ diff --git a/generic/tclTest.c b/generic/tclTest.c index a8b27fb..835036b 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -327,10 +327,12 @@ static int TestreturnObjCmd(ClientData dummy, Tcl_Obj *const objv[]); static void TestregexpXflags(const char *string, int length, int *cflagsPtr, int *eflagsPtr); +#ifndef TCL_NO_DEPRECATED static int TestsaveresultCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static void TestsaveresultFree(char *blockPtr); +#endif /* TCL_NO_DEPRECATED */ static int TestsetassocdataCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestsetCmd(ClientData dummy, @@ -523,7 +525,9 @@ int Tcltest_Init( Tcl_Interp *interp) /* Interpreter for application. */ { +#ifndef TCL_NO_DEPRECATED Tcl_ValueType t3ArgTypes[2]; +#endif /* TCL_NO_DEPRECATED */ Tcl_Obj *listPtr; Tcl_Obj **objv; @@ -642,8 +646,10 @@ Tcltest_Init( NULL, NULL); Tcl_CreateObjCommand(interp, "testreturn", TestreturnObjCmd, NULL, NULL); +#ifndef TCL_NO_DEPRECATED Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd, NULL, NULL); +#endif /* TCL_NO_DEPRECATED */ Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd, @@ -665,8 +671,10 @@ Tcltest_Init( Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); +#ifndef TCL_NO_DEPRECATED Tcl_CreateMathFunc(interp, "T1", 0, NULL, TestMathFunc, (ClientData) 123); Tcl_CreateMathFunc(interp, "T2", 0, NULL, TestMathFunc, (ClientData) 345); +#endif /* TCL_NO_DEPRECATED */ Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd, @@ -677,10 +685,12 @@ Tcltest_Init( Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd, (ClientData) 0, NULL); #endif +#ifndef TCL_NO_DEPRECATED t3ArgTypes[0] = TCL_EITHER; t3ArgTypes[1] = TCL_EITHER; Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2, NULL); +#endif /* TCL_NO_DEPRECATED */ Tcl_CreateObjCommand(interp, "testnrelevels", TestNRELevels, NULL, NULL); @@ -5003,6 +5013,7 @@ Testset2Cmd( } } +#ifndef TCL_NO_DEPRECATED /* *---------------------------------------------------------------------- * @@ -5136,6 +5147,7 @@ TestsaveresultFree( { freeCount++; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -6170,7 +6182,7 @@ TestReport( * API, but there you go. We should convert it to objects. */ - Tcl_SavedResult savedResult; + Tcl_Obj *savedResult; Tcl_DString ds; Tcl_DStringInit(&ds); @@ -6184,11 +6196,15 @@ TestReport( Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2)); } Tcl_DStringEndSublist(&ds); - Tcl_SaveResult(interp, &savedResult); + savedResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(savedResult); + Tcl_SetObjResult(interp, Tcl_NewObj()); Tcl_Eval(interp, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); - Tcl_RestoreResult(interp, &savedResult); - } + Tcl_ResetResult(interp); + Tcl_SetObjResult(interp, savedResult); + Tcl_DecrRefCount(savedResult); + } } static int diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c index 4bddc42..f36b07f 100644 --- a/generic/tclTestObj.c +++ b/generic/tclTestObj.c @@ -555,7 +555,7 @@ TestindexobjCmd( } Tcl_GetIndexFromObj(NULL, objv[1], tablePtr, "token", 0, &index); - indexRep = objv[1]->internalRep.otherValuePtr; + indexRep = objv[1]->internalRep.twoPtrValue.ptr1; indexRep->index = index2; result = Tcl_GetIndexFromObj(NULL, objv[1], tablePtr, "token", 0, &index); @@ -592,7 +592,7 @@ TestindexobjCmd( if (objv[3]->typePtr != NULL && !strcmp("index", objv[3]->typePtr->name)) { - indexRep = objv[3]->internalRep.otherValuePtr; + indexRep = objv[3]->internalRep.twoPtrValue.ptr1; if (indexRep->tablePtr == (void *) argv) { TclFreeIntRep(objv[3]); } @@ -1250,7 +1250,7 @@ TeststringobjCmd( if (varPtr[varIndex] != NULL) { Tcl_ConvertToType(NULL, varPtr[varIndex], Tcl_GetObjType("string")); - strPtr = varPtr[varIndex]->internalRep.otherValuePtr; + strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1; length = (int) strPtr->allocated; } else { length = -1; @@ -1304,7 +1304,7 @@ TeststringobjCmd( if (varPtr[varIndex] != NULL) { Tcl_ConvertToType(NULL, varPtr[varIndex], Tcl_GetObjType("string")); - strPtr = varPtr[varIndex]->internalRep.otherValuePtr; + strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1; length = strPtr->maxChars; } else { length = -1; diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index e4261d6..abd5af5 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -573,7 +573,7 @@ TclThreadAllocObj(void) } while (--numMove >= 0) { objPtr = &newObjsPtr[numMove]; - objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; cachePtr->firstObjPtr = objPtr; } } @@ -584,7 +584,7 @@ TclThreadAllocObj(void) */ objPtr = cachePtr->firstObjPtr; - cachePtr->firstObjPtr = objPtr->internalRep.otherValuePtr; + cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1; cachePtr->numObjects--; return objPtr; } @@ -621,7 +621,7 @@ TclThreadFreeObj( * Get this thread's list and push on the free Tcl_Obj. */ - objPtr->internalRep.otherValuePtr = cachePtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; cachePtr->firstObjPtr = objPtr; cachePtr->numObjects++; @@ -722,16 +722,16 @@ MoveObjs( */ while (--numMove) { - objPtr = objPtr->internalRep.otherValuePtr; + objPtr = objPtr->internalRep.twoPtrValue.ptr1; } - fromPtr->firstObjPtr = objPtr->internalRep.otherValuePtr; + fromPtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1; /* * Move all objects as a block - they are already linked to each other, we * just have to update the first and last. */ - objPtr->internalRep.otherValuePtr = toPtr->firstObjPtr; + objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; toPtr->firstObjPtr = fromFirstObjPtr; } diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index b90e33d..8708f9a 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -926,10 +926,11 @@ ThreadSend( ckfree(resultPtr->errorInfo); } } - Tcl_SetResult(interp, resultPtr->result, TCL_DYNAMIC); + Tcl_AppendResult(interp, resultPtr->result, NULL); Tcl_ConditionFinalize(&resultPtr->done); code = resultPtr->code; + ckfree(resultPtr->result); ckfree(resultPtr); return code; diff --git a/generic/tclTrace.c b/generic/tclTrace.c index 519f201..c0cde49 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -155,8 +155,8 @@ typedef struct StringTraceData { #define FOREACH_VAR_TRACE(interp, name, clientData) \ (clientData) = NULL; \ - while (((clientData) = Tcl_VarTraceInfo((interp), (name), 0, \ - TraceVarProc, (clientData))) != NULL) + while (((clientData) = Tcl_VarTraceInfo2((interp), (name), NULL, \ + 0, TraceVarProc, (clientData))) != NULL) #define FOREACH_COMMAND_TRACE(interp, name, clientData) \ (clientData) = NULL; \ @@ -1322,7 +1322,7 @@ TraceCommandProc( Tcl_DStringLength(&cmd), 0); if (code != TCL_OK) { /* We ignore errors in these traced commands */ - /*** QUESTION: Use Tcl_BackgroundError(interp); instead? ***/ + /*** QUESTION: Use Tcl_BackgroundException(interp, code); instead? ***/ } Tcl_DStringFree(&cmd); } @@ -1485,7 +1485,11 @@ TclCheckExecutionTraces( } iPtr->activeCmdTracePtr = active.nextPtr; if (state) { - Tcl_RestoreInterpState(interp, state); + if (traceCode == TCL_OK) { + (void) Tcl_RestoreInterpState(interp, state); + } else { + Tcl_DiscardInterpState(state); + } } return traceCode; @@ -2811,6 +2815,7 @@ DisposeTraceResult( *---------------------------------------------------------------------- */ +#undef Tcl_UntraceVar void Tcl_UntraceVar( Tcl_Interp *interp, /* Interpreter containing variable. */ @@ -2979,6 +2984,7 @@ Tcl_UntraceVar2( *---------------------------------------------------------------------- */ +#undef Tcl_VarTraceInfo ClientData Tcl_VarTraceInfo( Tcl_Interp *interp, /* Interpreter containing variable. */ @@ -3087,6 +3093,7 @@ Tcl_VarTraceInfo2( *---------------------------------------------------------------------- */ +#undef Tcl_TraceVar int Tcl_TraceVar( Tcl_Interp *interp, /* Interpreter in which variable is to be diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 4b5b37b..18a82f7 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -1516,8 +1516,9 @@ Tcl_UniCharIsSpace( if (((Tcl_UniChar) ch) < ((Tcl_UniChar) 0x80)) { return isspace(UCHAR(ch)); /* INTL: ISO space */ - } else if ((Tcl_UniChar) ch == 0x0085 || (Tcl_UniChar) ch == 0x200b - || (Tcl_UniChar) ch == 0x2060 || (Tcl_UniChar) ch == 0xfeff) { + } else if ((Tcl_UniChar) ch == 0x0085 || (Tcl_UniChar) ch == 0x180e + || (Tcl_UniChar) ch == 0x200b || (Tcl_UniChar) ch == 0x2060 + || (Tcl_UniChar) ch == 0xfeff) { return 1; } else { return ((SPACE_BITS >> GetCategory(ch)) & 1); diff --git a/generic/tclVar.c b/generic/tclVar.c index 6b67029..af1a563 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -47,6 +47,13 @@ static inline void CleanupVar(Var *varPtr, Var *arrayPtr); #define VarHashGetValue(hPtr) \ ((Var *) ((char *)hPtr - TclOffset(VarInHash, entry))) +/* + * NOTE: VarHashCreateVar increments the recount of its key argument. + * All callers that will call Tcl_DecrRefCount on that argument must + * call Tcl_IncrRefCount on it before passing it in. This requirement + * can bubble up to callers of callers .... etc. + */ + static inline Var * VarHashCreateVar( TclVarHashTable *tablePtr, @@ -137,6 +144,30 @@ static const char *isArrayElement = #define HasLocalVars(framePtr) ((framePtr)->isProcCallFrame & FRAME_IS_PROC) /* + * The following structure describes an enumerative search in progress on an + * array variable; this are invoked with options to the "array" command. + */ + +typedef struct ArraySearch { + int id; /* Integer id used to distinguish among + * multiple concurrent searches for the same + * array. */ + struct Var *varPtr; /* Pointer to array variable that's being + * searched. */ + Tcl_HashSearch search; /* Info kept by the hash module about progress + * through the array. */ + Tcl_HashEntry *nextEntry; /* Non-null means this is the next element to + * be enumerated (it's leftover from the + * Tcl_FirstHashEntry call or from an "array + * anymore" command). NULL means must call + * Tcl_NextHashEntry to get value to + * return. */ + struct ArraySearch *nextPtr;/* Next in list of all active searches for + * this variable, or NULL if this is the last + * one. */ +} ArraySearch; + +/* * Forward references to functions defined later in this file: */ @@ -383,11 +414,12 @@ TclLookupVar( * address of array variable. Otherwise this * is set to NULL. */ { - Tcl_Obj *part1Ptr; Var *varPtr; + Tcl_Obj *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); + if (createPart1) { + Tcl_IncrRefCount(part1Ptr); + } varPtr = TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, arrayPtrPtr); @@ -432,6 +464,8 @@ TclLookupVar( * are 1. The object part1Ptr is converted to one of localVarNameType, * tclNsVarNameType or tclParsedVarNameType and caches as much of the * lookup as it can. + * When createPart1 is 1, callers must IncrRefCount part1Ptr if they + * plan to DecrRefCount it. * *---------------------------------------------------------------------- */ @@ -460,14 +494,14 @@ TclObjLookupVar( * address of array variable. Otherwise this * is set to NULL. */ { - Tcl_Obj *part2Ptr; + Tcl_Obj *part2Ptr = NULL; Var *resPtr; if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); - Tcl_IncrRefCount(part2Ptr); - } else { - part2Ptr = NULL; + if (createPart2) { + Tcl_IncrRefCount(part2Ptr); + } } resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, @@ -480,6 +514,12 @@ TclObjLookupVar( return resPtr; } +/* + * When createPart1 is 1, callers must IncrRefCount part1Ptr if they + * plan to DecrRefCount it. + * When createPart2 is 1, callers must IncrRefCount part2Ptr if they + * plan to DecrRefCount it. + */ Var * TclObjLookupVarEx( Tcl_Interp *interp, /* Interpreter to use for lookup. */ @@ -620,7 +660,9 @@ TclObjLookupVarEx( part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2; if (newPart2) { part2Ptr = Tcl_NewStringObj(newPart2, -1); - Tcl_IncrRefCount(part2Ptr); + if (createPart2) { + Tcl_IncrRefCount(part2Ptr); + } } part1Ptr = part1Ptr->internalRep.twoPtrValue.ptr1; typePtr = part1Ptr->typePtr; @@ -666,7 +708,9 @@ TclObjLookupVarEx( *(newPart2+len2) = '\0'; part2 = newPart2; part2Ptr = Tcl_NewStringObj(newPart2, -1); - Tcl_IncrRefCount(part2Ptr); + if (createPart2) { + Tcl_IncrRefCount(part2Ptr); + } /* * Free the internal rep of the original part1Ptr, now renamed @@ -847,6 +891,7 @@ TclObjLookupVarEx( * * Side effects: * A new hashtable entry may be created if create is 1. + * Callers must Incr varNamePtr if they plan to Decr it if create is 1. * *---------------------------------------------------------------------- */ @@ -1075,6 +1120,8 @@ TclLookupSimpleVar( * The variable at arrayPtr may be converted to be an array if * createPart1 is 1. A new hashtable entry may be created if createPart2 * is 1. + * When createElem is 1, callers must incr elNamePtr if they plan + * to decr it. * *---------------------------------------------------------------------- */ @@ -1200,6 +1247,7 @@ TclLookupArrayElement( *---------------------------------------------------------------------- */ +#undef Tcl_GetVar const char * Tcl_GetVar( Tcl_Interp *interp, /* Command interpreter in which varName is to @@ -1209,11 +1257,9 @@ Tcl_GetVar( * TCL_NAMESPACE_ONLY or TCL_LEAVE_ERR_MSG * bits. */ { - Tcl_Obj *varNamePtr, *resultPtr; + Tcl_Obj *varNamePtr = Tcl_NewStringObj(varName, -1); + Tcl_Obj *resultPtr = Tcl_ObjGetVar2(interp, varNamePtr, NULL, flags); - varNamePtr = Tcl_NewStringObj(varName, -1); - Tcl_IncrRefCount(varNamePtr); - resultPtr = Tcl_ObjGetVar2(interp, varNamePtr, NULL, flags); TclDecrRefCount(varNamePtr); if (resultPtr == NULL) { @@ -1257,15 +1303,12 @@ Tcl_GetVar2( * TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG * * bits. */ { - Tcl_Obj *resultPtr, *part1Ptr, *part2Ptr; + Tcl_Obj *resultPtr; + Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); Tcl_IncrRefCount(part2Ptr); - } else { - part2Ptr = NULL; } resultPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags); @@ -1314,15 +1357,11 @@ Tcl_GetVar2Ex( int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and * TCL_LEAVE_ERR_MSG bits. */ { - Tcl_Obj *part1Ptr, *part2Ptr, *resPtr; + Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); Tcl_IncrRefCount(part2Ptr); - } else { - part2Ptr = NULL; } resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags); @@ -1355,6 +1394,8 @@ Tcl_GetVar2Ex( * the returned reference; if you want to keep a reference to the object * you must increment its ref count yourself. * + * Callers must incr part2Ptr if they plan to decr it. + * *---------------------------------------------------------------------- */ @@ -1549,6 +1590,7 @@ Tcl_SetObjCmd( *---------------------------------------------------------------------- */ +#undef Tcl_SetVar const char * Tcl_SetVar( Tcl_Interp *interp, /* Command interpreter in which varName is to @@ -1560,17 +1602,13 @@ Tcl_SetVar( * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ { - Tcl_Obj *valuePtr, *varNamePtr, *varValuePtr; + Tcl_Obj *varValuePtr, *varNamePtr = Tcl_NewStringObj(varName, -1); - varNamePtr = Tcl_NewStringObj(varName, -1); Tcl_IncrRefCount(varNamePtr); - valuePtr = Tcl_NewStringObj(newValue, -1); - Tcl_IncrRefCount(valuePtr); - - varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL, valuePtr, flags); - + varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL, + Tcl_NewStringObj(newValue, -1), flags); Tcl_DecrRefCount(varNamePtr); - Tcl_DecrRefCount(valuePtr); + if (varValuePtr == NULL) { return NULL; } @@ -1618,27 +1656,9 @@ Tcl_SetVar2( * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or * TCL_LEAVE_ERR_MSG. */ { - Tcl_Obj *valuePtr, *part1Ptr, *part2Ptr; - Tcl_Obj *varValuePtr; + Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, part1, part2, + Tcl_NewStringObj(newValue, -1), flags); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); - if (part2 != NULL) { - part2Ptr = Tcl_NewStringObj(part2, -1); - Tcl_IncrRefCount(part2Ptr); - } else { - part2Ptr = NULL; - } - valuePtr = Tcl_NewStringObj(newValue, -1); - Tcl_IncrRefCount(valuePtr); - - varValuePtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, valuePtr, flags); - - Tcl_DecrRefCount(part1Ptr); - if (part2Ptr != NULL) { - Tcl_DecrRefCount(part2Ptr); - } - Tcl_DecrRefCount(valuePtr); if (varValuePtr == NULL) { return NULL; } @@ -1697,15 +1717,12 @@ Tcl_SetVar2Ex( * TCL_APPEND_VALUE, TCL_LIST_ELEMENT or * TCL_LEAVE_ERR_MSG. */ { - Tcl_Obj *part1Ptr, *part2Ptr, *resPtr; + Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); Tcl_IncrRefCount(part2Ptr); - } else { - part2Ptr = NULL; } resPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags); @@ -1738,6 +1755,8 @@ Tcl_SetVar2Ex( * Side effects: * The value of the given variable is set. If either the array or the * entry didn't exist then a new variable is created. + * Callers must Incr part1Ptr if they plan to Decr it. + * Callers must Incr part2Ptr if they plan to Decr it. * *---------------------------------------------------------------------- */ @@ -2027,6 +2046,8 @@ TclPtrSetVar( * variable is created. The ref count for the returned object is _not_ * incremented to reflect the returned reference; if you want to keep a * reference to the object you must increment its ref count yourself. + * Callers must Incr part1Ptr if they plan to Decr it. + * Callers must Incr part2Ptr if they plan to Decr it. * *---------------------------------------------------------------------- */ @@ -2052,8 +2073,8 @@ TclIncrObjVar2( varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read", 1, 1, &arrayPtr); if (varPtr == NULL) { - Tcl_AddObjErrorInfo(interp, - "\n (reading value of variable to increment)", -1); + Tcl_AddErrorInfo(interp, + "\n (reading value of variable to increment)"); return NULL; } return TclPtrIncrObjVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, @@ -2109,8 +2130,7 @@ TclPtrIncrObjVar( * variable, or -1. Only used when part1Ptr is * NULL. */ { - register Tcl_Obj *varValuePtr, *newValuePtr = NULL; - int duplicated, code; + register Tcl_Obj *varValuePtr; if (TclIsVarInHash(varPtr)) { VarHashRefCount(varPtr)++; @@ -2124,19 +2144,33 @@ TclPtrIncrObjVar( varValuePtr = Tcl_NewIntObj(0); } if (Tcl_IsShared(varValuePtr)) { - duplicated = 1; + /* Copy on write */ varValuePtr = Tcl_DuplicateObj(varValuePtr); + + if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) { + return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, + varValuePtr, flags, index); + } else { + Tcl_DecrRefCount(varValuePtr); + return NULL; + } } else { - duplicated = 0; - } - code = TclIncrObj(interp, varValuePtr, incrPtr); - if (code == TCL_OK) { - newValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, - part2Ptr, varValuePtr, flags, index); - } else if (duplicated) { - Tcl_DecrRefCount(varValuePtr); + /* Unshared - can Incr in place */ + if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) { + + /* + * This seems dumb to write the incremeted value into the var + * after we just adjusted the value in place, but the spec for + * [incr] requires that write traces fire, and making this call + * is the way to make that happen. + */ + + return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, + varValuePtr, flags, index); + } else { + return NULL; + } } - return newValuePtr; } /* @@ -2159,6 +2193,7 @@ TclPtrIncrObjVar( *---------------------------------------------------------------------- */ +#undef Tcl_UnsetVar int Tcl_UnsetVar( Tcl_Interp *interp, /* Command interpreter in which varName is to @@ -2219,13 +2254,10 @@ Tcl_UnsetVar2( * TCL_LEAVE_ERR_MSG. */ { int result; - Tcl_Obj *part1Ptr, *part2Ptr = NULL; + Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); - Tcl_IncrRefCount(part2Ptr); } /* @@ -2841,6 +2873,7 @@ Tcl_LappendObjCmd( * * Side effects: * A variable will be created if one does not already exist. + * Callers must Incr arrayNameObj if they pland to Decr it. * *---------------------------------------------------------------------- */ @@ -4255,6 +4288,8 @@ TclInitArrayCmd( * The variable given by myName is linked to the variable in framePtr * given by otherP1 and otherP2, so that references to myName are * redirected to the other variable like a symbolic link. + * Callers must Incr myNamePtr if they plan to Decr it. + * Callers must Incr otherP1Ptr if they plan to Decr it. * *---------------------------------------------------------------------- */ @@ -4363,14 +4398,12 @@ TclPtrMakeUpvar( int index) /* If the variable to be linked is an indexed * scalar, this is its index. Otherwise, -1 */ { - Tcl_Obj *myNamePtr; + Tcl_Obj *myNamePtr = NULL; int result; if (myName) { myNamePtr = Tcl_NewStringObj(myName, -1); Tcl_IncrRefCount(myNamePtr); - } else { - myNamePtr = NULL; } result = TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index); if (myNamePtr) { @@ -4379,6 +4412,8 @@ TclPtrMakeUpvar( return result; } +/* Callers must Incr myNamePtr if they plan to Decr it. */ + int TclPtrObjMakeUpvar( Tcl_Interp *interp, /* Interpreter containing variables. Used for @@ -4518,6 +4553,7 @@ TclPtrObjMakeUpvar( *---------------------------------------------------------------------- */ +#undef Tcl_UpVar int Tcl_UpVar( Tcl_Interp *interp, /* Command interpreter in which varName is to @@ -5111,7 +5147,8 @@ ParseSearchId( * Parse the id. */ - if (Tcl_ConvertToType(interp, handleObj, &tclArraySearchType) != TCL_OK) { + if ((handleObj->typePtr != &tclArraySearchType) + && (SetArraySearchObj(interp, handleObj) != TCL_OK)) { return NULL; } @@ -5242,8 +5279,6 @@ TclDeleteNamespaceVars( for (varPtr = VarHashFirstVar(tablePtr, &search); varPtr != NULL; varPtr = VarHashFirstVar(tablePtr, &search)) { Tcl_Obj *objPtr = Tcl_NewObj(); - - Tcl_IncrRefCount(objPtr); VarHashRefCount(varPtr)++; /* Make sure we get to remove from * hash. */ Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr); @@ -5507,15 +5542,10 @@ TclVarErrMsg( * e.g. "read", "set", or "unset". */ const char *reason) /* String describing why operation failed. */ { - Tcl_Obj *part1Ptr = NULL, *part2Ptr = NULL; + Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1); - part1Ptr = Tcl_NewStringObj(part1, -1); - Tcl_IncrRefCount(part1Ptr); if (part2) { part2Ptr = Tcl_NewStringObj(part2, -1); - Tcl_IncrRefCount(part2Ptr); - } else { - part2 = NULL; } TclObjVarErrMsg(interp, part1Ptr, part2Ptr, operation, reason, -1); @@ -5788,7 +5818,6 @@ Tcl_FindNamespaceVar( Tcl_Obj *namePtr = Tcl_NewStringObj(name, -1); Tcl_Var var; - Tcl_IncrRefCount(namePtr); var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags); Tcl_DecrRefCount(namePtr); return var; @@ -5883,7 +5912,6 @@ ObjFindNamespaceVar( varPtr = NULL; if (simpleName != name) { simpleNamePtr = Tcl_NewStringObj(simpleName, -1); - Tcl_IncrRefCount(simpleNamePtr); } else { simpleNamePtr = namePtr; } diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9c1176e..9bceb4c 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3111,7 +3111,7 @@ ZlibTransformOutput( e = deflate(&cd->outStream, Z_NO_FLUSH); produced = cd->outAllocated - cd->outStream.avail_out; - if (e == Z_OK && cd->outStream.avail_out > 0) { + if (e == Z_OK && produced > 0) { if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { *errorCodePtr = Tcl_GetErrno(); return -1; @@ -3865,7 +3865,7 @@ TclZlibInit( cfg[0].key = "zlibVersion"; cfg[0].value = zlibVersion(); cfg[1].key = NULL; - Tcl_RegisterConfig(interp, "zlib", cfg, "ascii"); + Tcl_RegisterConfig(interp, "zlib", cfg, "iso8859-1"); /* * Formally provide the package as a Tcl built-in. @@ -3891,8 +3891,10 @@ Tcl_ZlibStreamInit( Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); + Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + } return TCL_ERROR; } @@ -3957,8 +3959,10 @@ Tcl_ZlibDeflate( int level, Tcl_Obj *gzipHeaderDictObj) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); + Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + } return TCL_ERROR; } @@ -3970,8 +3974,10 @@ Tcl_ZlibInflate( int bufferSize, Tcl_Obj *gzipHeaderDictObj) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); - Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1)); + Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL); + } return TCL_ERROR; } diff --git a/library/auto.tcl b/library/auto.tcl index 4bd860d..0848bb1 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -20,8 +20,9 @@ # None. proc auto_reset {} { - if {[array exists ::auto_index]} { - foreach cmdName [array names ::auto_index] { + global auto_execs auto_index auto_path + if {[array exists auto_index]} { + foreach cmdName [array names auto_index] { set fqcn [namespace which $cmdName] if {$fqcn eq ""} { continue @@ -29,11 +30,11 @@ proc auto_reset {} { rename $fqcn {} } } - unset -nocomplain ::auto_execs ::auto_index ::tcl::auto_oldpath - if {[catch {llength $::auto_path}]} { - set ::auto_path [list [info library]] - } elseif {[info library] ni $::auto_path} { - lappend ::auto_path [info library] + unset -nocomplain auto_execs auto_index ::tcl::auto_oldpath + if {[catch {llength $auto_path}]} { + set auto_path [list [info library]] + } elseif {[info library] ni $auto_path} { + lappend auto_path [info library] } } @@ -53,7 +54,7 @@ proc auto_reset {} { proc tcl_findLibrary {basename version patch initScript enVarName varName} { upvar #0 $varName the_library - global env + global auto_path env tcl_platform set dirs {} set errors {} @@ -83,12 +84,10 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # 3. Relative to auto_path directories. This checks relative to the # Tcl library as well as allowing loading of libraries added to the # auto_path that is not relative to the core library or binary paths. - foreach d $::auto_path { + foreach d $auto_path { lappend dirs [file join $d $basename$version] - if { - $::tcl_platform(platform) eq "unix" - && $::tcl_platform(os) eq "Darwin" - } then { + if {$tcl_platform(platform) eq "unix" + && $tcl_platform(os) eq "Darwin"} { # 4. On MacOSX, check the Resources/Scripts subdir too lappend dirs [file join $d $basename$version Resources Scripts] } @@ -606,6 +605,15 @@ auto_mkindex_parser::command namespace {op args} { } catch {$parser eval "_%@namespace import $args"} } + ensemble { + variable parser + variable contextStack + if {[lindex $args 0] eq "create"} { + set name ::[join [lreverse $contextStack] ::] + # create artifical proc to force an entry in the tclIndex + $parser eval [list ::proc $name {} {}] + } + } } } diff --git a/library/http/http.tcl b/library/http/http.tcl index 4d8aa51..8985368 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -11,7 +11,7 @@ package require Tcl 8.6 # Keep this in sync with pkgIndex.tcl and with the install directories in # Makefiles -package provide http 2.8.6 +package provide http 2.8.7 namespace eval http { # Allow resourcing to not clobber existing data @@ -398,13 +398,16 @@ proc http::geturl {url args} { # First, before the colon, is the protocol scheme (e.g. http) # Second, for HTTP-like protocols, is the authority # The authority is preceded by // and lasts up to (but not including) - # the following / and it identifies up to four parts, of which only one, - # the host, is required (if an authority is present at all). All other - # parts of the authority (user name, password, port number) are optional. + # the following / or ? and it identifies up to four parts, of which + # only one, the host, is required (if an authority is present at all). + # All other parts of the authority (user name, password, port number) + # are optional. # Third is the resource name, which is split into two parts at a ? # The first part (from the single "/" up to "?") is the path, and the # second part (from that "?" up to "#") is the query. *HOWEVER*, we do # not need to separate them; we send the whole lot to the server. + # Both, path and query are allowed to be missing, including their + # delimiting character. # Fourth is the fragment identifier, which is everything after the first # "#" in the URL. The fragment identifier MUST NOT be sent to the server # and indeed, we don't bother to validate it (it could be an error to @@ -441,7 +444,7 @@ proc http::geturl {url args} { ) (?: : (\d+) )? # <port part of authority> )? - ( / [^\#]*)? # <path> (including query) + ( [/\?] [^\#]*)? # <path> (including query) (?: \# (.*) )? # <fragment> $ } @@ -485,6 +488,12 @@ proc http::geturl {url args} { } } if {$srvurl ne ""} { + # RFC 3986 allows empty paths (not even a /), but servers + # return 400 if the path in the HTTP request doesn't start + # with / , so add it here if needed. + if {[string index $srvurl 0] ne "/"} { + set srvurl /$srvurl + } # Check for validity according to RFC 3986, Appendix A set validityRE {(?xi) ^ @@ -545,11 +554,10 @@ proc http::geturl {url args} { # If a timeout is specified we set up the after event and arrange for an # asynchronous socket connection. - set sockopts [list] + set sockopts [list -async] if {$state(-timeout) > 0} { set state(after) [after $state(-timeout) \ [list http::reset $token timeout]] - lappend sockopts -async } # If we are using the proxy, we must pass in the full URL that includes @@ -605,10 +613,15 @@ proc http::geturl {url args} { set socketmap($state(socketinfo)) $sock } - # Wait for the connection to complete. + if {![info exists phost]} { + set phost "" + } + fileevent $sock writable [list http::Connect $token $proto $phost $srvurl] - if {$state(-timeout) > 0} { - fileevent $sock writable [list http::Connect $token] + # Wait for the connection to complete. + if {![info exists state(-command)]} { + # geturl does EVERYTHING asynchronously, so if the user + # calls it synchronously, we just do a wait here. http::wait $token if {![info exists state]} { @@ -624,13 +637,29 @@ proc http::geturl {url args} { set err [lindex $state(error) 0] cleanup $token return -code error $err - } elseif {$state(status) ne "connect"} { - # Likely to be connection timeout - return $token } - set state(status) "" } + return $token +} + + +proc http::Connected { token proto phost srvurl} { + variable http + variable urlTypes + + variable $token + upvar 0 $token state + + # Set back the variables needed here + set sock $state(sock) + set isQueryChannel [info exists state(-querychannel)] + set isQuery [info exists state(-query)] + set host [lindex [split $state(socketinfo) :] 0] + set port [lindex [split $state(socketinfo) :] 1] + + set defport [lindex $urlTypes($proto) 0] + # Send data in cr-lf format, but accept any line terminators fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) @@ -779,35 +808,17 @@ proc http::geturl {url args} { fileevent $sock readable [list http::Event $sock $token] } - if {![info exists state(-command)]} { - # geturl does EVERYTHING asynchronously, so if the user calls it - # synchronously, we just do a wait here. - - wait $token - if {$state(status) eq "error"} { - # Something went wrong, so throw the exception, and the - # enclosing catch will do cleanup. - return -code error [lindex $state(error) 0] - } - } } err]} { # The socket probably was never connected, or the connection dropped # later. - # Clean up after events and such, but DON'T call the command callback - # (if available) because we're going to throw an exception from here - # instead. - # if state(status) is error, it means someone's already called Finish # to do the above-described clean up. if {$state(status) ne "error"} { - Finish $token $err 1 + Finish $token $err } - cleanup $token - return -code error $err } - return $token } # Data access functions: @@ -891,7 +902,7 @@ proc http::cleanup {token} { # Sets the status of the connection, which unblocks # the waiting geturl call -proc http::Connect {token} { +proc http::Connect {token proto phost srvurl} { variable $token upvar 0 $token state set err "due to unexpected EOF" @@ -899,10 +910,10 @@ proc http::Connect {token} { [eof $state(sock)] || [set err [fconfigure $state(sock) -error]] ne "" } { - Finish $token "connect failed $err" 1 + Finish $token "connect failed $err" } else { - set state(status) connect fileevent $state(sock) writable {} + ::http::Connected $token $proto $phost $srvurl } return } @@ -1008,7 +1019,7 @@ proc http::Event {sock token} { } elseif {$n == 0} { # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 - if {$state(http) == "" || [lindex $state(http) 1] == 100} { + if {$state(http) == "" || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)} { return } diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl index ae36e64..753b972 100644 --- a/library/http/pkgIndex.tcl +++ b/library/http/pkgIndex.tcl @@ -1,4 +1,4 @@ if {![package vsatisfies [package provide Tcl] 8.6]} {return} -package ifneeded http 2.8.6 [list tclPkgSetup $dir http 2.8.6 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] +package ifneeded http 2.8.7 [list tclPkgSetup $dir http 2.8.7 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] package ifneeded cookiejar 0.1 [list source [file join $dir cookiejar.tcl]] package ifndeeded tcl::idna 1.0 [list source [file join $dir idna.tcl]] diff --git a/library/init.tcl b/library/init.tcl index e836df9..bedc06e 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -12,6 +12,7 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # +# This test intentionally written in pre-7.5 Tcl if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } @@ -116,9 +117,10 @@ namespace eval tcl { if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} { namespace eval tcl { proc EnvTraceProc {lo n1 n2 op} { - set x $::env($n2) - set ::env($lo) $x - set ::env([string toupper $lo]) $x + global env + set x $env($n2) + set env($lo) $x + set env([string toupper $lo]) $x } proc InitWinEnv {} { global env tcl_platform @@ -159,8 +161,8 @@ if {[interp issafe]} { } else { # Set up search for Tcl Modules (TIP #189). # and setup platform specific unknown package handlers - if {$::tcl_platform(os) eq "Darwin" - && $::tcl_platform(platform) eq "unix"} { + if {$tcl_platform(os) eq "Darwin" + && $tcl_platform(platform) eq "unix"} { package unknown {::tcl::tm::UnknownHandler \ {::tcl::MacOSXPkgUnknown ::tclPkgUnknown}} } else { @@ -233,14 +235,13 @@ if {[namespace which -command tclLog] eq ""} { proc unknown args { variable ::tcl::UnknownPending - global auto_noexec auto_noload env tcl_interactive + global auto_noexec auto_noload env tcl_interactive errorInfo errorCode - - if {[info exists ::errorInfo]} { - set savedErrorInfo $::errorInfo + if {[info exists errorInfo]} { + set savedErrorInfo $errorInfo } - if {[info exists ::errorCode]} { - set savedErrorCode $::errorCode + if {[info exists errorCode]} { + set savedErrorCode $errorCode } set name [lindex $args 0] @@ -271,9 +272,9 @@ proc unknown args { unset -nocomplain ::errorCode } if {[info exists savedErrorInfo]} { - set ::errorInfo $savedErrorInfo + set errorInfo $savedErrorInfo } else { - unset -nocomplain ::errorInfo + unset -nocomplain errorInfo } set code [catch {uplevel 1 $args} msg opts] if {$code == 1} { @@ -282,8 +283,8 @@ proc unknown args { # Note the dependence on how Tcl_AddErrorInfo, etc. # construct the stack trace. # - set errorInfo [dict get $opts -errorinfo] - set errorCode [dict get $opts -errorcode] + set errInfo [dict get $opts -errorinfo] + set errCode [dict get $opts -errorcode] set cinfo $args if {[string bytelength $cinfo] > 150} { set cinfo [string range $cinfo 0 150] @@ -300,7 +301,7 @@ proc unknown args { # and trim the extra contribution from the matching case # set expect "$msg\n while executing\n\"$cinfo" - if {$errorInfo eq $expect} { + if {$errInfo eq $expect} { # # The stack has only the eval from the expanded command # Do not generate any stack trace here. @@ -315,18 +316,18 @@ proc unknown args { # set expect "\n invoked from within\n\"$cinfo" set exlen [string length $expect] - set eilen [string length $errorInfo] + set eilen [string length $errInfo] set i [expr {$eilen - $exlen - 1}] - set einfo [string range $errorInfo 0 $i] + set einfo [string range $errInfo 0 $i] # - # For now verify that $errorInfo consists of what we are about + # For now verify that $errInfo consists of what we are about # to return plus what we expected to trim off. # - if {$errorInfo ne "$einfo$expect"} { + if {$errInfo ne "$einfo$expect"} { error "Tcl bug: unexpected stack trace in \"unknown\"" {} \ - [list CORE UNKNOWN BADTRACE $einfo $expect $errorInfo] + [list CORE UNKNOWN BADTRACE $einfo $expect $errInfo] } - return -code error -errorcode $errorCode \ + return -code error -errorcode $errCode \ -errorinfo $einfo $msg } else { dict incr opts -level @@ -335,7 +336,7 @@ proc unknown args { } } - if {([info level] == 1) && ([info script] eq "") \ + if {([info level] == 1) && ([info script] eq "") && [info exists tcl_interactive] && $tcl_interactive} { if {![info exists auto_noexec]} { set new [auto_execok $name] @@ -788,7 +789,7 @@ proc tcl::CopyDirectory {action src dest} { lappend existing {*}[glob -nocomplain -directory $dest \ -type hidden * .*] foreach s $existing { - if {([file tail $s] ne ".") && ([file tail $s] ne "..")} { + if {[file tail $s] ni {. ..}} { return -code error "error $action \"$src\" to\ \"$dest\": file already exists" } @@ -796,7 +797,7 @@ proc tcl::CopyDirectory {action src dest} { } } else { if {[string first $nsrc $ndest] != -1} { - set srclen [expr {[llength [file split $nsrc]] -1}] + set srclen [expr {[llength [file split $nsrc]] - 1}] set ndest [lindex [file split $ndest] $srclen] if {$ndest eq [file tail $nsrc]} { return -code error "error $action \"$src\" to\ @@ -816,37 +817,9 @@ proc tcl::CopyDirectory {action src dest} { [glob -nocomplain -directory $src -types hidden *]] foreach s [lsort -unique $filelist] { - if {([file tail $s] ne ".") && ([file tail $s] ne "..")} { - file copy -force $s [file join $dest [file tail $s]] + if {[file tail $s] ni {. ..}} { + file copy -force -- $s [file join $dest [file tail $s]] } } return } - -# TIP 131 -if 0 { -proc tcl::rmmadwiw {} { - set magic { - 42 83 fe f6 ff f8 f1 e5 c6 f9 eb fd ff fb f1 e5 cc f5 ec f5 e3 fd fe - ff f5 fa f3 e1 c7 f9 f2 fd ff f9 fe f9 ed f4 fa f6 e6 f9 f2 e6 fd f9 - ff f9 f6 e6 fa fd ff fc fb fc f9 f1 ed - } - foreach mystic [lassign $magic tragic] { - set comic [expr (0x$mystic ^ 0x$tragic) - 255 + 0x$tragic] - append logic [format %x $comic] - set tragic $mystic - } - binary format H* $logic -} - -proc tcl::mathfunc::rmmadwiw {} { - set age [expr {9*6}] - set mind "" - while {$age} { - lappend mind [expr {$age%13}] - set age [expr {$age/13}] - } - set matter [lreverse $mind] - return [join $matter ""] -} -} diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 112507a..5f0ba2e 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -13,7 +13,7 @@ package require Tcl 8.5 # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. -package provide msgcat 1.5.0 +package provide msgcat 1.5.1 namespace eval msgcat { namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \ @@ -287,7 +287,7 @@ proc msgcat::mcload {langdir} { } set x 0 foreach p [mcpreferences] { - if { $p eq {} } { + if {$p eq {}} { set p ROOT } set langfile [file join $langdir $p.msg] @@ -374,7 +374,7 @@ proc msgcat::mcflset {src {dest ""}} { # Results: # Returns the number of pairs processed -proc msgcat::mcmset {locale pairs } { +proc msgcat::mcmset {locale pairs} { variable Msgs set length [llength $pairs] @@ -551,10 +551,9 @@ proc msgcat::Init {} { # Examples: de-CH -> de_ch, sr-Latn-CS -> sr_cs@latin, es-419 -> es # set key {HKEY_CURRENT_USER\Control Panel\International} - if {([registry values $key "LocaleName"] ne "") + if {![catch {registry get $key LocaleName} localeName] && [regexp {^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}))?(?:-.+)?$}\ - [string tolower [registry get $key "LocaleName"]] match locale\ - script territory]} { + [string tolower $localeName] match locale script territory]} { if {"" ne $territory} { append locale _ $territory } @@ -562,9 +561,7 @@ proc msgcat::Init {} { if {[dict exists $modifierDict $script]} { append locale @ [dict get $modifierDict $script] } - if {![catch { - mclocale [ConvertLocale $locale] - }]} { + if {![catch {mclocale [ConvertLocale $locale]}]} { return } } diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index 832bf81..3fdb25a 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded msgcat 1.5.0 [list source [file join $dir msgcat.tcl]] +package ifneeded msgcat 1.5.1 [list source [file join $dir msgcat.tcl]] diff --git a/library/package.tcl b/library/package.tcl index c30431c..52daa0e 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -395,9 +395,7 @@ proc pkg_mkIndex {args} { foreach pkg [lsort [array names files]] { set cmd {} - foreach {name version} $pkg { - break - } + lassign $pkg name version lappend cmd ::tcl::Pkg::Create -name $name -version $version foreach spec [lsort -index 0 $files($pkg)] { foreach {file type procs} $spec { @@ -544,8 +542,7 @@ proc tclPkgUnknown {name args} { # Don't add directories we've already seen, or ones already on the # $use_path. foreach dir [lrange $auto_path $index end] { - if {![info exists tclSeenPath($dir)] - && ([lsearch -exact $use_path $dir] == -1) } { + if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} { lappend use_path $dir } } @@ -628,8 +625,7 @@ proc tcl::MacOSXPkgUnknown {original name args} { # Don't add directories we've already seen, or ones already on the # $use_path. foreach dir [lrange $auto_path $index end] { - if {![info exists tclSeenPath($dir)] - && ([lsearch -exact $use_path $dir] == -1) } { + if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} { lappend use_path $dir } } @@ -681,10 +677,7 @@ proc ::tcl::Pkg::Create {args} { } # Initialize parameters - set opts(-name) {} - set opts(-version) {} - set opts(-source) {} - set opts(-load) {} + array set opts {-name {} -version {} -source {} -load {}} # process parameters for {set i 0} {$i < $len} {incr i} { @@ -732,14 +725,9 @@ proc ::tcl::Pkg::Create {args} { # Handle -load and -source specs foreach key {load source} { foreach filespec $opts(-$key) { - foreach {filename proclist} {{} {}} { - break - } - foreach {filename proclist} $filespec { - break - } - - if {![llength $proclist]} { + lassign $filespec filename proclist + + if { [llength $proclist] == 0 } { set cmd "\[list $key \[file join \$dir [list $filename]\]\]" lappend cmdList $cmd } else { diff --git a/library/platform/pkgIndex.tcl b/library/platform/pkgIndex.tcl index 220a67b..b882e4f 100644 --- a/library/platform/pkgIndex.tcl +++ b/library/platform/pkgIndex.tcl @@ -1,3 +1,3 @@ -package ifneeded platform 1.0.10 [list source [file join $dir platform.tcl]] +package ifneeded platform 1.0.11 [list source [file join $dir platform.tcl]] package ifneeded platform::shell 1.1.4 [list source [file join $dir shell.tcl]] diff --git a/library/platform/platform.tcl b/library/platform/platform.tcl index dd2e66b..a1a728b 100644 --- a/library/platform/platform.tcl +++ b/library/platform/platform.tcl @@ -256,7 +256,7 @@ proc ::platform::LibcVersion {base _->_ vv} { if {![catch { set vdata [lindex [split [exec $libc] \n] 0] }]} { - regexp {([0-9]+(\.[0-9]+)*)} $vdata -> v + regexp {version ([0-9]+(\.[0-9]+)*), by} $vdata -> v foreach {major minor} [split $v .] break set v glibc${major}.${minor} return 1 @@ -368,7 +368,7 @@ proc ::platform::patterns {id} { # ### ### ### ######### ######### ######### ## Ready -package provide platform 1.0.10 +package provide platform 1.0.11 # ### ### ### ######### ######### ######### ## Demo application diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 83ec9d3..d6e6487 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -84,7 +84,7 @@ namespace eval tcltest { # None. # proc normalizePath {pathVar} { - upvar $pathVar path + upvar 1 $pathVar path set oldpwd [pwd] catch {cd $path} set path [pwd] @@ -247,15 +247,15 @@ namespace eval tcltest { # Kept only for compatibility Default constraintsSpecified {} AcceptList - trace variable constraintsSpecified r {set ::tcltest::constraintsSpecified \ - [array names ::tcltest::testConstraints] ;# } + trace add variable constraintsSpecified read [namespace code { + set constraintsSpecified [array names testConstraints] ;#}] # tests that use threads need to know which is the main thread Default mainThread 1 variable mainThread - if {[info commands thread::id] != {}} { + if {[info commands thread::id] ne {}} { set mainThread [thread::id] - } elseif {[info commands testthread] != {}} { + } elseif {[info commands testthread] ne {}} { set mainThread [testthread id] } @@ -263,7 +263,7 @@ namespace eval tcltest { # Tcl tests is the working directory. Whenever this value changes # change to that directory. variable workingDirectory - trace variable workingDirectory w \ + trace add variable workingDirectory write \ [namespace code {cd $workingDirectory ;#}] Default workingDirectory [pwd] AcceptAbsolutePath @@ -277,7 +277,7 @@ namespace eval tcltest { # Set the location of the execuatble Default tcltest [info nameofexecutable] - trace variable tcltest w [namespace code {testConstraint stdio \ + trace add variable tcltest write [namespace code {testConstraint stdio \ [eval [ConstraintInitializer stdio]] ;#}] # save the platform information so it can be restored later @@ -404,11 +404,11 @@ namespace eval tcltest { # already there. set outdir [normalizePath [file dirname \ [file join [pwd] $filename]]] - if {[string equal $outdir [temporaryDirectory]]} { + if {$outdir eq [temporaryDirectory]} { variable filesExisted FillFilesExisted set filename [file tail $filename] - if {[lsearch -exact $filesExisted $filename] == -1} { + if {$filename ni $filesExisted} { lappend filesExisted $filename } } @@ -448,11 +448,11 @@ namespace eval tcltest { # already there. set outdir [normalizePath [file dirname \ [file join [pwd] $filename]]] - if {[string equal $outdir [temporaryDirectory]]} { + if {$outdir eq [temporaryDirectory]} { variable filesExisted FillFilesExisted set filename [file tail $filename] - if {[lsearch -exact $filesExisted $filename] == -1} { + if {$filename ni $filesExisted} { lappend filesExisted $filename } } @@ -534,7 +534,7 @@ namespace eval tcltest { } default { # Exact match trumps ambiguity - if {[lsearch -exact $match $option] >= 0} { + if {$option in $match} { return $option } set values [join [lrange $match 0 end-1] ", "] @@ -549,7 +549,8 @@ namespace eval tcltest { variable OptionControlledVariables foreach varName [concat $OptionControlledVariables Option] { variable $varName - trace variable $varName r [namespace code {ProcessCmdLineArgs ;#}] + trace add variable $varName read [namespace code { + ProcessCmdLineArgs ;#}] } } @@ -557,11 +558,11 @@ namespace eval tcltest { variable OptionControlledVariables foreach varName [concat $OptionControlledVariables Option] { variable $varName - foreach pair [trace vinfo $varName] { - foreach {op cmd} $pair break - if {[string equal r $op] - && [string match *ProcessCmdLineArgs* $cmd]} { - trace vdelete $varName $op $cmd + foreach pair [trace info variable $varName] { + lassign $pair op cmd + if {($op eq "read") && + [string match *ProcessCmdLineArgs* $cmd]} { + trace remove variable $varName $op $cmd } } } @@ -698,7 +699,7 @@ namespace eval tcltest { Option -constraints {} { Do not skip the listed constraints listed in -constraints. } AcceptList - trace variable Option(-constraints) w \ + trace add variable Option(-constraints) write \ [namespace code {SetSelectedConstraints ;#}] # Don't run only the "-constraint" specified tests by default @@ -707,7 +708,7 @@ namespace eval tcltest { variable testConstraints if {!$Option(-limitconstraints)} {return} foreach c [array names testConstraints] { - if {[lsearch -exact $Option(-constraints) $c] == -1} { + if {$c ni $Option(-constraints)} { testConstraint $c 0 } } @@ -715,7 +716,7 @@ namespace eval tcltest { Option -limitconstraints 0 { whether to run only tests with the constraints } AcceptBoolean limitConstraints - trace variable Option(-limitconstraints) w \ + trace add variable Option(-limitconstraints) write \ [namespace code {ClearUnselectedConstraints ;#}] # A test application has to know how to load the tested commands @@ -736,7 +737,7 @@ namespace eval tcltest { } set directory [AcceptDirectory $directory] if {![file writable $directory]} { - if {[string equal [workingDirectory] $directory]} { + if {[workingDirectory] eq $directory} { # Special exception: accept the default value # even if the directory is not writable return $directory @@ -750,7 +751,7 @@ namespace eval tcltest { Option -tmpdir [workingDirectory] { Save temporary files in the specified directory. } AcceptTemporaryDirectory temporaryDirectory - trace variable Option(-tmpdir) w \ + trace add variable Option(-tmpdir) write \ [namespace code {normalizePath Option(-tmpdir) ;#}] # Tests should not rely on the current working directory. @@ -759,17 +760,17 @@ namespace eval tcltest { Option -testdir [workingDirectory] { Search tests in the specified directory. } AcceptDirectory testsDirectory - trace variable Option(-testdir) w \ + trace add variable Option(-testdir) write \ [namespace code {normalizePath Option(-testdir) ;#}] proc AcceptLoadFile { file } { - if {[string equal "" $file]} {return $file} + if {$file eq {}} {return $file} set file [file join [temporaryDirectory] $file] return [AcceptReadable $file] } proc ReadLoadScript {args} { variable Option - if {[string equal "" $Option(-loadfile)]} {return} + if {$Option(-loadfile) eq {}} {return} set tmp [open $Option(-loadfile) r] loadScript [read $tmp] close $tmp @@ -777,7 +778,7 @@ namespace eval tcltest { Option -loadfile {} { Read the script to load the tested commands from the specified file. } AcceptLoadFile loadFile - trace variable Option(-loadfile) w [namespace code ReadLoadScript] + trace add variable Option(-loadfile) write [namespace code ReadLoadScript] proc AcceptOutFile { file } { if {[string equal stderr $file]} {return $file} @@ -789,14 +790,14 @@ namespace eval tcltest { Option -outfile stdout { Send output from test runs to the specified file. } AcceptOutFile outputFile - trace variable Option(-outfile) w \ + trace add variable Option(-outfile) write \ [namespace code {outputChannel $Option(-outfile) ;#}] # errors go to stderr by default Option -errfile stderr { Send errors from test runs to the specified file. } AcceptOutFile errorFile - trace variable Option(-errfile) w \ + trace add variable Option(-errfile) write \ [namespace code {errorChannel $Option(-errfile) ;#}] proc loadIntoSlaveInterpreter {slave args} { @@ -877,7 +878,7 @@ proc tcltest::DebugPArray {level arrayvar} { variable debug if {$debug >= $level} { - catch {upvar $arrayvar $arrayvar} + catch {upvar 1 $arrayvar $arrayvar} parray $arrayvar } return @@ -961,8 +962,7 @@ proc tcltest::testConstraint {constraint {value ""}} { if {[catch {expr {$value && $value}} msg]} { return -code error $msg } - if {[limitConstraints] - && [lsearch -exact $Option(-constraints) $constraint] == -1} { + if {[limitConstraints] && ($constraint ni $Option(-constraints))} { set value 0 } set testConstraints($constraint) $value @@ -986,11 +986,7 @@ proc tcltest::interpreter { {interp ""} } { if {[llength [info level 0]] == 1} { return $tcltest } - if {[string equal {} $interp]} { - set tcltest {} - } else { - set tcltest $interp - } + set tcltest $interp } ##################################################################### @@ -1055,7 +1051,7 @@ proc tcltest::PrintError {errorMsg} { [expr {80 - $InitialMsgLen}]]] puts [errorChannel] [string range $errorMsg 0 $beginningIndex] - while {![string equal end $beginningIndex]} { + while {$beginningIndex ne "end"} { puts -nonewline [errorChannel] \ [string repeat " " $InitialMsgLen] if {($endingIndex - $beginningIndex) @@ -1108,7 +1104,7 @@ proc tcltest::PrintError {errorMsg} { proc tcltest::SafeFetch {n1 n2 op} { variable testConstraints DebugPuts 3 "entering SafeFetch $n1 $n2 $op" - if {[string equal {} $n2]} {return} + if {$n2 eq {}} {return} if {![info exists testConstraints($n2)]} { if {[catch {testConstraint $n2 [eval [ConstraintInitializer $n2]]}]} { testConstraint $n2 0 @@ -1253,9 +1249,8 @@ proc tcltest::DefineConstraintInitializers {} { # are running as root on Unix. ConstraintInitializer root {expr \ - {[string equal unix $::tcl_platform(platform)] - && ([string equal root $::tcl_platform(user)] - || [string equal "" $::tcl_platform(user)])}} + {($::tcl_platform(platform) eq "unix") && + ($::tcl_platform(user) in {root {}})}} ConstraintInitializer notRoot {expr {![testConstraint root]}} # Set nonBlockFiles constraint: 1 means this platform supports @@ -1263,7 +1258,7 @@ proc tcltest::DefineConstraintInitializers {} { ConstraintInitializer nonBlockFiles { set code [expr {[catch {set f [open defs r]}] - || [catch {fconfigure $f -blocking off}]}] + || [catch {chan configure $f -blocking off}]}] catch {close $f} set code } @@ -1289,10 +1284,10 @@ proc tcltest::DefineConstraintInitializers {} { ConstraintInitializer unixExecs { set code 1 - if {[string equal macintosh $::tcl_platform(platform)]} { + if {$::tcl_platform(platform) eq "macintosh"} { set code 0 } - if {[string equal windows $::tcl_platform(platform)]} { + if {$::tcl_platform(platform) eq "windows"} { if {[catch { set file _tcl_test_remove_me.txt makeFile {hello} $file @@ -1386,7 +1381,7 @@ proc tcltest::Usage { {option ""} } { set allOpts [concat -help [Configure]] foreach opt $allOpts { set foo [Usage $opt] - foreach [list x type($opt) usage($opt)] $foo break + lassign $foo x type($opt) usage($opt) set line($opt) " $opt $type($opt) " set length($opt) [string length $line($opt)] if {$length($opt) > $max} {set max $length($opt)} @@ -1410,7 +1405,7 @@ proc tcltest::Usage { {option ""} } { append msg $u } return $msg\n - } elseif {[string equal -help $option]} { + } elseif {$option eq "-help"} { return [list -help "" "Display this usage information."] } else { set type [lindex [info args $Verify($option)] 0] @@ -1436,7 +1431,7 @@ proc tcltest::Usage { {option ""} } { proc tcltest::ProcessFlags {flagArray} { # Process -help first - if {[lsearch -exact $flagArray {-help}] != -1} { + if {"-help" in $flagArray} { PrintUsageInfo exit 1 } @@ -1445,14 +1440,14 @@ proc tcltest::ProcessFlags {flagArray} { RemoveAutoConfigureTraces } else { set args $flagArray - while {[llength $args]>1 && [catch {configure {*}$args} msg]} { + while {[llength $args] > 1 && [catch {configure {*}$args} msg]} { # Something went wrong parsing $args for tcltest options # Check whether the problem is "unknown option" if {[regexp {^unknown option (\S+):} $msg -> option]} { # Could be this is an option the Hook knows about set moreOptions [processCmdLineArgsAddFlagsHook] - if {[lsearch -exact $moreOptions $option] == -1} { + if {$option ni $moreOptions} { # Nope. Report the error, including additional options, # but keep going if {[llength $moreOptions]} { @@ -1471,7 +1466,7 @@ proc tcltest::ProcessFlags {flagArray} { # To recover, find that unknown option and remove up to it. # then retry - while {![string equal [lindex $args 0] $option]} { + while {[lindex $args 0] ne $option} { set args [lrange $args 2 end] } set args [lrange $args 2 end] @@ -1577,7 +1572,7 @@ proc tcltest::Replace::puts {args} { } 2 { # Either -nonewline or channelId has been specified - if {[string equal -nonewline [lindex $args 0]]} { + if {[lindex $args 0] eq "-nonewline"} { append outData [lindex $args end] return # return [Puts -nonewline [lindex $args end]] @@ -1587,7 +1582,7 @@ proc tcltest::Replace::puts {args} { } } 3 { - if {[string equal -nonewline [lindex $args 0]]} { + if {[lindex $args 0] eq "-nonewline"} { # Both -nonewline and channelId are specified, unless # it's an error. -nonewline is supposed to be argv[0]. set channel [lindex $args 1] @@ -1597,12 +1592,10 @@ proc tcltest::Replace::puts {args} { } if {[info exists channel]} { - if {[string equal $channel [[namespace parent]::outputChannel]] - || [string equal $channel stdout]} { + if {$channel in [list [[namespace parent]::outputChannel] stdout]} { append outData [lindex $args end]$newline return - } elseif {[string equal $channel [[namespace parent]::errorChannel]] - || [string equal $channel stderr]} { + } elseif {$channel in [list [[namespace parent]::errorChannel] stderr]} { append errData [lindex $args end]$newline return } @@ -1771,7 +1764,7 @@ proc tcltest::SubstArguments {argList} { set argList {} } - if {$token != {}} { + if {$token ne {}} { # If we saw a word with quote before, then there is a # multi-word token starting with that word. In this case, # add the text and the current word to this token. @@ -1878,10 +1871,7 @@ proc tcltest::test {name description args} { # Pre-define everything to null except output and errorOutput. We # determine whether or not to trap output based on whether or not # these variables (output & errorOutput) are defined. - foreach item {constraints setup cleanup body result returnCodes - match} { - set $item {} - } + lassign {} constraints setup cleanup body result returnCodes match # Set the default match mode set match exact @@ -1893,8 +1883,7 @@ proc tcltest::test {name description args} { # The old test format can't have a 3rd argument (constraints or # script) that starts with '-'. - if {[string match -* [lindex $args 0]] - || ([llength $args] <= 1)} { + if {[string match -* [lindex $args 0]] || ([llength $args] <= 1)} { if {[llength $args] == 1} { set list [SubstArguments [lindex $args 0]] foreach {element value} $list { @@ -1915,7 +1904,7 @@ proc tcltest::test {name description args} { -match -output -errorOutput -constraints} foreach flag [array names testAttributes] { - if {[lsearch -exact $validFlags $flag] == -1} { + if {$flag ni $validFlags} { incr testLevel -1 set sorted [lsort $validFlags] set options [join [lrange $sorted 0 end-1] ", "] @@ -1931,7 +1920,7 @@ proc tcltest::test {name description args} { # Check the values supplied for -match variable CustomMatch - if {[lsearch [array names CustomMatch] $match] == -1} { + if {$match ni [array names CustomMatch]} { incr testLevel -1 set sorted [lsort [array names CustomMatch]] set values [join [lrange $sorted 0 end-1] ", "] @@ -1995,7 +1984,7 @@ proc tcltest::test {name description args} { } else { set testResult [uplevel 1 [list [namespace origin Eval] $command 1]] } - foreach {actualAnswer returnCode} $testResult break + lassign $testResult actualAnswer returnCode if {$returnCode == 1} { set errorInfo(body) $::errorInfo set errorCode(body) $::errorCode @@ -2031,11 +2020,11 @@ proc tcltest::test {name description args} { if {([preserveCore] > 1) && ($coreFailure)} { append coreMsg "\nMoving file to:\ [file join [temporaryDirectory] core-$name]" - catch {file rename -force \ + catch {file rename -force -- \ [file join [workingDirectory] core] \ [file join [temporaryDirectory] core-$name] } msg - if {[string length $msg] > 0} { + if {$msg ne {}} { append coreMsg "\nError:\ Problem renaming core file: $msg" } @@ -2045,7 +2034,7 @@ proc tcltest::test {name description args} { # check if the return code matched the expected return code set codeFailure 0 - if {!$setupFailure && [lsearch -exact $returnCodes $returnCode] == -1} { + if {!$setupFailure && ($returnCode ni $returnCodes)} { set codeFailure 1 } @@ -2124,7 +2113,7 @@ proc tcltest::test {name description args} { set testFd [open $testFile r] set testLine [expr {[lsearch -regexp \ [split [read $testFd] "\n"] \ - "^\[ \t\]*test [string map {. \\.} $name] "]+1}] + "^\[ \t\]*test [string map {. \\.} $name] "] + 1}] close $testFd } } @@ -2169,7 +2158,7 @@ proc tcltest::test {name description args} { puts [outputChannel] "---- Return code should have been\ one of: $returnCodes" if {[IsVerbose error]} { - if {[info exists errorInfo(body)] && ([lsearch $returnCodes 1]<0)} { + if {[info exists errorInfo(body)] && (1 ni $returnCodes)} { puts [outputChannel] "---- errorInfo: $errorInfo(body)" puts [outputChannel] "---- errorCode: $errorCode(body)" } @@ -2250,7 +2239,7 @@ proc tcltest::Skipped {name constraints} { } return 1 } - if {[string equal {} $constraints]} { + if {$constraints eq {}} { # If we're limited to the listed constraints and there aren't # any listed, then we shouldn't run the test. if {[limitConstraints]} { @@ -2401,7 +2390,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} { foreach file $filesMade { if {[file exists $file]} { DebugDo 1 {Warn "cleanupTests deleting $file..."} - catch {file delete -force $file} + catch {file delete -force -- $file} } } set currentFiles {} @@ -2411,7 +2400,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} { } set newFiles {} foreach file $currentFiles { - if {[lsearch -exact $filesExisted $file] == -1} { + if {$file ni $filesExisted} { lappend newFiles $file } } @@ -2494,8 +2483,7 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} { # then add current file to failFile list if any tests in this # file failed - if {$currentFailure \ - && ([lsearch -exact $failFiles $testFileName] == -1)} { + if {$currentFailure && ($testFileName ni $failFiles)} { lappend failFiles $testFileName } set currentFailure false @@ -2555,11 +2543,11 @@ proc tcltest::cleanupTests {{calledFromAllFile 0}} { puts [outputChannel] "produced core file! \ Moving file to: \ [file join [temporaryDirectory] core-$testFileName]" - catch {file rename -force \ + catch {file rename -force -- \ [file join [workingDirectory] core] \ [file join [temporaryDirectory] core-$testFileName] } msg - if {[string length $msg] > 0} { + if {$msg ne {}} { PrintError "Problem renaming file: $msg" } } else { @@ -2637,7 +2625,7 @@ proc tcltest::GetMatchingFiles { args } { # Add to result list all files in match list and not in skip list foreach file $matchFileList { - if {[lsearch -exact $skipFileList $file] == -1} { + if {$file ni $skipFileList} { lappend matchingFiles $file } } @@ -2684,7 +2672,7 @@ proc tcltest::GetMatchingDirectories {rootdir} { foreach pattern [matchDirectories] { foreach path [glob -directory $rootdir -types d -nocomplain -- \ $pattern] { - if {[lsearch -exact $skipDirs $path] == -1} { + if {$path ni $skipDirs} { set matchDirs [concat $matchDirs [GetMatchingDirectories $path]] if {[file exists [file join $path all.tcl]]} { lappend matchDirs $path @@ -2737,7 +2725,7 @@ proc tcltest::runAllTests { {shell ""} } { # [file system] first available in Tcl 8.4 if {![catch {file system [testsDirectory]} result] - && ![string equal native [lindex $result 0]]} { + && ([lindex $result 0] ne "native")} { # If we aren't running in the native filesystem, then we must # run the tests in a single process (via 'source'), because # trying to run then via a pipe will fail since the files don't @@ -2784,10 +2772,10 @@ proc tcltest::runAllTests { {shell ""} } { # needs to read and process output of children. set childargv [list] foreach opt [Configure] { - if {[string equal $opt -outfile]} {continue} + if {$opt eq "-outfile"} {continue} set value [Configure $opt] # Don't bother passing default configuration options - if {[string equal $value $DefaultValue($opt)]} { + if {$value eq $DefaultValue($opt)} { continue } lappend childargv $opt $value @@ -2880,11 +2868,6 @@ proc tcltest::runAllTests { {shell ""} } { # none. proc tcltest::loadTestedCommands {} { - variable l - if {[string equal {} [loadScript]]} { - return - } - return [uplevel 1 [loadScript]] } @@ -2927,16 +2910,15 @@ proc tcltest::saveState {} { proc tcltest::restoreState {} { variable saveState foreach p [uplevel 1 {::info procs}] { - if {([lsearch [lindex $saveState 0] $p] < 0) - && ![string equal [namespace current]::$p \ - [uplevel 1 [list ::namespace origin $p]]]} { + if {($p ni [lindex $saveState 0]) && ("[namespace current]::$p" ne + [uplevel 1 [list ::namespace origin $p]])} { DebugPuts 2 "[lindex [info level 0] 0]: Removing proc $p" uplevel 1 [list ::catch [list ::rename $p {}]] } } foreach p [uplevel 1 {::info vars}] { - if {[lsearch [lindex $saveState 1] $p] < 0} { + if {$p ni [lindex $saveState 1]} { DebugPuts 2 "[lindex [info level 0] 0]:\ Removing variable $p" uplevel 1 [list ::catch [list ::unset $p]] @@ -2997,15 +2979,15 @@ proc tcltest::makeFile {contents name {directory ""}} { putting ``$contents'' into $fullName" set fd [open $fullName w] - fconfigure $fd -translation lf - if {[string equal [string index $contents end] \n]} { + chan configure $fd -translation lf + if {[string index $contents end] eq "\n"} { puts -nonewline $fd $contents } else { puts $fd $contents } close $fd - if {[lsearch -exact $filesMade $fullName] == -1} { + if {$fullName ni $filesMade} { lappend filesMade $fullName } return $fullName @@ -3045,7 +3027,7 @@ proc tcltest::removeFile {name {directory ""}} { Warn "removeFile removing \"$fullName\":\n not a file" } } - return [file delete $fullName] + return [file delete -- $fullName] } # tcltest::makeDirectory -- @@ -3075,7 +3057,7 @@ proc tcltest::makeDirectory {name {directory ""}} { set fullName [file join $directory $name] DebugPuts 3 "[lindex [info level 0] 0]: creating $fullName" file mkdir $fullName - if {[lsearch -exact $filesMade $fullName] == -1} { + if {$fullName ni $filesMade} { lappend filesMade $fullName } return $fullName @@ -3116,7 +3098,7 @@ proc tcltest::removeDirectory {name {directory ""}} { Warn "removeDirectory removing \"$fullName\":\n not a directory" } } - return [file delete -force $fullName] + return [file delete -force -- $fullName] } # tcltest::viewFile -- @@ -3213,7 +3195,7 @@ proc tcltest::LeakFiles {old} { } set leak {} foreach p $new { - if {[lsearch $old $p] < 0} { + if {$p ni $old} { lappend leak $p } } @@ -3284,7 +3266,7 @@ proc tcltest::RestoreLocale {} { # proc tcltest::threadReap {} { - if {[info commands testthread] != {}} { + if {[info commands testthread] ne {}} { # testthread built into tcltest @@ -3304,7 +3286,7 @@ proc tcltest::threadReap {} { } testthread errorproc ThreadError return [llength [testthread names]] - } elseif {[info commands thread::id] != {}} { + } elseif {[info commands thread::id] ne {}} { # Thread extension @@ -3336,15 +3318,15 @@ namespace eval tcltest { # Set up the constraints in the testConstraints array to be lazily # initialized by a registered initializer, or by "false" if no # initializer is registered. - trace variable testConstraints r [namespace code SafeFetch] + trace add variable testConstraints read [namespace code SafeFetch] # Only initialize constraints at package load time if an # [initConstraintsHook] has been pre-defined. This is only # for compatibility support. The modern way to add a custom # test constraint is to just call the [testConstraint] command # straight away, without all this "hook" nonsense. - if {[string equal [namespace current] \ - [namespace qualifiers [namespace which initConstraintsHook]]]} { + if {[namespace current] eq + [namespace qualifiers [namespace which initConstraintsHook]]} { InitConstraints } else { proc initConstraintsHook {} {} @@ -3381,15 +3363,15 @@ namespace eval tcltest { proc LoadTimeCmdLineArgParsingRequired {} { set required false - if {[info exists ::argv] && [lsearch -exact $::argv -help] != -1} { + if {[info exists ::argv] && ("-help" in $::argv)} { # The command line asks for -help, so give it (and exit) # right now. ([configure] does not process -help) set required true } foreach hook { PrintUsageInfoHook processCmdLineArgsHook processCmdLineArgsAddFlagsHook } { - if {[string equal [namespace current] [namespace qualifiers \ - [namespace which $hook]]]} { + if {[namespace current] eq + [namespace qualifiers [namespace which $hook]]} { set required true } else { proc $hook args {} diff --git a/library/tm.tcl b/library/tm.tcl index ce8a013..d2af4f5 100644 --- a/library/tm.tcl +++ b/library/tm.tcl @@ -54,7 +54,7 @@ namespace eval ::tcl::tm { # Export the public API namespace export path - namespace ensemble create -command path -subcommand {add remove list} + namespace ensemble create -command path -subcommands {add remove list} } # ::tcl::tm::path implementations -- @@ -260,10 +260,8 @@ proc ::tcl::tm::UnknownHandler {original name args} { # Otherwise we still have to fallback to the regular # package search to complete the processing. - if { - ($pkgname eq $name) && - [package vsatisfies $pkgversion {*}$args] - } then { + if {($pkgname eq $name) + && [package vsatisfies $pkgversion {*}$args]} { set satisfied 1 # We do not abort the loop, and keep adding provide @@ -347,7 +345,7 @@ proc ::tcl::tm::Defaults {} { # Calls 'path add' to paths to the list of module search paths. proc ::tcl::tm::roots {paths} { - foreach {major minor} [split [info tclversion] .] break + lassign [split [package present Tcl] .] major minor foreach pa $paths { set p [file join $pa tcl$major] for {set n $minor} {$n >= 0} {incr n -1} { diff --git a/library/tzdata/Africa/Cairo b/library/tzdata/Africa/Cairo index 165d8c4..842b7b2 100644 --- a/library/tzdata/Africa/Cairo +++ b/library/tzdata/Africa/Cairo @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Cairo) { - {-9223372036854775808 7500 0 LMT} - {-2185409100 7200 0 EET} + {-9223372036854775808 7509 0 LMT} + {-2185409109 7200 0 EET} {-929844000 10800 1 EEST} {-923108400 7200 0 EET} {-906170400 10800 1 EEST} diff --git a/library/tzdata/Africa/Casablanca b/library/tzdata/Africa/Casablanca index 41f8742..74b767a 100644 --- a/library/tzdata/Africa/Casablanca +++ b/library/tzdata/Africa/Casablanca @@ -34,24 +34,38 @@ set TZData(:Africa/Casablanca) { {1345428000 3600 1 WEST} {1348970400 0 0 WET} {1367114400 3600 1 WEST} + {1373335200 0 0 WET} + {1375927200 3600 1 WEST} {1380420000 0 0 WET} {1398564000 3600 1 WEST} + {1404007200 0 0 WET} + {1406599200 3600 1 WEST} {1411869600 0 0 WET} {1430013600 3600 1 WEST} + {1434592800 0 0 WET} + {1437184800 3600 1 WEST} {1443319200 0 0 WET} {1461463200 3600 1 WEST} + {1465264800 0 0 WET} + {1467856800 3600 1 WEST} {1474768800 0 0 WET} {1493517600 3600 1 WEST} + {1495850400 0 0 WET} + {1498442400 3600 1 WEST} {1506218400 0 0 WET} {1524967200 3600 1 WEST} + {1526436000 0 0 WET} + {1529028000 3600 1 WEST} {1538272800 0 0 WET} {1556416800 3600 1 WEST} + {1557108000 0 0 WET} + {1559700000 3600 1 WEST} {1569722400 0 0 WET} - {1587866400 3600 1 WEST} + {1590285600 3600 1 WEST} {1601172000 0 0 WET} - {1619316000 3600 1 WEST} + {1620871200 3600 1 WEST} {1632621600 0 0 WET} - {1650765600 3600 1 WEST} + {1651543200 3600 1 WEST} {1664071200 0 0 WET} {1682820000 3600 1 WEST} {1695520800 0 0 WET} diff --git a/library/tzdata/Africa/Gaborone b/library/tzdata/Africa/Gaborone index 7753ba0..bd38673 100644 --- a/library/tzdata/Africa/Gaborone +++ b/library/tzdata/Africa/Gaborone @@ -2,7 +2,8 @@ set TZData(:Africa/Gaborone) { {-9223372036854775808 6220 0 LMT} - {-2682294220 7200 0 CAT} + {-2682294220 5400 0 SAST} + {-2109288600 7200 0 CAT} {-829526400 10800 1 CAST} {-813805200 7200 0 CAT} } diff --git a/library/tzdata/Africa/Tripoli b/library/tzdata/Africa/Tripoli index e993249..ac78218 100644 --- a/library/tzdata/Africa/Tripoli +++ b/library/tzdata/Africa/Tripoli @@ -27,5 +27,180 @@ set TZData(:Africa/Tripoli) { {641775600 7200 0 EET} {844034400 3600 0 CET} {860108400 7200 1 CEST} - {875916000 7200 0 EET} + {875919600 7200 0 EET} + {1352505600 3600 0 CET} + {1364515200 7200 1 CEST} + {1382659200 3600 0 CET} + {1395964800 7200 1 CEST} + {1414713600 3600 0 CET} + {1427414400 7200 1 CEST} + {1446163200 3600 0 CET} + {1458864000 7200 1 CEST} + {1477612800 3600 0 CET} + {1490918400 7200 1 CEST} + {1509062400 3600 0 CET} + {1522368000 7200 1 CEST} + {1540512000 3600 0 CET} + {1553817600 7200 1 CEST} + {1571961600 3600 0 CET} + {1585267200 7200 1 CEST} + {1604016000 3600 0 CET} + {1616716800 7200 1 CEST} + {1635465600 3600 0 CET} + {1648166400 7200 1 CEST} + {1666915200 3600 0 CET} + {1680220800 7200 1 CEST} + {1698364800 3600 0 CET} + {1711670400 7200 1 CEST} + {1729814400 3600 0 CET} + {1743120000 7200 1 CEST} + {1761868800 3600 0 CET} + {1774569600 7200 1 CEST} + {1793318400 3600 0 CET} + {1806019200 7200 1 CEST} + {1824768000 3600 0 CET} + {1838073600 7200 1 CEST} + {1856217600 3600 0 CET} + {1869523200 7200 1 CEST} + {1887667200 3600 0 CET} + {1900972800 7200 1 CEST} + {1919116800 3600 0 CET} + {1932422400 7200 1 CEST} + {1951171200 3600 0 CET} + {1963872000 7200 1 CEST} + {1982620800 3600 0 CET} + {1995321600 7200 1 CEST} + {2014070400 3600 0 CET} + {2027376000 7200 1 CEST} + {2045520000 3600 0 CET} + {2058825600 7200 1 CEST} + {2076969600 3600 0 CET} + {2090275200 7200 1 CEST} + {2109024000 3600 0 CET} + {2121724800 7200 1 CEST} + {2140473600 3600 0 CET} + {2153174400 7200 1 CEST} + {2171923200 3600 0 CET} + {2184624000 7200 1 CEST} + {2203372800 3600 0 CET} + {2216678400 7200 1 CEST} + {2234822400 3600 0 CET} + {2248128000 7200 1 CEST} + {2266272000 3600 0 CET} + {2279577600 7200 1 CEST} + {2298326400 3600 0 CET} + {2311027200 7200 1 CEST} + {2329776000 3600 0 CET} + {2342476800 7200 1 CEST} + {2361225600 3600 0 CET} + {2374531200 7200 1 CEST} + {2392675200 3600 0 CET} + {2405980800 7200 1 CEST} + {2424124800 3600 0 CET} + {2437430400 7200 1 CEST} + {2455574400 3600 0 CET} + {2468880000 7200 1 CEST} + {2487628800 3600 0 CET} + {2500329600 7200 1 CEST} + {2519078400 3600 0 CET} + {2531779200 7200 1 CEST} + {2550528000 3600 0 CET} + {2563833600 7200 1 CEST} + {2581977600 3600 0 CET} + {2595283200 7200 1 CEST} + {2613427200 3600 0 CET} + {2626732800 7200 1 CEST} + {2645481600 3600 0 CET} + {2658182400 7200 1 CEST} + {2676931200 3600 0 CET} + {2689632000 7200 1 CEST} + {2708380800 3600 0 CET} + {2721686400 7200 1 CEST} + {2739830400 3600 0 CET} + {2753136000 7200 1 CEST} + {2771280000 3600 0 CET} + {2784585600 7200 1 CEST} + {2802729600 3600 0 CET} + {2816035200 7200 1 CEST} + {2834784000 3600 0 CET} + {2847484800 7200 1 CEST} + {2866233600 3600 0 CET} + {2878934400 7200 1 CEST} + {2897683200 3600 0 CET} + {2910988800 7200 1 CEST} + {2929132800 3600 0 CET} + {2942438400 7200 1 CEST} + {2960582400 3600 0 CET} + {2973888000 7200 1 CEST} + {2992636800 3600 0 CET} + {3005337600 7200 1 CEST} + {3024086400 3600 0 CET} + {3036787200 7200 1 CEST} + {3055536000 3600 0 CET} + {3068236800 7200 1 CEST} + {3086985600 3600 0 CET} + {3100291200 7200 1 CEST} + {3118435200 3600 0 CET} + {3131740800 7200 1 CEST} + {3149884800 3600 0 CET} + {3163190400 7200 1 CEST} + {3181939200 3600 0 CET} + {3194640000 7200 1 CEST} + {3213388800 3600 0 CET} + {3226089600 7200 1 CEST} + {3244838400 3600 0 CET} + {3258144000 7200 1 CEST} + {3276288000 3600 0 CET} + {3289593600 7200 1 CEST} + {3307737600 3600 0 CET} + {3321043200 7200 1 CEST} + {3339187200 3600 0 CET} + {3352492800 7200 1 CEST} + {3371241600 3600 0 CET} + {3383942400 7200 1 CEST} + {3402691200 3600 0 CET} + {3415392000 7200 1 CEST} + {3434140800 3600 0 CET} + {3447446400 7200 1 CEST} + {3465590400 3600 0 CET} + {3478896000 7200 1 CEST} + {3497040000 3600 0 CET} + {3510345600 7200 1 CEST} + {3529094400 3600 0 CET} + {3541795200 7200 1 CEST} + {3560544000 3600 0 CET} + {3573244800 7200 1 CEST} + {3591993600 3600 0 CET} + {3605299200 7200 1 CEST} + {3623443200 3600 0 CET} + {3636748800 7200 1 CEST} + {3654892800 3600 0 CET} + {3668198400 7200 1 CEST} + {3686342400 3600 0 CET} + {3699648000 7200 1 CEST} + {3718396800 3600 0 CET} + {3731097600 7200 1 CEST} + {3749846400 3600 0 CET} + {3762547200 7200 1 CEST} + {3781296000 3600 0 CET} + {3794601600 7200 1 CEST} + {3812745600 3600 0 CET} + {3826051200 7200 1 CEST} + {3844195200 3600 0 CET} + {3857500800 7200 1 CEST} + {3876249600 3600 0 CET} + {3888950400 7200 1 CEST} + {3907699200 3600 0 CET} + {3920400000 7200 1 CEST} + {3939148800 3600 0 CET} + {3951849600 7200 1 CEST} + {3970598400 3600 0 CET} + {3983904000 7200 1 CEST} + {4002048000 3600 0 CET} + {4015353600 7200 1 CEST} + {4033497600 3600 0 CET} + {4046803200 7200 1 CEST} + {4065552000 3600 0 CET} + {4078252800 7200 1 CEST} + {4097001600 3600 0 CET} } diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion index 14bbab2..d530193 100644 --- a/library/tzdata/America/Asuncion +++ b/library/tzdata/America/Asuncion @@ -82,7 +82,8 @@ set TZData(:America/Asuncion) { {1317528000 -10800 1 PYST} {1333854000 -14400 0 PYT} {1349582400 -10800 1 PYST} - {1365908400 -14400 0 PYT} + {1364094000 -14400 0 PYT} + {1365912000 -14400 0 PYT} {1381032000 -10800 1 PYST} {1397358000 -14400 0 PYT} {1412481600 -10800 1 PYST} diff --git a/library/tzdata/America/Barbados b/library/tzdata/America/Barbados index 5c06408..ea17073 100644 --- a/library/tzdata/America/Barbados +++ b/library/tzdata/America/Barbados @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Barbados) { - {-9223372036854775808 -14308 0 LMT} - {-1451678492 -14308 0 BMT} - {-1199217692 -14400 0 AST} + {-9223372036854775808 -14309 0 LMT} + {-1451678491 -14309 0 BMT} + {-1199217691 -14400 0 AST} {234943200 -10800 1 ADT} {244616400 -14400 0 AST} {261554400 -10800 1 ADT} diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota index f727d17..b28abc1 100644 --- a/library/tzdata/America/Bogota +++ b/library/tzdata/America/Bogota @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Bogota) { - {-9223372036854775808 -17780 0 LMT} - {-2707671820 -17780 0 BMT} - {-1739041420 -18000 0 COT} + {-9223372036854775808 -17776 0 LMT} + {-2707671824 -17776 0 BMT} + {-1739041424 -18000 0 COT} {704869200 -14400 1 COST} {733896000 -18000 0 COT} } diff --git a/library/tzdata/America/Costa_Rica b/library/tzdata/America/Costa_Rica index 04420a4..8fc9343 100644 --- a/library/tzdata/America/Costa_Rica +++ b/library/tzdata/America/Costa_Rica @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Costa_Rica) { - {-9223372036854775808 -20180 0 LMT} - {-2524501420 -20180 0 SJMT} - {-1545071020 -21600 0 CST} + {-9223372036854775808 -20173 0 LMT} + {-2524501427 -20173 0 SJMT} + {-1545071027 -21600 0 CST} {288770400 -18000 1 CDT} {297234000 -21600 0 CST} {320220000 -18000 1 CDT} diff --git a/library/tzdata/America/Curacao b/library/tzdata/America/Curacao index 443a319..5189e9c 100644 --- a/library/tzdata/America/Curacao +++ b/library/tzdata/America/Curacao @@ -1,7 +1,7 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Curacao) { - {-9223372036854775808 -16544 0 LMT} - {-1826738656 -16200 0 ANT} + {-9223372036854775808 -16547 0 LMT} + {-1826738653 -16200 0 ANT} {-157750200 -14400 0 AST} } diff --git a/library/tzdata/America/Nassau b/library/tzdata/America/Nassau index 06c5f06..1c35e93 100644 --- a/library/tzdata/America/Nassau +++ b/library/tzdata/America/Nassau @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Nassau) { - {-9223372036854775808 -18564 0 LMT} - {-1825095036 -18000 0 EST} + {-9223372036854775808 -18570 0 LMT} + {-1825095030 -18000 0 EST} {-179341200 -14400 1 EDT} {-163620000 -18000 0 EST} {-147891600 -14400 1 EDT} diff --git a/library/tzdata/America/Port-au-Prince b/library/tzdata/America/Port-au-Prince index 639972b..f1d7fc4 100644 --- a/library/tzdata/America/Port-au-Prince +++ b/library/tzdata/America/Port-au-Prince @@ -40,4 +40,178 @@ set TZData(:America/Port-au-Prince) { {1162094400 -18000 0 EST} {1331449200 -14400 1 EDT} {1352008800 -18000 0 EST} + {1362898800 -14400 1 EDT} + {1383458400 -18000 0 EST} + {1394348400 -14400 1 EDT} + {1414908000 -18000 0 EST} + {1425798000 -14400 1 EDT} + {1446357600 -18000 0 EST} + {1457852400 -14400 1 EDT} + {1478412000 -18000 0 EST} + {1489302000 -14400 1 EDT} + {1509861600 -18000 0 EST} + {1520751600 -14400 1 EDT} + {1541311200 -18000 0 EST} + {1552201200 -14400 1 EDT} + {1572760800 -18000 0 EST} + {1583650800 -14400 1 EDT} + {1604210400 -18000 0 EST} + {1615705200 -14400 1 EDT} + {1636264800 -18000 0 EST} + {1647154800 -14400 1 EDT} + {1667714400 -18000 0 EST} + {1678604400 -14400 1 EDT} + {1699164000 -18000 0 EST} + {1710054000 -14400 1 EDT} + {1730613600 -18000 0 EST} + {1741503600 -14400 1 EDT} + {1762063200 -18000 0 EST} + {1772953200 -14400 1 EDT} + {1793512800 -18000 0 EST} + {1805007600 -14400 1 EDT} + {1825567200 -18000 0 EST} + {1836457200 -14400 1 EDT} + {1857016800 -18000 0 EST} + {1867906800 -14400 1 EDT} + {1888466400 -18000 0 EST} + {1899356400 -14400 1 EDT} + {1919916000 -18000 0 EST} + {1930806000 -14400 1 EDT} + {1951365600 -18000 0 EST} + {1962860400 -14400 1 EDT} + {1983420000 -18000 0 EST} + {1994310000 -14400 1 EDT} + {2014869600 -18000 0 EST} + {2025759600 -14400 1 EDT} + {2046319200 -18000 0 EST} + {2057209200 -14400 1 EDT} + {2077768800 -18000 0 EST} + {2088658800 -14400 1 EDT} + {2109218400 -18000 0 EST} + {2120108400 -14400 1 EDT} + {2140668000 -18000 0 EST} + {2152162800 -14400 1 EDT} + {2172722400 -18000 0 EST} + {2183612400 -14400 1 EDT} + {2204172000 -18000 0 EST} + {2215062000 -14400 1 EDT} + {2235621600 -18000 0 EST} + {2246511600 -14400 1 EDT} + {2267071200 -18000 0 EST} + {2277961200 -14400 1 EDT} + {2298520800 -18000 0 EST} + {2309410800 -14400 1 EDT} + {2329970400 -18000 0 EST} + {2341465200 -14400 1 EDT} + {2362024800 -18000 0 EST} + {2372914800 -14400 1 EDT} + {2393474400 -18000 0 EST} + {2404364400 -14400 1 EDT} + {2424924000 -18000 0 EST} + {2435814000 -14400 1 EDT} + {2456373600 -18000 0 EST} + {2467263600 -14400 1 EDT} + {2487823200 -18000 0 EST} + {2499318000 -14400 1 EDT} + {2519877600 -18000 0 EST} + {2530767600 -14400 1 EDT} + {2551327200 -18000 0 EST} + {2562217200 -14400 1 EDT} + {2582776800 -18000 0 EST} + {2593666800 -14400 1 EDT} + {2614226400 -18000 0 EST} + {2625116400 -14400 1 EDT} + {2645676000 -18000 0 EST} + {2656566000 -14400 1 EDT} + {2677125600 -18000 0 EST} + {2688620400 -14400 1 EDT} + {2709180000 -18000 0 EST} + {2720070000 -14400 1 EDT} + {2740629600 -18000 0 EST} + {2751519600 -14400 1 EDT} + {2772079200 -18000 0 EST} + {2782969200 -14400 1 EDT} + {2803528800 -18000 0 EST} + {2814418800 -14400 1 EDT} + {2834978400 -18000 0 EST} + {2846473200 -14400 1 EDT} + {2867032800 -18000 0 EST} + {2877922800 -14400 1 EDT} + {2898482400 -18000 0 EST} + {2909372400 -14400 1 EDT} + {2929932000 -18000 0 EST} + {2940822000 -14400 1 EDT} + {2961381600 -18000 0 EST} + {2972271600 -14400 1 EDT} + {2992831200 -18000 0 EST} + {3003721200 -14400 1 EDT} + {3024280800 -18000 0 EST} + {3035775600 -14400 1 EDT} + {3056335200 -18000 0 EST} + {3067225200 -14400 1 EDT} + {3087784800 -18000 0 EST} + {3098674800 -14400 1 EDT} + {3119234400 -18000 0 EST} + {3130124400 -14400 1 EDT} + {3150684000 -18000 0 EST} + {3161574000 -14400 1 EDT} + {3182133600 -18000 0 EST} + {3193023600 -14400 1 EDT} + {3213583200 -18000 0 EST} + {3225078000 -14400 1 EDT} + {3245637600 -18000 0 EST} + {3256527600 -14400 1 EDT} + {3277087200 -18000 0 EST} + {3287977200 -14400 1 EDT} + {3308536800 -18000 0 EST} + {3319426800 -14400 1 EDT} + {3339986400 -18000 0 EST} + {3350876400 -14400 1 EDT} + {3371436000 -18000 0 EST} + {3382930800 -14400 1 EDT} + {3403490400 -18000 0 EST} + {3414380400 -14400 1 EDT} + {3434940000 -18000 0 EST} + {3445830000 -14400 1 EDT} + {3466389600 -18000 0 EST} + {3477279600 -14400 1 EDT} + {3497839200 -18000 0 EST} + {3508729200 -14400 1 EDT} + {3529288800 -18000 0 EST} + {3540178800 -14400 1 EDT} + {3560738400 -18000 0 EST} + {3572233200 -14400 1 EDT} + {3592792800 -18000 0 EST} + {3603682800 -14400 1 EDT} + {3624242400 -18000 0 EST} + {3635132400 -14400 1 EDT} + {3655692000 -18000 0 EST} + {3666582000 -14400 1 EDT} + {3687141600 -18000 0 EST} + {3698031600 -14400 1 EDT} + {3718591200 -18000 0 EST} + {3730086000 -14400 1 EDT} + {3750645600 -18000 0 EST} + {3761535600 -14400 1 EDT} + {3782095200 -18000 0 EST} + {3792985200 -14400 1 EDT} + {3813544800 -18000 0 EST} + {3824434800 -14400 1 EDT} + {3844994400 -18000 0 EST} + {3855884400 -14400 1 EDT} + {3876444000 -18000 0 EST} + {3887334000 -14400 1 EDT} + {3907893600 -18000 0 EST} + {3919388400 -14400 1 EDT} + {3939948000 -18000 0 EST} + {3950838000 -14400 1 EDT} + {3971397600 -18000 0 EST} + {3982287600 -14400 1 EDT} + {4002847200 -18000 0 EST} + {4013737200 -14400 1 EDT} + {4034296800 -18000 0 EST} + {4045186800 -14400 1 EDT} + {4065746400 -18000 0 EST} + {4076636400 -14400 1 EDT} + {4097196000 -18000 0 EST} } diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index f42ff3d..44be9f8 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -114,178 +114,178 @@ set TZData(:America/Santiago) { {1313899200 -10800 1 CLST} {1335668400 -14400 0 CLT} {1346558400 -10800 1 CLST} - {1362884400 -14400 0 CLT} - {1381636800 -10800 1 CLST} - {1394334000 -14400 0 CLT} - {1413086400 -10800 1 CLST} - {1426388400 -14400 0 CLT} - {1444536000 -10800 1 CLST} - {1457838000 -14400 0 CLT} - {1475985600 -10800 1 CLST} - {1489287600 -14400 0 CLT} - {1508040000 -10800 1 CLST} - {1520737200 -14400 0 CLT} - {1539489600 -10800 1 CLST} - {1552186800 -14400 0 CLT} - {1570939200 -10800 1 CLST} - {1584241200 -14400 0 CLT} - {1602388800 -10800 1 CLST} - {1615690800 -14400 0 CLT} - {1633838400 -10800 1 CLST} - {1647140400 -14400 0 CLT} - {1665288000 -10800 1 CLST} - {1678590000 -14400 0 CLT} - {1697342400 -10800 1 CLST} - {1710039600 -14400 0 CLT} - {1728792000 -10800 1 CLST} - {1741489200 -14400 0 CLT} - {1760241600 -10800 1 CLST} - {1773543600 -14400 0 CLT} - {1791691200 -10800 1 CLST} - {1804993200 -14400 0 CLT} - {1823140800 -10800 1 CLST} - {1836442800 -14400 0 CLT} - {1855195200 -10800 1 CLST} - {1867892400 -14400 0 CLT} - {1886644800 -10800 1 CLST} - {1899342000 -14400 0 CLT} - {1918094400 -10800 1 CLST} - {1930791600 -14400 0 CLT} - {1949544000 -10800 1 CLST} - {1962846000 -14400 0 CLT} - {1980993600 -10800 1 CLST} - {1994295600 -14400 0 CLT} - {2012443200 -10800 1 CLST} - {2025745200 -14400 0 CLT} - {2044497600 -10800 1 CLST} - {2057194800 -14400 0 CLT} - {2075947200 -10800 1 CLST} - {2088644400 -14400 0 CLT} - {2107396800 -10800 1 CLST} - {2120698800 -14400 0 CLT} - {2138846400 -10800 1 CLST} - {2152148400 -14400 0 CLT} - {2170296000 -10800 1 CLST} - {2183598000 -14400 0 CLT} - {2201745600 -10800 1 CLST} - {2215047600 -14400 0 CLT} - {2233800000 -10800 1 CLST} - {2246497200 -14400 0 CLT} - {2265249600 -10800 1 CLST} - {2277946800 -14400 0 CLT} - {2296699200 -10800 1 CLST} - {2310001200 -14400 0 CLT} - {2328148800 -10800 1 CLST} - {2341450800 -14400 0 CLT} - {2359598400 -10800 1 CLST} - {2372900400 -14400 0 CLT} - {2391652800 -10800 1 CLST} - {2404350000 -14400 0 CLT} - {2423102400 -10800 1 CLST} - {2435799600 -14400 0 CLT} - {2454552000 -10800 1 CLST} - {2467854000 -14400 0 CLT} - {2486001600 -10800 1 CLST} - {2499303600 -14400 0 CLT} - {2517451200 -10800 1 CLST} - {2530753200 -14400 0 CLT} - {2548900800 -10800 1 CLST} - {2562202800 -14400 0 CLT} - {2580955200 -10800 1 CLST} - {2593652400 -14400 0 CLT} - {2612404800 -10800 1 CLST} - {2625102000 -14400 0 CLT} - {2643854400 -10800 1 CLST} - {2657156400 -14400 0 CLT} - {2675304000 -10800 1 CLST} - {2688606000 -14400 0 CLT} - {2706753600 -10800 1 CLST} - {2720055600 -14400 0 CLT} - {2738808000 -10800 1 CLST} - {2751505200 -14400 0 CLT} - {2770257600 -10800 1 CLST} - {2782954800 -14400 0 CLT} - {2801707200 -10800 1 CLST} - {2814404400 -14400 0 CLT} - {2833156800 -10800 1 CLST} - {2846458800 -14400 0 CLT} - {2864606400 -10800 1 CLST} - {2877908400 -14400 0 CLT} - {2896056000 -10800 1 CLST} - {2909358000 -14400 0 CLT} - {2928110400 -10800 1 CLST} - {2940807600 -14400 0 CLT} - {2959560000 -10800 1 CLST} - {2972257200 -14400 0 CLT} - {2991009600 -10800 1 CLST} - {3004311600 -14400 0 CLT} - {3022459200 -10800 1 CLST} - {3035761200 -14400 0 CLT} - {3053908800 -10800 1 CLST} - {3067210800 -14400 0 CLT} - {3085358400 -10800 1 CLST} - {3098660400 -14400 0 CLT} - {3117412800 -10800 1 CLST} - {3130110000 -14400 0 CLT} - {3148862400 -10800 1 CLST} - {3161559600 -14400 0 CLT} - {3180312000 -10800 1 CLST} - {3193614000 -14400 0 CLT} - {3211761600 -10800 1 CLST} - {3225063600 -14400 0 CLT} - {3243211200 -10800 1 CLST} - {3256513200 -14400 0 CLT} - {3275265600 -10800 1 CLST} - {3287962800 -14400 0 CLT} - {3306715200 -10800 1 CLST} - {3319412400 -14400 0 CLT} - {3338164800 -10800 1 CLST} - {3351466800 -14400 0 CLT} - {3369614400 -10800 1 CLST} - {3382916400 -14400 0 CLT} - {3401064000 -10800 1 CLST} - {3414366000 -14400 0 CLT} - {3432513600 -10800 1 CLST} - {3445815600 -14400 0 CLT} - {3464568000 -10800 1 CLST} - {3477265200 -14400 0 CLT} - {3496017600 -10800 1 CLST} - {3508714800 -14400 0 CLT} - {3527467200 -10800 1 CLST} - {3540769200 -14400 0 CLT} - {3558916800 -10800 1 CLST} - {3572218800 -14400 0 CLT} - {3590366400 -10800 1 CLST} - {3603668400 -14400 0 CLT} - {3622420800 -10800 1 CLST} - {3635118000 -14400 0 CLT} - {3653870400 -10800 1 CLST} - {3666567600 -14400 0 CLT} - {3685320000 -10800 1 CLST} - {3698017200 -14400 0 CLT} - {3716769600 -10800 1 CLST} - {3730071600 -14400 0 CLT} - {3748219200 -10800 1 CLST} - {3761521200 -14400 0 CLT} - {3779668800 -10800 1 CLST} - {3792970800 -14400 0 CLT} - {3811723200 -10800 1 CLST} - {3824420400 -14400 0 CLT} - {3843172800 -10800 1 CLST} - {3855870000 -14400 0 CLT} - {3874622400 -10800 1 CLST} - {3887924400 -14400 0 CLT} - {3906072000 -10800 1 CLST} - {3919374000 -14400 0 CLT} - {3937521600 -10800 1 CLST} - {3950823600 -14400 0 CLT} - {3968971200 -10800 1 CLST} - {3982273200 -14400 0 CLT} - {4001025600 -10800 1 CLST} - {4013722800 -14400 0 CLT} - {4032475200 -10800 1 CLST} - {4045172400 -14400 0 CLT} - {4063924800 -10800 1 CLST} - {4077226800 -14400 0 CLT} - {4095374400 -10800 1 CLST} + {1367118000 -14400 0 CLT} + {1378612800 -10800 1 CLST} + {1398567600 -14400 0 CLT} + {1410062400 -10800 1 CLST} + {1430017200 -14400 0 CLT} + {1441512000 -10800 1 CLST} + {1461466800 -14400 0 CLT} + {1472961600 -10800 1 CLST} + {1492916400 -14400 0 CLT} + {1504411200 -10800 1 CLST} + {1524970800 -14400 0 CLT} + {1535860800 -10800 1 CLST} + {1556420400 -14400 0 CLT} + {1567915200 -10800 1 CLST} + {1587870000 -14400 0 CLT} + {1599364800 -10800 1 CLST} + {1619319600 -14400 0 CLT} + {1630814400 -10800 1 CLST} + {1650769200 -14400 0 CLT} + {1662264000 -10800 1 CLST} + {1682218800 -14400 0 CLT} + {1693713600 -10800 1 CLST} + {1714273200 -14400 0 CLT} + {1725768000 -10800 1 CLST} + {1745722800 -14400 0 CLT} + {1757217600 -10800 1 CLST} + {1777172400 -14400 0 CLT} + {1788667200 -10800 1 CLST} + {1808622000 -14400 0 CLT} + {1820116800 -10800 1 CLST} + {1840071600 -14400 0 CLT} + {1851566400 -10800 1 CLST} + {1872126000 -14400 0 CLT} + {1883016000 -10800 1 CLST} + {1903575600 -14400 0 CLT} + {1915070400 -10800 1 CLST} + {1935025200 -14400 0 CLT} + {1946520000 -10800 1 CLST} + {1966474800 -14400 0 CLT} + {1977969600 -10800 1 CLST} + {1997924400 -14400 0 CLT} + {2009419200 -10800 1 CLST} + {2029374000 -14400 0 CLT} + {2040868800 -10800 1 CLST} + {2061428400 -14400 0 CLT} + {2072318400 -10800 1 CLST} + {2092878000 -14400 0 CLT} + {2104372800 -10800 1 CLST} + {2124327600 -14400 0 CLT} + {2135822400 -10800 1 CLST} + {2155777200 -14400 0 CLT} + {2167272000 -10800 1 CLST} + {2187226800 -14400 0 CLT} + {2198721600 -10800 1 CLST} + {2219281200 -14400 0 CLT} + {2230171200 -10800 1 CLST} + {2250730800 -14400 0 CLT} + {2262225600 -10800 1 CLST} + {2282180400 -14400 0 CLT} + {2293675200 -10800 1 CLST} + {2313630000 -14400 0 CLT} + {2325124800 -10800 1 CLST} + {2345079600 -14400 0 CLT} + {2356574400 -10800 1 CLST} + {2376529200 -14400 0 CLT} + {2388024000 -10800 1 CLST} + {2408583600 -14400 0 CLT} + {2419473600 -10800 1 CLST} + {2440033200 -14400 0 CLT} + {2451528000 -10800 1 CLST} + {2471482800 -14400 0 CLT} + {2482977600 -10800 1 CLST} + {2502932400 -14400 0 CLT} + {2514427200 -10800 1 CLST} + {2534382000 -14400 0 CLT} + {2545876800 -10800 1 CLST} + {2565831600 -14400 0 CLT} + {2577326400 -10800 1 CLST} + {2597886000 -14400 0 CLT} + {2609380800 -10800 1 CLST} + {2629335600 -14400 0 CLT} + {2640830400 -10800 1 CLST} + {2660785200 -14400 0 CLT} + {2672280000 -10800 1 CLST} + {2692234800 -14400 0 CLT} + {2703729600 -10800 1 CLST} + {2723684400 -14400 0 CLT} + {2735179200 -10800 1 CLST} + {2755738800 -14400 0 CLT} + {2766628800 -10800 1 CLST} + {2787188400 -14400 0 CLT} + {2798683200 -10800 1 CLST} + {2818638000 -14400 0 CLT} + {2830132800 -10800 1 CLST} + {2850087600 -14400 0 CLT} + {2861582400 -10800 1 CLST} + {2881537200 -14400 0 CLT} + {2893032000 -10800 1 CLST} + {2912986800 -14400 0 CLT} + {2924481600 -10800 1 CLST} + {2945041200 -14400 0 CLT} + {2955931200 -10800 1 CLST} + {2976490800 -14400 0 CLT} + {2987985600 -10800 1 CLST} + {3007940400 -14400 0 CLT} + {3019435200 -10800 1 CLST} + {3039390000 -14400 0 CLT} + {3050884800 -10800 1 CLST} + {3070839600 -14400 0 CLT} + {3082334400 -10800 1 CLST} + {3102894000 -14400 0 CLT} + {3113784000 -10800 1 CLST} + {3134343600 -14400 0 CLT} + {3145838400 -10800 1 CLST} + {3165793200 -14400 0 CLT} + {3177288000 -10800 1 CLST} + {3197242800 -14400 0 CLT} + {3208737600 -10800 1 CLST} + {3228692400 -14400 0 CLT} + {3240187200 -10800 1 CLST} + {3260142000 -14400 0 CLT} + {3271636800 -10800 1 CLST} + {3292196400 -14400 0 CLT} + {3303086400 -10800 1 CLST} + {3323646000 -14400 0 CLT} + {3335140800 -10800 1 CLST} + {3355095600 -14400 0 CLT} + {3366590400 -10800 1 CLST} + {3386545200 -14400 0 CLT} + {3398040000 -10800 1 CLST} + {3417994800 -14400 0 CLT} + {3429489600 -10800 1 CLST} + {3449444400 -14400 0 CLT} + {3460939200 -10800 1 CLST} + {3481498800 -14400 0 CLT} + {3492993600 -10800 1 CLST} + {3512948400 -14400 0 CLT} + {3524443200 -10800 1 CLST} + {3544398000 -14400 0 CLT} + {3555892800 -10800 1 CLST} + {3575847600 -14400 0 CLT} + {3587342400 -10800 1 CLST} + {3607297200 -14400 0 CLT} + {3618792000 -10800 1 CLST} + {3639351600 -14400 0 CLT} + {3650241600 -10800 1 CLST} + {3670801200 -14400 0 CLT} + {3682296000 -10800 1 CLST} + {3702250800 -14400 0 CLT} + {3713745600 -10800 1 CLST} + {3733700400 -14400 0 CLT} + {3745195200 -10800 1 CLST} + {3765150000 -14400 0 CLT} + {3776644800 -10800 1 CLST} + {3796599600 -14400 0 CLT} + {3808094400 -10800 1 CLST} + {3828654000 -14400 0 CLT} + {3839544000 -10800 1 CLST} + {3860103600 -14400 0 CLT} + {3871598400 -10800 1 CLST} + {3891553200 -14400 0 CLT} + {3903048000 -10800 1 CLST} + {3923002800 -14400 0 CLT} + {3934497600 -10800 1 CLST} + {3954452400 -14400 0 CLT} + {3965947200 -10800 1 CLST} + {3986506800 -14400 0 CLT} + {3997396800 -10800 1 CLST} + {4017956400 -14400 0 CLT} + {4029451200 -10800 1 CLST} + {4049406000 -14400 0 CLT} + {4060900800 -10800 1 CLST} + {4080855600 -14400 0 CLT} + {4092350400 -10800 1 CLST} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index 601a684..e87b171 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -77,178 +77,178 @@ set TZData(:Antarctica/Palmer) { {1313899200 -10800 1 CLST} {1335668400 -14400 0 CLT} {1346558400 -10800 1 CLST} - {1362884400 -14400 0 CLT} - {1381636800 -10800 1 CLST} - {1394334000 -14400 0 CLT} - {1413086400 -10800 1 CLST} - {1426388400 -14400 0 CLT} - {1444536000 -10800 1 CLST} - {1457838000 -14400 0 CLT} - {1475985600 -10800 1 CLST} - {1489287600 -14400 0 CLT} - {1508040000 -10800 1 CLST} - {1520737200 -14400 0 CLT} - {1539489600 -10800 1 CLST} - {1552186800 -14400 0 CLT} - {1570939200 -10800 1 CLST} - {1584241200 -14400 0 CLT} - {1602388800 -10800 1 CLST} - {1615690800 -14400 0 CLT} - {1633838400 -10800 1 CLST} - {1647140400 -14400 0 CLT} - {1665288000 -10800 1 CLST} - {1678590000 -14400 0 CLT} - {1697342400 -10800 1 CLST} - {1710039600 -14400 0 CLT} - {1728792000 -10800 1 CLST} - {1741489200 -14400 0 CLT} - {1760241600 -10800 1 CLST} - {1773543600 -14400 0 CLT} - {1791691200 -10800 1 CLST} - {1804993200 -14400 0 CLT} - {1823140800 -10800 1 CLST} - {1836442800 -14400 0 CLT} - {1855195200 -10800 1 CLST} - {1867892400 -14400 0 CLT} - {1886644800 -10800 1 CLST} - {1899342000 -14400 0 CLT} - {1918094400 -10800 1 CLST} - {1930791600 -14400 0 CLT} - {1949544000 -10800 1 CLST} - {1962846000 -14400 0 CLT} - {1980993600 -10800 1 CLST} - {1994295600 -14400 0 CLT} - {2012443200 -10800 1 CLST} - {2025745200 -14400 0 CLT} - {2044497600 -10800 1 CLST} - {2057194800 -14400 0 CLT} - {2075947200 -10800 1 CLST} - {2088644400 -14400 0 CLT} - {2107396800 -10800 1 CLST} - {2120698800 -14400 0 CLT} - {2138846400 -10800 1 CLST} - {2152148400 -14400 0 CLT} - {2170296000 -10800 1 CLST} - {2183598000 -14400 0 CLT} - {2201745600 -10800 1 CLST} - {2215047600 -14400 0 CLT} - {2233800000 -10800 1 CLST} - {2246497200 -14400 0 CLT} - {2265249600 -10800 1 CLST} - {2277946800 -14400 0 CLT} - {2296699200 -10800 1 CLST} - {2310001200 -14400 0 CLT} - {2328148800 -10800 1 CLST} - {2341450800 -14400 0 CLT} - {2359598400 -10800 1 CLST} - {2372900400 -14400 0 CLT} - {2391652800 -10800 1 CLST} - {2404350000 -14400 0 CLT} - {2423102400 -10800 1 CLST} - {2435799600 -14400 0 CLT} - {2454552000 -10800 1 CLST} - {2467854000 -14400 0 CLT} - {2486001600 -10800 1 CLST} - {2499303600 -14400 0 CLT} - {2517451200 -10800 1 CLST} - {2530753200 -14400 0 CLT} - {2548900800 -10800 1 CLST} - {2562202800 -14400 0 CLT} - {2580955200 -10800 1 CLST} - {2593652400 -14400 0 CLT} - {2612404800 -10800 1 CLST} - {2625102000 -14400 0 CLT} - {2643854400 -10800 1 CLST} - {2657156400 -14400 0 CLT} - {2675304000 -10800 1 CLST} - {2688606000 -14400 0 CLT} - {2706753600 -10800 1 CLST} - {2720055600 -14400 0 CLT} - {2738808000 -10800 1 CLST} - {2751505200 -14400 0 CLT} - {2770257600 -10800 1 CLST} - {2782954800 -14400 0 CLT} - {2801707200 -10800 1 CLST} - {2814404400 -14400 0 CLT} - {2833156800 -10800 1 CLST} - {2846458800 -14400 0 CLT} - {2864606400 -10800 1 CLST} - {2877908400 -14400 0 CLT} - {2896056000 -10800 1 CLST} - {2909358000 -14400 0 CLT} - {2928110400 -10800 1 CLST} - {2940807600 -14400 0 CLT} - {2959560000 -10800 1 CLST} - {2972257200 -14400 0 CLT} - {2991009600 -10800 1 CLST} - {3004311600 -14400 0 CLT} - {3022459200 -10800 1 CLST} - {3035761200 -14400 0 CLT} - {3053908800 -10800 1 CLST} - {3067210800 -14400 0 CLT} - {3085358400 -10800 1 CLST} - {3098660400 -14400 0 CLT} - {3117412800 -10800 1 CLST} - {3130110000 -14400 0 CLT} - {3148862400 -10800 1 CLST} - {3161559600 -14400 0 CLT} - {3180312000 -10800 1 CLST} - {3193614000 -14400 0 CLT} - {3211761600 -10800 1 CLST} - {3225063600 -14400 0 CLT} - {3243211200 -10800 1 CLST} - {3256513200 -14400 0 CLT} - {3275265600 -10800 1 CLST} - {3287962800 -14400 0 CLT} - {3306715200 -10800 1 CLST} - {3319412400 -14400 0 CLT} - {3338164800 -10800 1 CLST} - {3351466800 -14400 0 CLT} - {3369614400 -10800 1 CLST} - {3382916400 -14400 0 CLT} - {3401064000 -10800 1 CLST} - {3414366000 -14400 0 CLT} - {3432513600 -10800 1 CLST} - {3445815600 -14400 0 CLT} - {3464568000 -10800 1 CLST} - {3477265200 -14400 0 CLT} - {3496017600 -10800 1 CLST} - {3508714800 -14400 0 CLT} - {3527467200 -10800 1 CLST} - {3540769200 -14400 0 CLT} - {3558916800 -10800 1 CLST} - {3572218800 -14400 0 CLT} - {3590366400 -10800 1 CLST} - {3603668400 -14400 0 CLT} - {3622420800 -10800 1 CLST} - {3635118000 -14400 0 CLT} - {3653870400 -10800 1 CLST} - {3666567600 -14400 0 CLT} - {3685320000 -10800 1 CLST} - {3698017200 -14400 0 CLT} - {3716769600 -10800 1 CLST} - {3730071600 -14400 0 CLT} - {3748219200 -10800 1 CLST} - {3761521200 -14400 0 CLT} - {3779668800 -10800 1 CLST} - {3792970800 -14400 0 CLT} - {3811723200 -10800 1 CLST} - {3824420400 -14400 0 CLT} - {3843172800 -10800 1 CLST} - {3855870000 -14400 0 CLT} - {3874622400 -10800 1 CLST} - {3887924400 -14400 0 CLT} - {3906072000 -10800 1 CLST} - {3919374000 -14400 0 CLT} - {3937521600 -10800 1 CLST} - {3950823600 -14400 0 CLT} - {3968971200 -10800 1 CLST} - {3982273200 -14400 0 CLT} - {4001025600 -10800 1 CLST} - {4013722800 -14400 0 CLT} - {4032475200 -10800 1 CLST} - {4045172400 -14400 0 CLT} - {4063924800 -10800 1 CLST} - {4077226800 -14400 0 CLT} - {4095374400 -10800 1 CLST} + {1367118000 -14400 0 CLT} + {1378612800 -10800 1 CLST} + {1398567600 -14400 0 CLT} + {1410062400 -10800 1 CLST} + {1430017200 -14400 0 CLT} + {1441512000 -10800 1 CLST} + {1461466800 -14400 0 CLT} + {1472961600 -10800 1 CLST} + {1492916400 -14400 0 CLT} + {1504411200 -10800 1 CLST} + {1524970800 -14400 0 CLT} + {1535860800 -10800 1 CLST} + {1556420400 -14400 0 CLT} + {1567915200 -10800 1 CLST} + {1587870000 -14400 0 CLT} + {1599364800 -10800 1 CLST} + {1619319600 -14400 0 CLT} + {1630814400 -10800 1 CLST} + {1650769200 -14400 0 CLT} + {1662264000 -10800 1 CLST} + {1682218800 -14400 0 CLT} + {1693713600 -10800 1 CLST} + {1714273200 -14400 0 CLT} + {1725768000 -10800 1 CLST} + {1745722800 -14400 0 CLT} + {1757217600 -10800 1 CLST} + {1777172400 -14400 0 CLT} + {1788667200 -10800 1 CLST} + {1808622000 -14400 0 CLT} + {1820116800 -10800 1 CLST} + {1840071600 -14400 0 CLT} + {1851566400 -10800 1 CLST} + {1872126000 -14400 0 CLT} + {1883016000 -10800 1 CLST} + {1903575600 -14400 0 CLT} + {1915070400 -10800 1 CLST} + {1935025200 -14400 0 CLT} + {1946520000 -10800 1 CLST} + {1966474800 -14400 0 CLT} + {1977969600 -10800 1 CLST} + {1997924400 -14400 0 CLT} + {2009419200 -10800 1 CLST} + {2029374000 -14400 0 CLT} + {2040868800 -10800 1 CLST} + {2061428400 -14400 0 CLT} + {2072318400 -10800 1 CLST} + {2092878000 -14400 0 CLT} + {2104372800 -10800 1 CLST} + {2124327600 -14400 0 CLT} + {2135822400 -10800 1 CLST} + {2155777200 -14400 0 CLT} + {2167272000 -10800 1 CLST} + {2187226800 -14400 0 CLT} + {2198721600 -10800 1 CLST} + {2219281200 -14400 0 CLT} + {2230171200 -10800 1 CLST} + {2250730800 -14400 0 CLT} + {2262225600 -10800 1 CLST} + {2282180400 -14400 0 CLT} + {2293675200 -10800 1 CLST} + {2313630000 -14400 0 CLT} + {2325124800 -10800 1 CLST} + {2345079600 -14400 0 CLT} + {2356574400 -10800 1 CLST} + {2376529200 -14400 0 CLT} + {2388024000 -10800 1 CLST} + {2408583600 -14400 0 CLT} + {2419473600 -10800 1 CLST} + {2440033200 -14400 0 CLT} + {2451528000 -10800 1 CLST} + {2471482800 -14400 0 CLT} + {2482977600 -10800 1 CLST} + {2502932400 -14400 0 CLT} + {2514427200 -10800 1 CLST} + {2534382000 -14400 0 CLT} + {2545876800 -10800 1 CLST} + {2565831600 -14400 0 CLT} + {2577326400 -10800 1 CLST} + {2597886000 -14400 0 CLT} + {2609380800 -10800 1 CLST} + {2629335600 -14400 0 CLT} + {2640830400 -10800 1 CLST} + {2660785200 -14400 0 CLT} + {2672280000 -10800 1 CLST} + {2692234800 -14400 0 CLT} + {2703729600 -10800 1 CLST} + {2723684400 -14400 0 CLT} + {2735179200 -10800 1 CLST} + {2755738800 -14400 0 CLT} + {2766628800 -10800 1 CLST} + {2787188400 -14400 0 CLT} + {2798683200 -10800 1 CLST} + {2818638000 -14400 0 CLT} + {2830132800 -10800 1 CLST} + {2850087600 -14400 0 CLT} + {2861582400 -10800 1 CLST} + {2881537200 -14400 0 CLT} + {2893032000 -10800 1 CLST} + {2912986800 -14400 0 CLT} + {2924481600 -10800 1 CLST} + {2945041200 -14400 0 CLT} + {2955931200 -10800 1 CLST} + {2976490800 -14400 0 CLT} + {2987985600 -10800 1 CLST} + {3007940400 -14400 0 CLT} + {3019435200 -10800 1 CLST} + {3039390000 -14400 0 CLT} + {3050884800 -10800 1 CLST} + {3070839600 -14400 0 CLT} + {3082334400 -10800 1 CLST} + {3102894000 -14400 0 CLT} + {3113784000 -10800 1 CLST} + {3134343600 -14400 0 CLT} + {3145838400 -10800 1 CLST} + {3165793200 -14400 0 CLT} + {3177288000 -10800 1 CLST} + {3197242800 -14400 0 CLT} + {3208737600 -10800 1 CLST} + {3228692400 -14400 0 CLT} + {3240187200 -10800 1 CLST} + {3260142000 -14400 0 CLT} + {3271636800 -10800 1 CLST} + {3292196400 -14400 0 CLT} + {3303086400 -10800 1 CLST} + {3323646000 -14400 0 CLT} + {3335140800 -10800 1 CLST} + {3355095600 -14400 0 CLT} + {3366590400 -10800 1 CLST} + {3386545200 -14400 0 CLT} + {3398040000 -10800 1 CLST} + {3417994800 -14400 0 CLT} + {3429489600 -10800 1 CLST} + {3449444400 -14400 0 CLT} + {3460939200 -10800 1 CLST} + {3481498800 -14400 0 CLT} + {3492993600 -10800 1 CLST} + {3512948400 -14400 0 CLT} + {3524443200 -10800 1 CLST} + {3544398000 -14400 0 CLT} + {3555892800 -10800 1 CLST} + {3575847600 -14400 0 CLT} + {3587342400 -10800 1 CLST} + {3607297200 -14400 0 CLT} + {3618792000 -10800 1 CLST} + {3639351600 -14400 0 CLT} + {3650241600 -10800 1 CLST} + {3670801200 -14400 0 CLT} + {3682296000 -10800 1 CLST} + {3702250800 -14400 0 CLT} + {3713745600 -10800 1 CLST} + {3733700400 -14400 0 CLT} + {3745195200 -10800 1 CLST} + {3765150000 -14400 0 CLT} + {3776644800 -10800 1 CLST} + {3796599600 -14400 0 CLT} + {3808094400 -10800 1 CLST} + {3828654000 -14400 0 CLT} + {3839544000 -10800 1 CLST} + {3860103600 -14400 0 CLT} + {3871598400 -10800 1 CLST} + {3891553200 -14400 0 CLT} + {3903048000 -10800 1 CLST} + {3923002800 -14400 0 CLT} + {3934497600 -10800 1 CLST} + {3954452400 -14400 0 CLT} + {3965947200 -10800 1 CLST} + {3986506800 -14400 0 CLT} + {3997396800 -10800 1 CLST} + {4017956400 -14400 0 CLT} + {4029451200 -10800 1 CLST} + {4049406000 -14400 0 CLT} + {4060900800 -10800 1 CLST} + {4080855600 -14400 0 CLT} + {4092350400 -10800 1 CLST} } diff --git a/library/tzdata/Asia/Aden b/library/tzdata/Asia/Aden index e939235..399d9f0 100644 --- a/library/tzdata/Asia/Aden +++ b/library/tzdata/Asia/Aden @@ -1,6 +1,6 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Aden) { - {-9223372036854775808 10848 0 LMT} - {-631162848 10800 0 AST} + {-9223372036854775808 10794 0 LMT} + {-631162794 10800 0 AST} } diff --git a/library/tzdata/Asia/Hong_Kong b/library/tzdata/Asia/Hong_Kong index 928cde6..fcf98a6 100644 --- a/library/tzdata/Asia/Hong_Kong +++ b/library/tzdata/Asia/Hong_Kong @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Hong_Kong) { - {-9223372036854775808 27396 0 LMT} - {-2056692996 28800 0 HKT} + {-9223372036854775808 27402 0 LMT} + {-2056693002 28800 0 HKT} {-907389000 32400 1 HKST} {-891667800 28800 0 HKT} {-884246400 32400 0 JST} diff --git a/library/tzdata/Asia/Khandyga b/library/tzdata/Asia/Khandyga new file mode 100644 index 0000000..2464b9f --- /dev/null +++ b/library/tzdata/Asia/Khandyga @@ -0,0 +1,72 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Asia/Khandyga) { + {-9223372036854775808 32533 0 LMT} + {-1579424533 28800 0 YAKT} + {-1247558400 32400 0 YAKMMTT} + {354898800 36000 1 YAKST} + {370706400 32400 0 YAKT} + {386434800 36000 1 YAKST} + {402242400 32400 0 YAKT} + {417970800 36000 1 YAKST} + {433778400 32400 0 YAKT} + {449593200 36000 1 YAKST} + {465325200 32400 0 YAKT} + {481050000 36000 1 YAKST} + {496774800 32400 0 YAKT} + {512499600 36000 1 YAKST} + {528224400 32400 0 YAKT} + {543949200 36000 1 YAKST} + {559674000 32400 0 YAKT} + {575398800 36000 1 YAKST} + {591123600 32400 0 YAKT} + {606848400 36000 1 YAKST} + {622573200 32400 0 YAKT} + {638298000 36000 1 YAKST} + {654627600 32400 0 YAKT} + {670352400 28800 0 YAKMMTT} + {670356000 32400 1 YAKST} + {686080800 28800 0 YAKT} + {695757600 32400 0 YAKMMTT} + {701791200 36000 1 YAKST} + {717512400 32400 0 YAKT} + {733251600 36000 1 YAKST} + {748976400 32400 0 YAKT} + {764701200 36000 1 YAKST} + {780426000 32400 0 YAKT} + {796150800 36000 1 YAKST} + {811875600 32400 0 YAKT} + {828205200 36000 1 YAKST} + {846349200 32400 0 YAKT} + {859654800 36000 1 YAKST} + {877798800 32400 0 YAKT} + {891104400 36000 1 YAKST} + {909248400 32400 0 YAKT} + {922554000 36000 1 YAKST} + {941302800 32400 0 YAKT} + {954003600 36000 1 YAKST} + {972752400 32400 0 YAKT} + {985453200 36000 1 YAKST} + {1004202000 32400 0 YAKT} + {1017507600 36000 1 YAKST} + {1035651600 32400 0 YAKT} + {1048957200 36000 1 YAKST} + {1067101200 32400 0 YAKT} + {1072882800 36000 0 VLAMMTT} + {1080403200 39600 1 VLAST} + {1099152000 36000 0 VLAT} + {1111852800 39600 1 VLAST} + {1130601600 36000 0 VLAT} + {1143302400 39600 1 VLAST} + {1162051200 36000 0 VLAT} + {1174752000 39600 1 VLAST} + {1193500800 36000 0 VLAT} + {1206806400 39600 1 VLAST} + {1224950400 36000 0 VLAT} + {1238256000 39600 1 VLAST} + {1256400000 36000 0 VLAT} + {1269705600 39600 1 VLAST} + {1288454400 36000 0 VLAT} + {1301155200 39600 0 VLAT} + {1315832400 36000 0 YAKT} +} diff --git a/library/tzdata/Asia/Muscat b/library/tzdata/Asia/Muscat index 21b5873..a69b880 100644 --- a/library/tzdata/Asia/Muscat +++ b/library/tzdata/Asia/Muscat @@ -1,6 +1,6 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Muscat) { - {-9223372036854775808 14060 0 LMT} - {-1577937260 14400 0 GST} + {-9223372036854775808 14064 0 LMT} + {-1577937264 14400 0 GST} } diff --git a/library/tzdata/Asia/Rangoon b/library/tzdata/Asia/Rangoon index 2b8c4fa..4f3ac02 100644 --- a/library/tzdata/Asia/Rangoon +++ b/library/tzdata/Asia/Rangoon @@ -2,8 +2,8 @@ set TZData(:Asia/Rangoon) { {-9223372036854775808 23080 0 LMT} - {-2840163880 23076 0 RMT} - {-1577946276 23400 0 BURT} + {-2840163880 23080 0 RMT} + {-1577946280 23400 0 BURT} {-873268200 32400 0 JST} {-778410000 23400 0 MMT} } diff --git a/library/tzdata/Asia/Shanghai b/library/tzdata/Asia/Shanghai index aa7dc58..4b3cc3b 100644 --- a/library/tzdata/Asia/Shanghai +++ b/library/tzdata/Asia/Shanghai @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Shanghai) { - {-9223372036854775808 29152 0 LMT} - {-1325491552 28800 0 CST} + {-9223372036854775808 29157 0 LMT} + {-1325491557 28800 0 CST} {-933494400 32400 1 CDT} {-923130000 28800 0 CST} {-908784000 32400 1 CDT} diff --git a/library/tzdata/Asia/Ust-Nera b/library/tzdata/Asia/Ust-Nera new file mode 100644 index 0000000..c8de7a5 --- /dev/null +++ b/library/tzdata/Asia/Ust-Nera @@ -0,0 +1,70 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Asia/Ust-Nera) { + {-9223372036854775808 34374 0 LMT} + {-1579426374 28800 0 YAKT} + {354898800 43200 0 MAGST} + {370699200 39600 0 MAGT} + {386427600 43200 1 MAGST} + {402235200 39600 0 MAGT} + {417963600 43200 1 MAGST} + {433771200 39600 0 MAGT} + {449586000 43200 1 MAGST} + {465318000 39600 0 MAGT} + {481042800 43200 1 MAGST} + {496767600 39600 0 MAGT} + {512492400 43200 1 MAGST} + {528217200 39600 0 MAGT} + {543942000 43200 1 MAGST} + {559666800 39600 0 MAGT} + {575391600 43200 1 MAGST} + {591116400 39600 0 MAGT} + {606841200 43200 1 MAGST} + {622566000 39600 0 MAGT} + {638290800 43200 1 MAGST} + {654620400 39600 0 MAGT} + {670345200 36000 0 MAGMMTT} + {670348800 39600 1 MAGST} + {686073600 36000 0 MAGT} + {695750400 39600 0 MAGMMTT} + {701784000 43200 1 MAGST} + {717505200 39600 0 MAGT} + {733244400 43200 1 MAGST} + {748969200 39600 0 MAGT} + {764694000 43200 1 MAGST} + {780418800 39600 0 MAGT} + {796143600 43200 1 MAGST} + {811868400 39600 0 MAGT} + {828198000 43200 1 MAGST} + {846342000 39600 0 MAGT} + {859647600 43200 1 MAGST} + {877791600 39600 0 MAGT} + {891097200 43200 1 MAGST} + {909241200 39600 0 MAGT} + {922546800 43200 1 MAGST} + {941295600 39600 0 MAGT} + {953996400 43200 1 MAGST} + {972745200 39600 0 MAGT} + {985446000 43200 1 MAGST} + {1004194800 39600 0 MAGT} + {1017500400 43200 1 MAGST} + {1035644400 39600 0 MAGT} + {1048950000 43200 1 MAGST} + {1067094000 39600 0 MAGT} + {1080399600 43200 1 MAGST} + {1099148400 39600 0 MAGT} + {1111849200 43200 1 MAGST} + {1130598000 39600 0 MAGT} + {1143298800 43200 1 MAGST} + {1162047600 39600 0 MAGT} + {1174748400 43200 1 MAGST} + {1193497200 39600 0 MAGT} + {1206802800 43200 1 MAGST} + {1224946800 39600 0 MAGT} + {1238252400 43200 1 MAGST} + {1256396400 39600 0 MAGT} + {1269702000 43200 1 MAGST} + {1288450800 39600 0 MAGT} + {1301151600 43200 0 MAGT} + {1315828800 39600 0 VLAT} +} diff --git a/library/tzdata/Atlantic/Bermuda b/library/tzdata/Atlantic/Bermuda index e8b165a..2d4d983 100644 --- a/library/tzdata/Atlantic/Bermuda +++ b/library/tzdata/Atlantic/Bermuda @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Atlantic/Bermuda) { - {-9223372036854775808 -15544 0 LMT} - {-1262281256 -14400 0 AST} + {-9223372036854775808 -15558 0 LMT} + {-1262281242 -14400 0 AST} {136360800 -10800 0 ADT} {152082000 -14400 0 AST} {167810400 -10800 1 ADT} diff --git a/library/tzdata/Europe/Busingen b/library/tzdata/Europe/Busingen new file mode 100644 index 0000000..62abc29 --- /dev/null +++ b/library/tzdata/Europe/Busingen @@ -0,0 +1,5 @@ +# created by tools/tclZIC.tcl - do not edit +if {![info exists TZData(Europe/Zurich)]} { + LoadTimeZoneFile Europe/Zurich +} +set TZData(:Europe/Busingen) $TZData(:Europe/Zurich) diff --git a/library/tzdata/Europe/Vienna b/library/tzdata/Europe/Vienna index 41d744d..95283eb 100644 --- a/library/tzdata/Europe/Vienna +++ b/library/tzdata/Europe/Vienna @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Vienna) { - {-9223372036854775808 3920 0 LMT} - {-2422055120 3600 0 CET} + {-9223372036854775808 3921 0 LMT} + {-2422055121 3600 0 CET} {-1693706400 7200 1 CEST} {-1680483600 3600 0 CET} {-1663455600 7200 1 CEST} diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index 38795fb..000c6d1 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -98,178 +98,178 @@ set TZData(:Pacific/Easter) { {1313899200 -18000 1 EASST} {1335668400 -21600 0 EAST} {1346558400 -18000 1 EASST} - {1362884400 -21600 0 EAST} - {1381636800 -18000 1 EASST} - {1394334000 -21600 0 EAST} - {1413086400 -18000 1 EASST} - {1426388400 -21600 0 EAST} - {1444536000 -18000 1 EASST} - {1457838000 -21600 0 EAST} - {1475985600 -18000 1 EASST} - {1489287600 -21600 0 EAST} - {1508040000 -18000 1 EASST} - {1520737200 -21600 0 EAST} - {1539489600 -18000 1 EASST} - {1552186800 -21600 0 EAST} - {1570939200 -18000 1 EASST} - {1584241200 -21600 0 EAST} - {1602388800 -18000 1 EASST} - {1615690800 -21600 0 EAST} - {1633838400 -18000 1 EASST} - {1647140400 -21600 0 EAST} - {1665288000 -18000 1 EASST} - {1678590000 -21600 0 EAST} - {1697342400 -18000 1 EASST} - {1710039600 -21600 0 EAST} - {1728792000 -18000 1 EASST} - {1741489200 -21600 0 EAST} - {1760241600 -18000 1 EASST} - {1773543600 -21600 0 EAST} - {1791691200 -18000 1 EASST} - {1804993200 -21600 0 EAST} - {1823140800 -18000 1 EASST} - {1836442800 -21600 0 EAST} - {1855195200 -18000 1 EASST} - {1867892400 -21600 0 EAST} - {1886644800 -18000 1 EASST} - {1899342000 -21600 0 EAST} - {1918094400 -18000 1 EASST} - {1930791600 -21600 0 EAST} - {1949544000 -18000 1 EASST} - {1962846000 -21600 0 EAST} - {1980993600 -18000 1 EASST} - {1994295600 -21600 0 EAST} - {2012443200 -18000 1 EASST} - {2025745200 -21600 0 EAST} - {2044497600 -18000 1 EASST} - {2057194800 -21600 0 EAST} - {2075947200 -18000 1 EASST} - {2088644400 -21600 0 EAST} - {2107396800 -18000 1 EASST} - {2120698800 -21600 0 EAST} - {2138846400 -18000 1 EASST} - {2152148400 -21600 0 EAST} - {2170296000 -18000 1 EASST} - {2183598000 -21600 0 EAST} - {2201745600 -18000 1 EASST} - {2215047600 -21600 0 EAST} - {2233800000 -18000 1 EASST} - {2246497200 -21600 0 EAST} - {2265249600 -18000 1 EASST} - {2277946800 -21600 0 EAST} - {2296699200 -18000 1 EASST} - {2310001200 -21600 0 EAST} - {2328148800 -18000 1 EASST} - {2341450800 -21600 0 EAST} - {2359598400 -18000 1 EASST} - {2372900400 -21600 0 EAST} - {2391652800 -18000 1 EASST} - {2404350000 -21600 0 EAST} - {2423102400 -18000 1 EASST} - {2435799600 -21600 0 EAST} - {2454552000 -18000 1 EASST} - {2467854000 -21600 0 EAST} - {2486001600 -18000 1 EASST} - {2499303600 -21600 0 EAST} - {2517451200 -18000 1 EASST} - {2530753200 -21600 0 EAST} - {2548900800 -18000 1 EASST} - {2562202800 -21600 0 EAST} - {2580955200 -18000 1 EASST} - {2593652400 -21600 0 EAST} - {2612404800 -18000 1 EASST} - {2625102000 -21600 0 EAST} - {2643854400 -18000 1 EASST} - {2657156400 -21600 0 EAST} - {2675304000 -18000 1 EASST} - {2688606000 -21600 0 EAST} - {2706753600 -18000 1 EASST} - {2720055600 -21600 0 EAST} - {2738808000 -18000 1 EASST} - {2751505200 -21600 0 EAST} - {2770257600 -18000 1 EASST} - {2782954800 -21600 0 EAST} - {2801707200 -18000 1 EASST} - {2814404400 -21600 0 EAST} - {2833156800 -18000 1 EASST} - {2846458800 -21600 0 EAST} - {2864606400 -18000 1 EASST} - {2877908400 -21600 0 EAST} - {2896056000 -18000 1 EASST} - {2909358000 -21600 0 EAST} - {2928110400 -18000 1 EASST} - {2940807600 -21600 0 EAST} - {2959560000 -18000 1 EASST} - {2972257200 -21600 0 EAST} - {2991009600 -18000 1 EASST} - {3004311600 -21600 0 EAST} - {3022459200 -18000 1 EASST} - {3035761200 -21600 0 EAST} - {3053908800 -18000 1 EASST} - {3067210800 -21600 0 EAST} - {3085358400 -18000 1 EASST} - {3098660400 -21600 0 EAST} - {3117412800 -18000 1 EASST} - {3130110000 -21600 0 EAST} - {3148862400 -18000 1 EASST} - {3161559600 -21600 0 EAST} - {3180312000 -18000 1 EASST} - {3193614000 -21600 0 EAST} - {3211761600 -18000 1 EASST} - {3225063600 -21600 0 EAST} - {3243211200 -18000 1 EASST} - {3256513200 -21600 0 EAST} - {3275265600 -18000 1 EASST} - {3287962800 -21600 0 EAST} - {3306715200 -18000 1 EASST} - {3319412400 -21600 0 EAST} - {3338164800 -18000 1 EASST} - {3351466800 -21600 0 EAST} - {3369614400 -18000 1 EASST} - {3382916400 -21600 0 EAST} - {3401064000 -18000 1 EASST} - {3414366000 -21600 0 EAST} - {3432513600 -18000 1 EASST} - {3445815600 -21600 0 EAST} - {3464568000 -18000 1 EASST} - {3477265200 -21600 0 EAST} - {3496017600 -18000 1 EASST} - {3508714800 -21600 0 EAST} - {3527467200 -18000 1 EASST} - {3540769200 -21600 0 EAST} - {3558916800 -18000 1 EASST} - {3572218800 -21600 0 EAST} - {3590366400 -18000 1 EASST} - {3603668400 -21600 0 EAST} - {3622420800 -18000 1 EASST} - {3635118000 -21600 0 EAST} - {3653870400 -18000 1 EASST} - {3666567600 -21600 0 EAST} - {3685320000 -18000 1 EASST} - {3698017200 -21600 0 EAST} - {3716769600 -18000 1 EASST} - {3730071600 -21600 0 EAST} - {3748219200 -18000 1 EASST} - {3761521200 -21600 0 EAST} - {3779668800 -18000 1 EASST} - {3792970800 -21600 0 EAST} - {3811723200 -18000 1 EASST} - {3824420400 -21600 0 EAST} - {3843172800 -18000 1 EASST} - {3855870000 -21600 0 EAST} - {3874622400 -18000 1 EASST} - {3887924400 -21600 0 EAST} - {3906072000 -18000 1 EASST} - {3919374000 -21600 0 EAST} - {3937521600 -18000 1 EASST} - {3950823600 -21600 0 EAST} - {3968971200 -18000 1 EASST} - {3982273200 -21600 0 EAST} - {4001025600 -18000 1 EASST} - {4013722800 -21600 0 EAST} - {4032475200 -18000 1 EASST} - {4045172400 -21600 0 EAST} - {4063924800 -18000 1 EASST} - {4077226800 -21600 0 EAST} - {4095374400 -18000 1 EASST} + {1367118000 -21600 0 EAST} + {1378612800 -18000 1 EASST} + {1398567600 -21600 0 EAST} + {1410062400 -18000 1 EASST} + {1430017200 -21600 0 EAST} + {1441512000 -18000 1 EASST} + {1461466800 -21600 0 EAST} + {1472961600 -18000 1 EASST} + {1492916400 -21600 0 EAST} + {1504411200 -18000 1 EASST} + {1524970800 -21600 0 EAST} + {1535860800 -18000 1 EASST} + {1556420400 -21600 0 EAST} + {1567915200 -18000 1 EASST} + {1587870000 -21600 0 EAST} + {1599364800 -18000 1 EASST} + {1619319600 -21600 0 EAST} + {1630814400 -18000 1 EASST} + {1650769200 -21600 0 EAST} + {1662264000 -18000 1 EASST} + {1682218800 -21600 0 EAST} + {1693713600 -18000 1 EASST} + {1714273200 -21600 0 EAST} + {1725768000 -18000 1 EASST} + {1745722800 -21600 0 EAST} + {1757217600 -18000 1 EASST} + {1777172400 -21600 0 EAST} + {1788667200 -18000 1 EASST} + {1808622000 -21600 0 EAST} + {1820116800 -18000 1 EASST} + {1840071600 -21600 0 EAST} + {1851566400 -18000 1 EASST} + {1872126000 -21600 0 EAST} + {1883016000 -18000 1 EASST} + {1903575600 -21600 0 EAST} + {1915070400 -18000 1 EASST} + {1935025200 -21600 0 EAST} + {1946520000 -18000 1 EASST} + {1966474800 -21600 0 EAST} + {1977969600 -18000 1 EASST} + {1997924400 -21600 0 EAST} + {2009419200 -18000 1 EASST} + {2029374000 -21600 0 EAST} + {2040868800 -18000 1 EASST} + {2061428400 -21600 0 EAST} + {2072318400 -18000 1 EASST} + {2092878000 -21600 0 EAST} + {2104372800 -18000 1 EASST} + {2124327600 -21600 0 EAST} + {2135822400 -18000 1 EASST} + {2155777200 -21600 0 EAST} + {2167272000 -18000 1 EASST} + {2187226800 -21600 0 EAST} + {2198721600 -18000 1 EASST} + {2219281200 -21600 0 EAST} + {2230171200 -18000 1 EASST} + {2250730800 -21600 0 EAST} + {2262225600 -18000 1 EASST} + {2282180400 -21600 0 EAST} + {2293675200 -18000 1 EASST} + {2313630000 -21600 0 EAST} + {2325124800 -18000 1 EASST} + {2345079600 -21600 0 EAST} + {2356574400 -18000 1 EASST} + {2376529200 -21600 0 EAST} + {2388024000 -18000 1 EASST} + {2408583600 -21600 0 EAST} + {2419473600 -18000 1 EASST} + {2440033200 -21600 0 EAST} + {2451528000 -18000 1 EASST} + {2471482800 -21600 0 EAST} + {2482977600 -18000 1 EASST} + {2502932400 -21600 0 EAST} + {2514427200 -18000 1 EASST} + {2534382000 -21600 0 EAST} + {2545876800 -18000 1 EASST} + {2565831600 -21600 0 EAST} + {2577326400 -18000 1 EASST} + {2597886000 -21600 0 EAST} + {2609380800 -18000 1 EASST} + {2629335600 -21600 0 EAST} + {2640830400 -18000 1 EASST} + {2660785200 -21600 0 EAST} + {2672280000 -18000 1 EASST} + {2692234800 -21600 0 EAST} + {2703729600 -18000 1 EASST} + {2723684400 -21600 0 EAST} + {2735179200 -18000 1 EASST} + {2755738800 -21600 0 EAST} + {2766628800 -18000 1 EASST} + {2787188400 -21600 0 EAST} + {2798683200 -18000 1 EASST} + {2818638000 -21600 0 EAST} + {2830132800 -18000 1 EASST} + {2850087600 -21600 0 EAST} + {2861582400 -18000 1 EASST} + {2881537200 -21600 0 EAST} + {2893032000 -18000 1 EASST} + {2912986800 -21600 0 EAST} + {2924481600 -18000 1 EASST} + {2945041200 -21600 0 EAST} + {2955931200 -18000 1 EASST} + {2976490800 -21600 0 EAST} + {2987985600 -18000 1 EASST} + {3007940400 -21600 0 EAST} + {3019435200 -18000 1 EASST} + {3039390000 -21600 0 EAST} + {3050884800 -18000 1 EASST} + {3070839600 -21600 0 EAST} + {3082334400 -18000 1 EASST} + {3102894000 -21600 0 EAST} + {3113784000 -18000 1 EASST} + {3134343600 -21600 0 EAST} + {3145838400 -18000 1 EASST} + {3165793200 -21600 0 EAST} + {3177288000 -18000 1 EASST} + {3197242800 -21600 0 EAST} + {3208737600 -18000 1 EASST} + {3228692400 -21600 0 EAST} + {3240187200 -18000 1 EASST} + {3260142000 -21600 0 EAST} + {3271636800 -18000 1 EASST} + {3292196400 -21600 0 EAST} + {3303086400 -18000 1 EASST} + {3323646000 -21600 0 EAST} + {3335140800 -18000 1 EASST} + {3355095600 -21600 0 EAST} + {3366590400 -18000 1 EASST} + {3386545200 -21600 0 EAST} + {3398040000 -18000 1 EASST} + {3417994800 -21600 0 EAST} + {3429489600 -18000 1 EASST} + {3449444400 -21600 0 EAST} + {3460939200 -18000 1 EASST} + {3481498800 -21600 0 EAST} + {3492993600 -18000 1 EASST} + {3512948400 -21600 0 EAST} + {3524443200 -18000 1 EASST} + {3544398000 -21600 0 EAST} + {3555892800 -18000 1 EASST} + {3575847600 -21600 0 EAST} + {3587342400 -18000 1 EASST} + {3607297200 -21600 0 EAST} + {3618792000 -18000 1 EASST} + {3639351600 -21600 0 EAST} + {3650241600 -18000 1 EASST} + {3670801200 -21600 0 EAST} + {3682296000 -18000 1 EASST} + {3702250800 -21600 0 EAST} + {3713745600 -18000 1 EASST} + {3733700400 -21600 0 EAST} + {3745195200 -18000 1 EASST} + {3765150000 -21600 0 EAST} + {3776644800 -18000 1 EASST} + {3796599600 -21600 0 EAST} + {3808094400 -18000 1 EASST} + {3828654000 -21600 0 EAST} + {3839544000 -18000 1 EASST} + {3860103600 -21600 0 EAST} + {3871598400 -18000 1 EASST} + {3891553200 -21600 0 EAST} + {3903048000 -18000 1 EASST} + {3923002800 -21600 0 EAST} + {3934497600 -18000 1 EASST} + {3954452400 -21600 0 EAST} + {3965947200 -18000 1 EASST} + {3986506800 -21600 0 EAST} + {3997396800 -18000 1 EASST} + {4017956400 -21600 0 EAST} + {4029451200 -18000 1 EASST} + {4049406000 -21600 0 EAST} + {4060900800 -18000 1 EASST} + {4080855600 -21600 0 EAST} + {4092350400 -18000 1 EASST} } diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index e067377..bfcaa03 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Pacific/Fiji) { - {-9223372036854775808 42820 0 LMT} - {-1709985220 43200 0 FJT} + {-9223372036854775808 42944 0 LMT} + {-1709985344 43200 0 FJT} {909842400 46800 1 FJST} {920124000 43200 0 FJT} {941896800 46800 1 FJST} diff --git a/library/word.tcl b/library/word.tcl index 16a4638..b8f34a5 100644 --- a/library/word.tcl +++ b/library/word.tcl @@ -67,7 +67,7 @@ namespace eval ::tcl { proc tcl_wordBreakAfter {str start} { variable ::tcl::WordBreakRE set result {-1 -1} - regexp -indices -start $start $WordBreakRE(after) $str result + regexp -indices -start $start -- $WordBreakRE(after) $str result return [lindex $result 1] } @@ -85,7 +85,7 @@ proc tcl_wordBreakAfter {str start} { proc tcl_wordBreakBefore {str start} { variable ::tcl::WordBreakRE set result {-1 -1} - regexp -indices $WordBreakRE(before) [string range $str 0 $start] result + regexp -indices -- $WordBreakRE(before) [string range $str 0 $start] result return [lindex $result 1] } @@ -104,7 +104,7 @@ proc tcl_wordBreakBefore {str start} { proc tcl_endOfWord {str start} { variable ::tcl::WordBreakRE set result {-1 -1} - regexp -indices -start $start $WordBreakRE(end) $str result + regexp -indices -start $start -- $WordBreakRE(end) $str result return [lindex $result 1] } @@ -122,7 +122,7 @@ proc tcl_endOfWord {str start} { proc tcl_startOfNextWord {str start} { variable ::tcl::WordBreakRE set result {-1 -1} - regexp -indices -start $start $WordBreakRE(next) $str result + regexp -indices -start $start -- $WordBreakRE(next) $str result return [lindex $result 1] } @@ -138,7 +138,7 @@ proc tcl_startOfNextWord {str start} { proc tcl_startOfPreviousWord {str start} { variable ::tcl::WordBreakRE set word {-1 -1} - regexp -indices $WordBreakRE(previous) [string range $str 0 $start-1] \ + regexp -indices -- $WordBreakRE(previous) [string range $str 0 $start-1] \ result word return [lindex $word 0] } diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c index f266443..8ecfd0b 100644 --- a/macosx/tclMacOSXFCmd.c +++ b/macosx/tclMacOSXFCmd.c @@ -578,7 +578,7 @@ GetOSTypeFromObj( int result = TCL_OK; if (objPtr->typePtr != &tclOSTypeType) { - result = tclOSTypeType.setFromAnyProc(interp, objPtr); + result = SetOSTypeFromAny(interp, objPtr); } *osTypePtr = (OSType) objPtr->internalRep.longValue; return result; @@ -608,7 +608,7 @@ NewOSTypeObj( Tcl_Obj *objPtr; TclNewObj(objPtr); - Tcl_InvalidateStringRep(objPtr); + TclInvalidateStringRep(objPtr); objPtr->internalRep.longValue = (long) osType; objPtr->typePtr = &tclOSTypeType; return objPtr; diff --git a/tests/assocd.test b/tests/assocd.test index d1489b3..edf55c4 100644 --- a/tests/assocd.test +++ b/tests/assocd.test @@ -11,10 +11,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -36,15 +34,21 @@ test assocd-1.4 {testing setting assoc data} testsetassocdata { testsetassocdata abc "abc d e f" } "" -test assocd-2.1 {testing getting assoc data} testgetassocdata { - testgetassocdata a -} 2 -test assocd-2.2 {testing getting assoc data} testgetassocdata { - testgetassocdata 123 -} 456 -test assocd-2.3 {testing getting assoc data} testgetassocdata { +test assocd-2.1 {testing getting assoc data} -setup { + testsetassocdata a 2 +} -constraints {testgetassocdata} -body { + testgetassocdata a +} -result 2 +test assocd-2.2 {testing getting assoc data} -setup { + testsetassocdata 123 456 +} -constraints {testgetassocdata} -body { + testgetassocdata 123 +} -result 456 +test assocd-2.3 {testing getting assoc data} -setup { + testsetassocdata abc "abc d e f" +} -constraints {testgetassocdata} -body { testgetassocdata abc -} {abc d e f} +} -result "abc d e f" test assocd-2.4 {testing getting assoc data} testgetassocdata { testgetassocdata xxx } "" @@ -60,5 +64,5 @@ test assocd-3.3 {testing deleting assoc data} testdelassocdata { } {0 {}} # cleanup -::tcltest::cleanupTests +cleanupTests return diff --git a/tests/autoMkindex.test b/tests/autoMkindex.test index 8f29131..4721553 100644 --- a/tests/autoMkindex.test +++ b/tests/autoMkindex.test @@ -236,6 +236,38 @@ test autoMkindex-3.3 {auto_mkindex_parser::command} -setup { # Reset initCommands to avoid trashing other tests AutoMkindexTestReset } -result "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}" +makeFile { + +namespace eval wok { + namespace ensemble create -subcommands {commands vars} + + proc commands {{pattern *}} { + puts [join [lsort -dictionary [info commands $pattern]] \n] + } + + proc vars {{pattern *}} { + puts [join [lsort -dictionary [info vars $pattern]] \n] + } + +} + +} ensemblecommands.tcl + +test autoMkindex-3.4 {ensemble commands in tclIndex} { + file delete tclIndex + auto_mkindex . ensemblecommands.tcl + set f [open tclIndex r] + set dat [list] + foreach r [split [string trim [read $f]] "\n"] { + if {[string match {set auto_index*} $r]} { + lappend dat $r + } + } + set result [lsort $dat] + close $f + set result +} {{set auto_index(::wok::commands) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(::wok::vars) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(wok) [list source [file join $dir ensemblecommands.tcl]]}} +removeFile ensemblecommands.tcl test autoMkindex-4.1 {platform independent source commands} -setup { file delete tclIndex diff --git a/tests/basic.test b/tests/basic.test index 7435571..1a0037c 100644 --- a/tests/basic.test +++ b/tests/basic.test @@ -16,7 +16,7 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 -namespace import -force ::tcltest::* +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -31,7 +31,7 @@ catch {interp delete test_interp} catch {rename p ""} catch {rename q ""} catch {rename cmd ""} -catch {unset x} +unset -nocomplain x test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} { catch {interp delete test_interp} @@ -267,14 +267,24 @@ test basic-18.4 {TclRenameCommand, bad new name} { } rename test_ns_basic::p :::george::martha } {} -test basic-18.5 {TclRenameCommand, new name must not already exist} { +test basic-18.5 {TclRenameCommand, new name must not already exist} -setup { + if {![llength [info commands :::george::martha]]} { + catch {namespace delete {*}[namespace children :: test_ns_*]} + namespace eval test_ns_basic { + proc p {} { + return "p in [namespace current]" + } + } + rename test_ns_basic::p :::george::martha + } +} -body { namespace eval test_ns_basic { proc q {} { return 42 } } list [catch {rename test_ns_basic::q :::george::martha} msg] $msg -} {1 {can't rename to ":::george::martha": command already exists}} +} -result {1 {can't rename to ":::george::martha": command already exists}} test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} { catch {namespace delete {*}[namespace children :: test_ns_*]} catch {rename p ""} @@ -302,7 +312,7 @@ test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespace catch {namespace delete {*}[namespace children :: test_ns_*]} catch {rename p ""} catch {rename q ""} - catch {unset x} + unset -nocomplain x set x [namespace eval test_ns_basic::test_ns_basic2 { # the following creates a cmd in the global namespace testcmdtoken create p @@ -355,7 +365,7 @@ test basic-23.1 {Tcl_DeleteCommand} {emptyTest} { test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} { catch {interp delete test_interp} - catch {unset x} + unset -nocomplain x interp create test_interp interp eval test_interp { proc useSet {} { @@ -427,7 +437,7 @@ test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup { # string would have been freed, leaving garbage bytes for the error # message. set f [open $fName w] - fileevent $f writable "fileevent $f writable {}; error foo" + chan event $f writable "chan event $f writable {}; error foo" set x {} vwait x close $f @@ -547,8 +557,8 @@ test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} { catch {close $f} set res [catch { set f [open |[list [interpreter]] w+] - fconfigure $f -buffering line - puts $f {fconfigure stdout -buffering line} + chan configure $f -buffering line + puts $f {chan configure stdout -buffering line} puts $f continue puts $f {puts $::errorInfo} puts $f {puts DONE} @@ -972,6 +982,6 @@ catch {rename p ""} catch {rename q ""} catch {rename cmd ""} catch {rename value:at: ""} -catch {unset x} -::tcltest::cleanupTests +unset -nocomplain x +cleanupTests return diff --git a/tests/binary.test b/tests/binary.test index ccd0f29..4393245 100644 --- a/tests/binary.test +++ b/tests/binary.test @@ -1582,38 +1582,46 @@ test binary-40.4 {ScanNumber: NaN} -body { list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1 } -match glob -result {1 -NaN*} -test binary-41.1 {ScanNumber: word alignment} { - unset -nocomplain arg1; unset arg2 +test binary-41.1 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -body { list [binary scan \x01\x01\x00 c1s1 arg1 arg2] $arg1 $arg2 -} {2 1 1} -test binary-41.2 {ScanNumber: word alignment} { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1} +test binary-41.2 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -body { list [binary scan \x01\x00\x01 c1S1 arg1 arg2] $arg1 $arg2 -} {2 1 1} -test binary-41.3 {ScanNumber: word alignment} { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1} +test binary-41.3 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -body { list [binary scan \x01\x01\x00\x00\x00 c1i1 arg1 arg2] $arg1 $arg2 -} {2 1 1} -test binary-41.4 {ScanNumber: word alignment} { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1} +test binary-41.4 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -body { list [binary scan \x01\x00\x00\x00\x01 c1I1 arg1 arg2] $arg1 $arg2 -} {2 1 1} -test binary-41.5 {ScanNumber: word alignment} bigEndian { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1} +test binary-41.5 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -constraints bigEndian -body { list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2 -} {2 1 1.600000023841858} -test binary-41.6 {ScanNumber: word alignment} littleEndian { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1.600000023841858} +test binary-41.6 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -constraints littleEndian -body { list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2 -} {2 1 1.600000023841858} -test binary-41.7 {ScanNumber: word alignment} bigEndian { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1.600000023841858} +test binary-41.7 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -constraints bigEndian -body { list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2 -} {2 1 1.6} -test binary-41.8 {ScanNumber: word alignment} littleEndian { - unset -nocomplain arg1; unset arg2 +} -result {2 1 1.6} +test binary-41.8 {ScanNumber: word alignment} -setup { + unset -nocomplain arg1 arg2 +} -constraints littleEndian -body { list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2 -} {2 1 1.6} +} -result {2 1 1.6} test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body { binary ? diff --git a/tests/chanio.test b/tests/chanio.test index 665df50..999d0bb 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -2214,13 +2214,17 @@ test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup { puts $sok DONE exit 0 } echo.tcl] -} -body { + variable done + unset -nocomplain done + set done "" + set timer "" set ff [openpipe r $echo] gets $ff port +} -body { set s [socket 127.0.0.1 $port] puts $s Hey close $s w - set timer [after 1000 [namespace code {set ::done Failed}]] + set timer [after 1000 [namespace code {set done Failed}]] set acc {} fileevent $s readable [namespace code { if {[gets $s line]<0} { @@ -2230,11 +2234,11 @@ test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup { } }] vwait [namespace which -variable done] - after cancel $timer - close $s r - close $ff list $done $acc } -cleanup { + catch {close $s} + close $ff + after cancel $timer removeFile echo.tcl } -result {Succeeded {Hey DONE}} diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 3051bfb..39e9ece 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -954,6 +954,19 @@ test cmdAH-19.11 {Tcl_FileObjCmd: exists} -constraints {unix notRoot} -setup { removeFile /tmp/tcl.foo.dir/file removeDirectory /tmp/tcl.foo.dir } -result 0 +test cmdAH-19.12 {Bug 3608360: [file exists] mustn't do globbing} -setup { + set newdirfile [makeDirectory newdir.file] + set cwd [pwd] + cd $newdirfile + # Content of file is totally unimportant; name is *not* + set innocentBystander [makeFile "abc" [file join $newdirfile foo.bar]] +} -body { + list [file exists foo.bar] [file exists *.bar] +} -cleanup { + cd $cwd + removeFile $innocentBystander + removeDirectory $newdirfile +} -result {1 0} # Stat related commands diff --git a/tests/cmdInfo.test b/tests/cmdInfo.test index 69d7171..0a587e8 100644 --- a/tests/cmdInfo.test +++ b/tests/cmdInfo.test @@ -13,10 +13,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -101,7 +99,7 @@ test cmdinfo-6.1 {Names for commands created when outside namespaces} \ # cleanup catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1} catch {rename x1 ""} -::tcltest::cleanupTests +cleanupTests return # Local Variables: diff --git a/tests/coroutine.test b/tests/coroutine.test index 8272717..1d9040b 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -439,7 +439,7 @@ test coroutine-4.5 {bug #2724403} -constraints {memory} \ } -result 0 test coroutine-4.6 {compile context, bug #3282869} -setup { - unset ::x + unset -nocomplain ::x proc f x { coroutine D eval {yield X$x;yield Y} } diff --git a/tests/dcall.test b/tests/dcall.test index 3df0ac8..41dd777 100644 --- a/tests/dcall.test +++ b/tests/dcall.test @@ -11,10 +11,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -41,5 +39,5 @@ test dcall-1.6 {deletion callbacks} testdcall { } {} # cleanup -::tcltest::cleanupTests +cleanupTests return diff --git a/tests/expr-old.test b/tests/expr-old.test index 4f3cb2e..06a00ba 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -13,10 +13,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2.1 - namespace import -force ::tcltest::* -} +package require tcltest 2.1 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -145,7 +143,7 @@ test expr-old-1.50 {integer operators} {expr +36} 36 test expr-old-1.51 {integer operators} {expr +--++36} 36 test expr-old-1.52 {integer operators} {expr +36%+5} 1 test expr-old-1.53 {integer operators} { - catch {unset x} + unset -nocomplain x set x yes list [expr {1 && $x}] [expr {$x && 1}] \ [expr {0 || $x}] [expr {$x || 0}] @@ -453,7 +451,7 @@ test expr-old-23.3 {double quotes} { test expr-old-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22 test expr-old-23.5 {double quotes} {expr {"\*bc"}} {*bc} test expr-old-23.6 {double quotes} { - catch {unset bogus__} + unset -nocomplain bogus__ list [catch {expr {"$bogus__"}} msg] $msg } {1 {can't read "bogus__": no such variable}} test expr-old-23.7 {double quotes} { @@ -502,7 +500,7 @@ test expr-old-26.2 {error conditions} -body { test expr-old-26.3 {error conditions} -body { expr 2+4*( } -returnCodes error -match glob -result * -catch {unset _non_existent_} +unset -nocomplain _non_existent_ test expr-old-26.4 {error conditions} { list [catch {expr 2+$_non_existent_} msg] $msg } {1 {can't read "_non_existent_": no such variable}} @@ -581,7 +579,7 @@ test expr-old-27.4 {cancelled evaluation} { expr {1?2:[set a 2]} set a } 1 -catch {unset x} +unset -nocomplain x test expr-old-27.5 {cancelled evaluation} { list [catch {expr {[info exists x] && $x}} msg] $msg } {0 0} diff --git a/tests/fCmd.test b/tests/fCmd.test index 325b374..8f27ad4 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -2441,14 +2441,17 @@ test fCmd-28.12 {file link: cd into a link} -setup { return "ok" } } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result ok test fCmd-28.13 {file link} -constraints {linkDirectory} -setup { cd [temporaryDirectory] + file link abc.link abc.dir } -body { # duplicate link throws error file link abc.link abc.dir } -returnCodes error -cleanup { + file delete -force abc.link cd [workingDirectory] } -result {could not create new link "abc.link": that path already exists} test fCmd-28.14 {file link: deletes link not dir} -setup { @@ -2469,6 +2472,7 @@ test fCmd-28.15.1 {file link: copies link not dir} -setup { # directory, not a link (links trace to endpoint). list [file type abc2.link] [file tail [file link abc.link]] } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result {directory abc.dir} test fCmd-28.15.2 {file link: copies link not dir} -setup { @@ -2479,6 +2483,7 @@ test fCmd-28.15.2 {file link: copies link not dir} -setup { file copy abc.link abc2.link list [file type abc2.link] [file tail [file link abc2.link]] } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result {link abc.dir} cd [temporaryDirectory] @@ -2498,20 +2503,25 @@ test fCmd-28.16 {file link: glob inside link} -setup { file link abc.link abc.dir lsort [glob -dir abc.link -tails *] } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result {abc.file abc2.file} test fCmd-28.17 {file link: glob -type l} -setup { cd [temporaryDirectory] + file link abc.link abc.dir } -constraints {linkDirectory} -body { glob -dir [pwd] -type l -tails abc* } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result {abc.link} test fCmd-28.18 {file link: glob -type d} -constraints linkDirectory -setup { cd [temporaryDirectory] + file link abc.link abc.dir } -body { lsort [glob -dir [pwd] -type d -tails abc*] } -cleanup { + file delete -force abc.link cd [workingDirectory] } -result [lsort [list abc.link abc.dir abc2.dir]] test fCmd-28.19 {file link: relative paths} -setup { diff --git a/tests/fileSystem.test b/tests/fileSystem.test index b098f35..942a86c 100644 --- a/tests/fileSystem.test +++ b/tests/fileSystem.test @@ -138,13 +138,18 @@ test filesystem-1.9 {link normalisation} -setup { testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \ [file normalize [file join dir.link inside.file foo]] } -result ok -test filesystem-1.10 {link normalisation: double link} {unix hasLinks} { +test filesystem-1.10 {link normalisation: double link} -constraints { + unix hasLinks +} -body { file link dir2.link dir.link testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \ [file normalize [file join dir2.link inside.file foo]] -} ok +} -cleanup { + file delete dir2.link +} -result ok makeDirectory dir2.file test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} { + file link dir2.link dir.link file link [file join dir2.file dir2.link] [file join .. dir2.link] testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \ [file normalize [file join dir2.file dir2.link inside.file foo]] @@ -373,7 +378,9 @@ test filesystem-2.0 {new native path} {unix} { # Make sure the testfilesystem hasn't been registered. if {[testConstraint testfilesystem]} { + proc resetfs {} { while {![catch {testfilesystem 0}]} {} + } } test filesystem-3.1 {Tcl_FSRegister & Tcl_FSUnregister} testfilesystem { @@ -388,12 +395,14 @@ test filesystem-3.3 {Tcl_FSRegister} testfilesystem { testfilesystem 0 testfilesystem 0 } {unregistered} -test filesystem-3.4 {Tcl_FSRegister} testfilesystem { +test filesystem-3.4 {Tcl_FSRegister} -constraints testfilesystem -body { testfilesystem 1 file system bar -} {reporting} -test filesystem-3.5 {Tcl_FSUnregister} testfilesystem { +} -cleanup { testfilesystem 0 +} -result {reporting} +test filesystem-3.5 {Tcl_FSUnregister} testfilesystem { + resetfs lindex [file system bar] 0 } {native} @@ -632,7 +641,7 @@ test filesystem-7.4 {cross-filesystem file copy with -force} -setup { file delete -force simplefile file delete -force file2 cd $dir -} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1} +} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1} test filesystem-7.5 {cross-filesystem file copy with -force} -setup { set dir [pwd] cd [tcltest::temporaryDirectory] @@ -657,7 +666,7 @@ test filesystem-7.5 {cross-filesystem file copy with -force} -setup { file delete -force simplefile file delete -force file2 cd $dir -} -result {0 10 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 10 1} +} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1} test filesystem-7.6 {cross-filesystem dir copy with -force} -setup { set dir [pwd] cd [tcltest::temporaryDirectory] diff --git a/tests/http.test b/tests/http.test index 7ec2d20..faf3abc 100644 --- a/tests/http.test +++ b/tests/http.test @@ -135,6 +135,7 @@ set fullurl http://user:pass@[info hostname]:$port/a/b/c set binurl //[info hostname]:$port/binary set posturl //[info hostname]:$port/post set badposturl //[info hostname]:$port/droppost +set authorityurl //[info hostname]:$port set ipv6url http://\[::1\]:$port/ test http-3.4 {http::geturl} -body { set token [http::geturl $url] @@ -391,7 +392,7 @@ Connection close Content-Type {text/plain;charset=utf-8} Accept-Encoding .* Content-Length 5} -test http-3.29 "http::geturl $ipv6url" -body { +test http-3.29 {http::geturl IPv6 address} -body { # We only want to see if the URL gets parsed correctly. This is # the case if http::geturl succeeds or returns a socket related # error. If the parsing is wrong, we'll get a parse error. @@ -405,7 +406,18 @@ test http-3.29 "http::geturl $ipv6url" -body { } -cleanup { catch { http::cleanup $token } } -result 0 - +test http-3.30 {http::geturl query without path} -body { + set token [http::geturl $authorityurl?var=val] + http::ncode $token +} -cleanup { + catch { http::cleanup $token } +} -result 200 +test http-3.31 {http::geturl fragment without path} -body { + set token [http::geturl "$authorityurl#fragment42"] + http::ncode $token +} -cleanup { + catch { http::cleanup $token } +} -result 200 test http-4.1 {http::Event} -body { set token [http::geturl $url -keepalive 0] upvar #0 $token data @@ -547,11 +559,10 @@ test http-4.14 {http::Event} -body { error "bogus return from http::geturl" } http::wait $token - http::status $token - # error code varies among platforms. -} -returnCodes 1 -match regexp -cleanup { + lindex [http::error $token] 0 +} -cleanup { catch {http::cleanup $token} -} -result {(connect failed|couldn't open socket)} +} -result {connect failed connection refused} # Bogus host test http-4.15 {http::Event} -body { # This test may fail if you use a proxy server. That is to be diff --git a/tests/listObj.test b/tests/listObj.test index 937fb1d..d7fb46c 100644 --- a/tests/listObj.test +++ b/tests/listObj.test @@ -196,7 +196,7 @@ test listobj-10.1 {Bug [2971669]} {*}{ -result {{a b c d e} {} {a b c d e f}} } -test listobj-11.1 {bug 3598580} { +test listobj-11.1 {Bug 3598580: Tcl_ListObjReplace refcount management} testobj { testobj bug3598580 } 123 diff --git a/tests/lmap.test b/tests/lmap.test index 7baa77b..08035d9 100644 --- a/tests/lmap.test +++ b/tests/lmap.test @@ -18,7 +18,7 @@ if {"::tcltest" ni [namespace children]} { namespace import -force ::tcltest::* } -unset -nocomplain a i x +unset -nocomplain a b i x # ----- Non-compiled operation ----------------------------------------------- @@ -404,14 +404,21 @@ test lmap-7.6 {lmap: related to "foreach" [Bug 1671087]} -setup { rename demo {} } -result {2 4} # Huge lists must not overflow the bytecode interpreter (development bug) -test lmap-7.7 {huge list non-compiled} { +test lmap-7.7 {huge list non-compiled} -setup { + unset -nocomplain a b x +} -body { set x [lmap a [lrepeat 1000000 x] { set b y$a }] list $b [llength $x] [string length $x] -} {yx 1000000 2999999} -test lmap-7.8 {huge list compiled} { - set x [apply {{times} { lmap a [lrepeat $times x] { set b y$a }}} 1000000] +} -result {yx 1000000 2999999} +test lmap-7.8 {huge list compiled} -setup { + unset -nocomplain a b x +} -body { + set x [apply {{times} { + global b + lmap a [lrepeat $times x] { set b Y$a } + }} 1000000] list $b [llength $x] [string length $x] -} {yx 1000000 2999999} +} -result {Yx 1000000 2999999} test lmap-7.9 {error then dereference loop var (dev bug)} { catch { lmap a 0 b {1 2 3} { error x } } set a diff --git a/tests/main.test b/tests/main.test index f1dc7fd..351fd4f 100644 --- a/tests/main.test +++ b/tests/main.test @@ -129,7 +129,7 @@ namespace eval ::tcl::test::main { set script [makeFile {} script] file delete $script set f [open $script w] - fconfigure $f -encoding utf-8 + chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} puts -nonewline $f {puts [string equal \u20ac } puts $f "\u20ac]" @@ -150,7 +150,7 @@ namespace eval ::tcl::test::main { set script [makeFile {} script] file delete $script set f [open $script w] - fconfigure $f -encoding utf-8 + chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} puts -nonewline $f {puts [string equal \u20ac } puts $f "\u20ac]" @@ -171,7 +171,7 @@ namespace eval ::tcl::test::main { set script [makeFile {} script] file delete $script set f [open $script w] - fconfigure $f -encoding utf-8 + chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} puts -nonewline $f {puts [string equal \u20ac } puts $f "\u20ac]" @@ -592,7 +592,7 @@ namespace eval ::tcl::test::main { catch {set f [open "|[list [interpreter]]" w+]} } -body { type $f { - fconfigure stdin -blocking 0 + chan configure stdin -blocking 0 puts SUCCESS } list [catch {gets $f} line] $line @@ -606,19 +606,19 @@ namespace eval ::tcl::test::main { exec } -setup { catch {set f [open "|[list [interpreter]]" w+]} - catch {fconfigure $f -blocking 0} + catch {chan configure $f -blocking 0} } -body { - type $f "fconfigure stdin -eofchar \\032 + type $f "chan configure stdin -eofchar \\032 if 1 \{\n\032" variable wait - fileevent $f readable \ + chan event $f readable \ [list set [namespace which -variable wait] "child exit"] set id [after 2000 [list set [namespace which -variable wait] timeout]] vwait [namespace which -variable wait] after cancel $id set wait } -cleanup { - if {[string equal timeout $wait] && [testConstraint unix]} { + if {$wait eq "timeout" && [testConstraint unix]} { exec kill [pid $f] } close $f @@ -631,17 +631,17 @@ namespace eval ::tcl::test::main { } -setup { set cmd {makeFile "if 1 \{" script} catch {set f [open "|[list [interpreter]] < [list [eval $cmd]]" r]} - catch {fconfigure $f -blocking 0} + catch {chan configure $f -blocking 0} } -body { variable wait - fileevent $f readable \ + chan event $f readable \ [list set [namespace which -variable wait] "child exit"] set id [after 2000 [list set [namespace which -variable wait] timeout]] vwait [namespace which -variable wait] after cancel $id set wait } -cleanup { - if {[string equal timeout $wait] && [testConstraint unix]} { + if {$wait eq "timeout" && [testConstraint unix]} { exec kill [pid $f] } close $f @@ -748,7 +748,7 @@ namespace eval ::tcl::test::main { exec Tcltest } -setup { catch {set f [open "|[list [interpreter]]" w+]} - catch {fconfigure $f -blocking 0} + catch {chan configure $f -blocking 0} } -body { type $f "testsetmainloop after 2000 testexitmainloop @@ -983,7 +983,7 @@ namespace eval ::tcl::test::main { } -body { exec [interpreter] << { testsetmainloop - fconfigure stdin -blocking 0 + chan configure stdin -blocking 0 testexitmainloop } >& result set f [open result] diff --git a/tests/msgcat.test b/tests/msgcat.test index 1522354..050b592 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -12,13 +12,13 @@ # Note that after running these tests, entries will be left behind in the # message catalogs for locales foo, foo_BAR, and foo_BAR_baz. -package require Tcl 8.2 +package require Tcl 8.5 if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return } -if {[catch {package require msgcat 1.5.0}]} { - puts stderr "Skipping tests in [info script]. No msgcat 1.5.0 found to test." +if {[catch {package require msgcat 1.5}]} { + puts stderr "Skipping tests in [info script]. No msgcat 1.5 found to test." return } @@ -56,7 +56,7 @@ namespace eval ::msgcat::test { set result [string tolower \ [msgcat::ConvertLocale $::tcl::mac::locale]] } else { - if {([info sharedlibextension] == ".dll") + if {([info sharedlibextension] eq ".dll") && ![catch {package require registry}]} { # Windows and Cygwin have other ways to determine the # locale when the environment variables are missing @@ -72,7 +72,7 @@ namespace eval ::msgcat::test { variable var foreach var $envVars { catch {variable $var $::env($var)} - catch {unset ::env($var)} + unset -nocomplain ::env($var) } foreach var $setVars { set ::env($var) $var @@ -84,13 +84,13 @@ namespace eval ::msgcat::test { } -cleanup { interp delete [namespace current]::i foreach var $envVars { - catch {unset ::env($var)} + unset -nocomplain ::env($var) catch {set ::env($var) [set [namespace current]::$var]} } } -body {i eval msgcat::mclocale} -result $result incr count } - catch {unset result} + unset -nocomplain result # Could add tests of initialization from Windows registry here. # Use a fake registry package. @@ -324,7 +324,7 @@ namespace eval ::msgcat::test { incr count } } - catch {unset result} + unset -nocomplain result # Tests msgcat-4.*: [mcunknown] diff --git a/tests/namespace.test b/tests/namespace.test index 1d46bf0..f6688f1 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -1111,6 +1111,14 @@ test namespace-26.7 {NamespaceExportCmd, -clear resets export list} { } list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello] } [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}] +test namespace-26.8 {NamespaceExportCmd, -clear resets export list} { + catch {namespace delete foo} + namespace eval foo { + namespace export x + namespace export -clear + } + list [namespace eval foo namespace export] [namespace delete foo] +} {{} {}} test namespace-27.1 {NamespaceForgetCmd, no args} { catch {namespace delete {*}[namespace children :: test_ns_*]} diff --git a/tests/oo.test b/tests/oo.test index 5d34077..49fe150 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2204,6 +2204,25 @@ test oo-19.2 {OO: varname method: Bug 2883857} -setup { } -cleanup { SpecialClass destroy } -result ::oo_test::x(y) +test oo-19.3 {OO: varname method and variable decl: Bug 3603695} -setup { + oo::class create testClass { + variable foo + export varname + constructor {} { + variable foo x + } + method bar {obj} { + my varname foo + $obj varname foo + } + } +} -body { + testClass create A + testClass create B + lsearch [list [A varname foo] [B varname foo]] [B bar A] +} -cleanup { + testClass destroy +} -result 0 test oo-20.1 {OO: variable method} -body { oo::class create testClass { diff --git a/tests/parse.test b/tests/parse.test index 0f76d64..b9cfe80 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -26,6 +26,7 @@ testConstraint testparsevarname [llength [info commands testparsevarname]] testConstraint testparsevar [llength [info commands testparsevar]] testConstraint testasync [llength [info commands testasync]] testConstraint testcmdtrace [llength [info commands testcmdtrace]] +testConstraint testevent [llength [info commands testevent]] test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser { testparser [bytestring "foo\0 bar"] -1 @@ -438,7 +439,7 @@ test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} { test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex { - catch {unset x} + unset -nocomplain x list [catch {testevalex {for {} 1 {} { @@ -479,7 +480,7 @@ test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex { testevalex {concat [expr 2 + 6]} } {8} test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {concat xxx[expr $a]}} msg] $msg } {1 {can't read "a": no such variable}} test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex { @@ -487,21 +488,21 @@ test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex { testevalex {concat $a} } {hello} test parse-10.6 {Tcl_EvalTokens, array variables} testevalex { - catch {unset a} + unset -nocomplain a set a(12) 46 testevalex {concat $a(12)} } {46} test parse-10.7 {Tcl_EvalTokens, array variables} testevalex { - catch {unset a} + unset -nocomplain a set a(12) 46 testevalex {concat $a(1[expr 3 - 1])} } {46} test parse-10.8 {Tcl_EvalTokens, array variables} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {concat $x($a)}} msg] $msg } {1 {can't read "a": no such variable}} test parse-10.9 {Tcl_EvalTokens, array variables} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {concat xyz$a(1)}} msg] $msg } {1 {can't read "a(1)": no such variable}} test parse-10.10 {Tcl_EvalTokens, object values} testevalex { @@ -541,11 +542,11 @@ test parse-11.2 {Tcl_EvalEx, error while parsing} testevalex { list [catch {testevalex {concat "abc}} msg] $msg } {1 {missing "}} test parse-11.3 {Tcl_EvalEx, error while collecting words} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {concat xyz $a}} msg] $msg } {1 {can't read "a": no such variable}} test parse-11.4 {Tcl_EvalEx, error in Tcl_EvalObjv call} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {_bogus_ a b c d}} msg] $msg } {1 {invalid command name "_bogus_"}} test parse-11.5 {Tcl_EvalEx, exceptional return} testevalex { @@ -564,7 +565,7 @@ test parse-11.8 {Tcl_EvalEx, multiple commands in script} testevalex { }] $a $c } {d b d} test parse-11.9 {Tcl_EvalEx, freeing memory after error} testevalex { - catch {unset a} + unset -nocomplain a list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg } {1 {can't read "a": no such variable}} test parse-11.10 {Tcl_EvalTokens, empty commands} testevalex { @@ -670,11 +671,11 @@ test parse-13.3 {Tcl_ParseVar procedure, no variable name} testparsevar { testparsevar {$.123} } {{$} .123} test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} testparsevar { - catch {unset abc} + unset -nocomplain abc list [catch {testparsevar {$abc}} msg] $msg } {1 {can't read "abc": no such variable}} test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar { - catch {unset abc} + unset -nocomplain abc list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg } {1 {invalid command name "bogus"}} @@ -1090,6 +1091,13 @@ test parse-20.12 {TclParseBackslash: truncated escape} testparser { testparser {\x12X} 5 } {- {\x12X} 1 word {\x12X} 2 backslash {\x12} 0 text X 0 {}} +test parse-21.0 {Bug 1884496} testevent { + set ::script {testevent delete a; set a [p]; set ::done $a} + proc ::p {} {string first s $::script} + testevent queue a head $::script + vwait done +} {} + cleanupTests } diff --git a/tests/parseExpr.test b/tests/parseExpr.test index 7910974..714c45b 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -8,10 +8,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -1067,5 +1065,5 @@ test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body { # cleanup -::tcltest::cleanupTests +cleanupTests return diff --git a/tests/parseOld.test b/tests/parseOld.test index 0edcbf0..f3b1591 100644 --- a/tests/parseOld.test +++ b/tests/parseOld.test @@ -13,10 +13,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -166,25 +164,25 @@ test parseOld-5.6 {variable substitution} { set msg } {can't read "_non_existent_": no such variable} test parseOld-5.7 {array variable substitution} { - catch {unset a} + unset -nocomplain a set a(xyz) 123 set b $a(xyz)foo set b } 123foo test parseOld-5.8 {array variable substitution} { - catch {unset a} + unset -nocomplain a set "a(x y z)" 123 set b $a(x y z)foo set b } 123foo test parseOld-5.9 {array variable substitution} { - catch {unset a}; catch {unset qqq} + unset -nocomplain a qqq set "a(x y z)" qqq set $a([format x]\ y [format z]) foo set qqq } foo test parseOld-5.10 {array variable substitution} { - catch {unset a} + unset -nocomplain a list [catch {set b $a(22)} msg] $msg } {1 {can't read "a(22)": no such variable}} test parseOld-5.11 {array variable substitution} { @@ -194,9 +192,9 @@ test parseOld-5.11 {array variable substitution} { test parseOld-5.12 {empty array name support} { list [catch {set b a$()} msg] $msg } {1 {can't read "()": no such variable}} -catch {unset a} +unset -nocomplain a test parseOld-5.13 {array variable substitution} { - catch {unset a} + unset -nocomplain a set long {This is a very long variable, long enough to cause storage \ allocation to occur in Tcl_ParseVar. If that storage isn't getting \ freed up correctly, then a core leak will occur when this test is \ @@ -211,13 +209,13 @@ test parseOld-5.13 {array variable substitution} { run. This text is probably beginning to sound like drivel, but I've \ run out of things to say and I need more characters still.}}} test parseOld-5.14 {array variable substitution} { - catch {unset a}; catch {unset b}; catch {unset a1} + unset -nocomplain a b a1 set a1(22) foo set a(foo) bar set b $a($a1(22)) set b } bar -catch {unset a}; catch {unset a1} +unset -nocomplain a a1 test parseOld-7.1 {backslash substitution} { set a "\a\c\n\]\}" diff --git a/tests/pkgMkIndex.test b/tests/pkgMkIndex.test index 0fe394e..84c82ce 100644 --- a/tests/pkgMkIndex.test +++ b/tests/pkgMkIndex.test @@ -8,10 +8,8 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* set fullPkgPath [makeDirectory pkg] @@ -45,7 +43,7 @@ proc pkgtest::parseArgs { args } { set a [lindex $args $iarg] if {[regexp {^-} $a]} { lappend options $a - if {[string compare -load $a] == 0} { + if {$a eq "-load"} { incr iarg lappend options [lindex $args $iarg] } @@ -81,7 +79,7 @@ proc pkgtest::parseIndex { filePath } { $slave eval { rename package package_original proc package { args } { - if {[string compare [lindex $args 0] ifneeded] == 0} { + if {[lindex $args 0] eq "ifneeded"} { set pkg [lindex $args 1] set ver [lindex $args 2] set ::PKGS($pkg:$ver) [lindex $args 3] @@ -111,9 +109,9 @@ proc pkgtest::parseIndex { filePath } { foreach k [lsort [array names P]] { lappend PKGS $k $P($k) } - } err]} { - set ei $::errorInfo - set ec $::errorCode + } err opts]} { + set ei [dict get $opts -errorinfo] + set ec [dict get $opts -errorcode] catch {interp delete $slave} diff --git a/tests/platform.test b/tests/platform.test index aab7c78..6596975 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -9,10 +9,14 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest 2 + +namespace eval ::tcl::test::platform { + namespace import ::tcltest::testConstraint + namespace import ::tcltest::test + namespace import ::tcltest::cleanupTests + + variable ::tcl_platform ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -54,7 +58,10 @@ test platform-3.1 {CPU ID on Windows/UNIX} \ -result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$} # cleanup -::tcltest::cleanupTests +cleanupTests + +} +namespace delete ::tcl::test::platform return # Local Variables: diff --git a/tests/reg.test b/tests/reg.test index a0ea850..559f549 100644 --- a/tests/reg.test +++ b/tests/reg.test @@ -1080,6 +1080,81 @@ test reg-33.13 {Bug 1810264 - infinite loop} { test reg-33.14 {Bug 1810264 - super-expensive expression} nonPortable { regexp {(x{200}){200}$y} {x} } 0 +test reg-33.15 {Bug 3603557 - an "in the wild" RE} { + lindex [regexp -expanded -about { + ^TETRA_MODE_CMD # Message Type + ([[:blank:]]+) # Pad + (ETS_1_1|ETS_1_2|ETS_2_2) # SystemCode + ([[:blank:]]+) # Pad + (CONTINUOUS|CARRIER|MCCH|TRAFFIC) # SharingMode + ([[:blank:]]+) # Pad + ([[:digit:]]{1,2}) # ColourCode + ([[:blank:]]+) # Pad + (1|2|3|4|6|9|12|18) # TSReservedFrames + ([[:blank:]]+) # Pad + (PASS|TRUE|FAIL|FALSE) # UPlaneDTX + ([[:blank:]]+) # Pad + (PASS|TRUE|FAIL|FALSE) # Frame18Extension + ([[:blank:]]+) # Pad + ([[:digit:]]{1,4}) # MCC + ([[:blank:]]+) # Pad + ([[:digit:]]{1,5}) # MNC + ([[:blank:]]+) # Pad + (BOTH|BCAST|ENQRY|NONE) # NbrCellBcast + ([[:blank:]]+) # Pad + (UNKNOWN|LOW|MEDIUM|HIGH) # CellServiceLevel + ([[:blank:]]+) # Pad + (PASS|TRUE|FAIL|FALSE) # LateEntryInfo + ([[:blank:]]+) # Pad + (300|400) # FrequencyBand + ([[:blank:]]+) # Pad + (NORMAL|REVERSE) # ReverseOperation + ([[:blank:]]+) # Pad + (NONE|\+6\.25|\-6\.25|\+12\.5) # Offset + ([[:blank:]]+) # Pad + (10) # DuplexSpacing + ([[:blank:]]+) # Pad + ([[:digit:]]{1,4}) # MainCarrierNr + ([[:blank:]]+) # Pad + (0|1|2|3) # NrCSCCH + ([[:blank:]]+) # Pad + (15|20|25|30|35|40|45) # MSTxPwrMax + ([[:blank:]]+) # Pad + (\-125|\-120|\-115|\-110|\-105|\-100|\-95|\-90|\-85|\-80|\-75|\-70|\-65|\-60|\-55|\-50) + # RxLevAccessMin + ([[:blank:]]+) # Pad + (\-53|\-51|\-49|\-47|\-45|\-43|\-41|\-39|\-37|\-35|\-33|\-31|\-29|\-27|\-25|\-23) + # AccessParameter + ([[:blank:]]+) # Pad + (DISABLE|[[:digit:]]{3,4}) # RadioDLTimeout + ([[:blank:]]+) # Pad + (\-[[:digit:]]{2,3}) # RSSIThreshold + ([[:blank:]]+) # Pad + ([[:digit:]]{1,5}) # CCKIdSCKVerNr + ([[:blank:]]+) # Pad + ([[:digit:]]{1,5}) # LocationArea + ([[:blank:]]+) # Pad + ([(1|0)]{16}) # SubscriberClass + ([[:blank:]]+) # Pad + ([(1|0)]{12}) # BSServiceDetails + ([[:blank:]]+) # Pad + (RANDOMIZE|IMMEDIATE|[[:digit:]]{1,2}) # IMM + ([[:blank:]]+) # Pad + ([[:digit:]]{1,2}) # WT + ([[:blank:]]+) # Pad + ([[:digit:]]{1,2}) # Nu + ([[:blank:]]+) # Pad + ([0-1]) # FrameLngFctr + ([[:blank:]]+) # Pad + ([[:digit:]]{1,2}) # TSPtr + ([[:blank:]]+) # Pad + ([0-7]) # MinPriority + ([[:blank:]]+) # Pad + (PASS|TRUE|FAIL|FALSE) # ExtdSrvcsEnabled + ([[:blank:]]+) # Pad + (.*) # ConditionalFields + }] 0 +} 68 # cleanup ::tcltest::cleanupTests diff --git a/tests/regexp.test b/tests/regexp.test index 7cafd1b..2d2814a 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -819,6 +819,52 @@ test regexp-22.1 {Bug 1810038} { test regexp-22.2 {regexp compile and backrefs, Bug 1857126} { regexp -- {([bc])\1} bb } 1 +test regexp-22.3 {Bug 3604074} { + # This will hang in interps where the bug is not fixed + regexp ((((((((a)*)*)*)*)*)*)*)* a +} 1 +test regexp-22.4 {Bug 3606139} -setup { + interp alias {} a {} string repeat a +} -body { + # This crashes in interps where the bug is not fixed + regexp [join [list [a 160]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 672]([a 55])[a 669]([a 55])[a 671]([a 55])[a 671]([a 55]) \ + [a 672]([a 55])[a 652]([a 55])[a 672]([a 55])[a 671]([a 55]) \ + [a 671]([a 55])[a 671]([a 55])[a 653]([a 55])[a 672]([a 55]) \ + [a 653]([a 55])[a 672]([a 55])[a 672]([a 55])[a 652]([a 55]) \ + [a 671]([a 55])[a 652]([a 55])[a 652]([a 55])[a 672]([a 55]) \ + [a 672]([a 55])[a 672]([a 55])[a 653]([a 55])[a 671]([a 55]) \ + [a 669]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 650]([a 55])[a 650]([a 55])[a 672]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 672]([a 55]) \ + [a 670]([a 55])[a 671]([a 55])[a 672]([a 55])[a 672]([a 55]) \ + [a 671]([a 55])[a 671]([a 55])[a 672]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \ + [a 669]([a 55])[a 668]([a 55])[a 669]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 710]([a 55]) \ + [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 667]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \ + [a 671]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \ + [a 668]([a 55])[a 710]([a 55])[a 668]([a 55])[a 668]([a 55]) \ + [a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 511]] {}] a +} -cleanup { + rename a {} +} -returnCodes 1 -result {couldn't compile regular expression pattern: nfa has too many states} test regexp-23.1 {regexp -all and -line} { set string "" diff --git a/tests/result.test b/tests/result.test index 3391ce1..9e8a66b 100644 --- a/tests/result.test +++ b/tests/result.test @@ -10,10 +10,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] diff --git a/tests/scan.test b/tests/scan.test index 97ad5eb..ea0c500 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -1,8 +1,8 @@ # Commands covered: scan # -# This file contains a collection of tests for one or more of the Tcl -# built-in commands. Sourcing this file into Tcl runs the tests and -# generates output for errors. No output means no errors were found. +# This file contains a collection of tests for one or more of the Tcl built-in +# commands. Sourcing this file into Tcl runs the tests and generates output +# for errors. No output means no errors were found. # # Copyright (c) 1991-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. @@ -11,14 +11,83 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { +if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } +# procedure that returns the range of integers + +proc int_range {} { + for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} { + set MIN_INT [expr { $MIN_INT << 1 }] + } + set MIN_INT [expr {int($MIN_INT)}] + set MAX_INT [expr { ~ $MIN_INT }] + return [list $MIN_INT $MAX_INT] +} + +# Big test for correct ordering of data in [expr] + +proc testIEEE {} { + variable ieeeValues + binary scan [binary format dd -1.0 1.0] c* c + switch -exact -- $c { + {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { + # little endian + binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + ieeeValues(-Infinity) + binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + ieeeValues(-Normal) + binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ + ieeeValues(-Subnormal) + binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \ + ieeeValues(-0) + binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(+0) + binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ + ieeeValues(+Subnormal) + binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + ieeeValues(+Normal) + binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + ieeeValues(+Infinity) + binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + ieeeValues(NaN) + set ieeeValues(littleEndian) 1 + return 1 + } + {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { + binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(-Infinity) + binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(-Normal) + binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(-Subnormal) + binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(-0) + binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(+0) + binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(+Subnormal) + binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(+Normal) + binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(+Infinity) + binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + ieeeValues(NaN) + set ieeeValues(littleEndian) 0 + return 1 + } + default { + return 0 + } + } +} + +testConstraint ieeeFloatingPoint [testIEEE] testConstraint wideIs64bit \ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] - + test scan-1.1 {BuildCharSet, CharInSet} { list [scan foo {%[^o]} x] $x } {1 f} @@ -43,10 +112,11 @@ test scan-1.7 {BuildCharSet, CharInSet} { test scan-1.8 {BuildCharSet, CharInSet} { list [scan def-abc {%[^c-a]} x] $x } {1 def-} -test scan-1.9 {BuildCharSet, CharInSet no match} { - catch {unset x} +test scan-1.9 {BuildCharSet, CharInSet no match} -setup { + unset -nocomplain x +} -body { list [scan {= f} {= %[TF]} x] [info exists x] -} {0 0} +} -result {0 0} test scan-2.1 {ReleaseCharSet} { list [scan abcde {%[abc]} x] $x @@ -55,53 +125,53 @@ test scan-2.2 {ReleaseCharSet} { list [scan abcde {%[a-c]} x] $x } {1 abc} -test scan-3.1 {ValidateFormat} { - list [catch {scan {} {%d%1$d} x} msg] $msg -} {1 {cannot mix "%" and "%n$" conversion specifiers}} -test scan-3.2 {ValidateFormat} { - list [catch {scan {} {%d%1$d} x} msg] $msg -} {1 {cannot mix "%" and "%n$" conversion specifiers}} -test scan-3.3 {ValidateFormat} { - list [catch {scan {} {%2$d%d} x} msg] $msg -} {1 {"%n$" argument index out of range}} +test scan-3.1 {ValidateFormat} -returnCodes error -body { + scan {} {%d%1$d} x +} -result {cannot mix "%" and "%n$" conversion specifiers} +test scan-3.2 {ValidateFormat} -returnCodes error -body { + scan {} {%d%1$d} x +} -result {cannot mix "%" and "%n$" conversion specifiers} +test scan-3.3 {ValidateFormat} -returnCodes error -body { + scan {} {%2$d%d} x +} -result {"%n$" argument index out of range} test scan-3.4 {ValidateFormat} { # degenerate case, before changed from 8.2 to 8.3 list [catch {scan {} %d} msg] $msg } {0 {}} -test scan-3.5 {ValidateFormat} { - list [catch {scan {} {%10c} a} msg] $msg -} {1 {field width may not be specified in %c conversion}} -test scan-3.6 {ValidateFormat} { - list [catch {scan {} {%*1$d} a} msg] $msg -} {1 {bad scan conversion character "$"}} -test scan-3.7 {ValidateFormat} { - list [catch {scan {} {%1$d%1$d} a} msg] $msg -} {1 {variable is assigned by multiple "%n$" conversion specifiers}} -test scan-3.8 {ValidateFormat} { - list [catch {scan {} a x} msg] $msg -} {1 {variable is not assigned by any conversion specifiers}} -test scan-3.9 {ValidateFormat} { - list [catch {scan {} {%2$s} x y} msg] $msg -} {1 {variable is not assigned by any conversion specifiers}} -test scan-3.10 {ValidateFormat} { - list [catch {scan {} {%[a} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-3.11 {ValidateFormat} { - list [catch {scan {} {%[^a} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-3.12 {ValidateFormat} { - list [catch {scan {} {%[]a} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-3.13 {ValidateFormat} { - list [catch {scan {} {%[^]a} x} msg] $msg -} {1 {unmatched [ in format string}} +test scan-3.5 {ValidateFormat} -returnCodes error -body { + scan {} {%10c} a +} -result {field width may not be specified in %c conversion} +test scan-3.6 {ValidateFormat} -returnCodes error -body { + scan {} {%*1$d} a +} -result {bad scan conversion character "$"} +test scan-3.7 {ValidateFormat} -returnCodes error -body { + scan {} {%1$d%1$d} a +} -result {variable is assigned by multiple "%n$" conversion specifiers} +test scan-3.8 {ValidateFormat} -returnCodes error -body { + scan {} a x +} -result {variable is not assigned by any conversion specifiers} +test scan-3.9 {ValidateFormat} -returnCodes error -body { + scan {} {%2$s} x y +} -result {variable is not assigned by any conversion specifiers} +test scan-3.10 {ValidateFormat} -returnCodes error -body { + scan {} {%[a} x +} -result {unmatched [ in format string} +test scan-3.11 {ValidateFormat} -returnCodes error -body { + scan {} {%[^a} x +} -result {unmatched [ in format string} +test scan-3.12 {ValidateFormat} -returnCodes error -body { + scan {} {%[]a} x +} -result {unmatched [ in format string} +test scan-3.13 {ValidateFormat} -returnCodes error -body { + scan {} {%[^]a} x +} -result {unmatched [ in format string} -test scan-4.1 {Tcl_ScanObjCmd, argument checks} { - list [catch {scan} msg] $msg -} {1 {wrong # args: should be "scan string format ?varName ...?"}} -test scan-4.2 {Tcl_ScanObjCmd, argument checks} { - list [catch {scan string} msg] $msg -} {1 {wrong # args: should be "scan string format ?varName ...?"}} +test scan-4.1 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body { + scan +} -result {wrong # args: should be "scan string format ?varName ...?"} +test scan-4.2 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body { + scan string +} -result {wrong # args: should be "scan string format ?varName ...?"} test scan-4.3 {Tcl_ScanObjCmd, argument checks} { # degenerate case, before changed from 8.2 to 8.3 list [catch {scan string format} msg] $msg @@ -191,93 +261,114 @@ test scan-4.29 {Tcl_ScanObjCmd, character scanning} { list [scan {abcdef} {%*c%n} x] $x } {1 1} -test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} { +test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {1234567890a} {%3d} x] $x -} {1 123} -test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {1 123} +test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {1234567890a} {%d} x] $x -} {1 1234567890} -test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {1 1234567890} +test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {01234567890a} {%d} x] $x -} {1 1234567890} -test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {1 1234567890} +test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {+01234} {%d} x] $x -} {1 1234} -test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {1 1234} +test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {-01234} {%d} x] $x -} {1 -1234} -test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {1 -1234} +test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {a01234} {%d} x] $x -} {0 {}} -test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} { +} -result {0 {}} +test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} -setup { set x {} +} -body { list [scan {0x10} {%d} x] $x -} {1 0} -test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} { +} -result {1 0} +test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} -setup { set x {} +} -body { list [scan {012345678} {%o} x] $x -} {1 342391} -test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} { +} -result {1 342391} +test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} -setup { set x {} +} -body { list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z -} {3 83 -83 83} -test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} { +} -result {3 83 -83 83} +test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} -setup { set x {} +} -body { list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z -} {3 4664 -4666 291} -test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} { +} -result {3 4664 -4666 291} +test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} -setup { + set x {} +} -body { # The behavior changed in 8.4a4/8.3.4cvs (6 Feb) to correctly # return '1' for 0x1 scanned via %x, to comply with 8.0 and C scanf. # Bug #495213 - set x {} list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z -} {3 11259375 11259375 1} -test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} { +} -result {3 11259375 11259375 1} +test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} -setup { set x {} +} -body { list [scan {0xF 0x00A0B 0X0XF} {%x %x %x} x y z] $x $y $z -} {3 15 2571 0} -test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} { - catch {unset x} +} -result {3 15 2571 0} +test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} -setup { + unset -nocomplain x +} -body { list [scan {xF} {%x} x] [info exists x] -} {0 0} -test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} { +} -result {0 0} +test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} -setup { set x {} +} -body { list [scan {1001 0b101 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} {%b %b %llb} x y z] $x $y $z -} {3 9 5 340282366920938463463374607431768211456} -test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} { +} -result {3 9 5 340282366920938463463374607431768211456} +test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup { set x {} +} -body { list [scan {10 010 0x10 0b10} {%i%i%i%i} x y z t] $x $y $z $t -} {4 10 8 16 0} -test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} { +} -result {4 10 8 16 0} +test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup { set x {} +} -body { list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z -} {3 10 8 16} -test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} { +} -result {3 10 8 16} +test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup { set x {} +} -body { list [scan {+ } {%i} x] $x -} {0 {}} -test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} { +} -result {0 {}} +test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup { set x {} +} -body { list [scan {+} {%i} x] $x -} {-1 {}} -test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} { +} -result {-1 {}} +test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup { set x {} +} -body { list [scan {0x} {%i%s} x y] $x $y -} {2 0 x} -test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} { +} -result {2 0 x} +test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup { set x {} +} -body { list [scan {0X} {%i%s} x y] $x $y -} {2 0 X} -test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} { +} -result {2 0 X} +test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} -setup { set x {} +} -body { list [scan {123def} {%*i%s} x] $x -} {1 def} +} -result {1 def} test scan-4.48 {Tcl_ScanObjCmd, float scanning} { list [scan {1 2 3} {%e %f %g} x y z] $x $y $z } {3 1.0 2.0 3.0} @@ -299,133 +390,134 @@ test scan-4.53 {Tcl_ScanObjCmd, float scanning} { test scan-4.54 {Tcl_ScanObjCmd, float scanning} { list [scan {1.0e-1} %f x] $x } {1 0.1} -test scan-4.55 {Tcl_ScanObjCmd, odd cases} { +test scan-4.55 {Tcl_ScanObjCmd, odd cases} -setup { set x {} +} -body { list [scan {+} %f x] $x -} {-1 {}} -test scan-4.56 {Tcl_ScanObjCmd, odd cases} { +} -result {-1 {}} +test scan-4.56 {Tcl_ScanObjCmd, odd cases} -setup { set x {} +} -body { list [scan {1.0e} %f%s x y] $x $y -} {2 1.0 e} -test scan-4.57 {Tcl_ScanObjCmd, odd cases} { +} -result {2 1.0 e} +test scan-4.57 {Tcl_ScanObjCmd, odd cases} -setup { set x {} +} -body { list [scan {1.0e+} %f%s x y] $x $y -} {2 1.0 e+} -test scan-4.58 {Tcl_ScanObjCmd, odd cases} { +} -result {2 1.0 e+} +test scan-4.58 {Tcl_ScanObjCmd, odd cases} -setup { set x {} set y {} +} -body { list [scan {e1} %f%s x y] $x $y -} {0 {} {}} +} -result {0 {} {}} test scan-4.59 {Tcl_ScanObjCmd, float scanning} { list [scan {1.0e-1x} %*f%n x] $x } {1 6} -test scan-4.60 {Tcl_ScanObjCmd, set errors} { +test scan-4.60 {Tcl_ScanObjCmd, set errors} -setup { set x {} set y {} - catch {unset z}; array set z {} - set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \ - $msg $x $y] - unset z - set result -} {1 {can't set "z": variable is array} abc ghi} -test scan-4.61 {Tcl_ScanObjCmd, set errors} { + unset -nocomplain z +} -body { + array set z {} + list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x $y +} -cleanup { + unset -nocomplain z +} -result {1 {can't set "z": variable is array} abc ghi} +test scan-4.61 {Tcl_ScanObjCmd, set errors} -setup { set x {} - catch {unset y}; array set y {} - catch {unset z}; array set z {} - set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \ - $msg $x] - unset y - unset z - set result -} {1 {can't set "z": variable is array} abc} - -# procedure that returns the range of integers - -proc int_range {} { - for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} { - set MIN_INT [expr { $MIN_INT << 1 }] - } - set MIN_INT [expr {int($MIN_INT)}] - set MAX_INT [expr { ~ $MIN_INT }] - return [list $MIN_INT $MAX_INT] -} + unset -nocomplain y + unset -nocomplain z +} -body { + array set y {} + array set z {} + list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x +} -cleanup { + unset -nocomplain y + unset -nocomplain z +} -result {1 {can't set "z": variable is array} abc} test scan-4.62 {scanning of large and negative octal integers} { - foreach { MIN_INT MAX_INT } [int_range] {} + lassign [int_range] MIN_INT MAX_INT set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT] list [scan $scanstring {%o %o %o} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} test scan-4.63 {scanning of large and negative hex integers} { - foreach { MIN_INT MAX_INT } [int_range] {} + lassign [int_range] MIN_INT MAX_INT set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT] list [scan $scanstring {%x %x %x} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} -# clean up from last two tests - -catch { - rename int_range {} -} - -test scan-5.1 {integer scanning} { +test scan-5.1 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d -} {4 -20 1476 33 0} -test scan-5.2 {integer scanning} { +} -result {4 -20 1476 33 0} +test scan-5.2 {integer scanning} -setup { set a {}; set b {}; set c {} +} -body { list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c -} {3 -4 16 7890} -test scan-5.3 {integer scanning} { +} -result {3 -4 16 7890} +test scan-5.3 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d -} {4 -45 16 10 987} -test scan-5.4 {integer scanning} { +} -result {4 -45 16 10 987} +test scan-5.4 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d -} {4 14 427 50 16} -test scan-5.5 {integer scanning} { +} -result {4 14 427 50 16} +test scan-5.5 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "12345670 1234567890ab cdefg" "%o %o %x %lx" a b c d] \ $a $b $c $d -} {4 2739128 342391 561323 52719} -test scan-5.6 {integer scanning} { +} -result {4 2739128 342391 561323 52719} +test scan-5.6 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d -} {4 171 291 -20 52} -test scan-5.7 {integer scanning} { +} -result {4 171 291 -20 52} +test scan-5.7 {integer scanning} -setup { set a {}; set b {} +} -body { list [scan "1234567 234 567 " "%*3x %x %*o %4o" a b] $a $b -} {2 17767 375} -test scan-5.8 {integer scanning} { +} -result {2 17767 375} +test scan-5.8 {integer scanning} -setup { set a {}; set b {} +} -body { list [scan "a 1234" "%d %d" a b] $a $b -} {0 {} {}} -test scan-5.9 {integer scanning} { - set a {}; set b {}; set c {}; set d {}; +} -result {0 {} {}} +test scan-5.9 {integer scanning} -setup { + set a {}; set b {}; set c {}; set d {} +} -body { list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d -} {4 12 34 56 78} -test scan-5.10 {integer scanning} { +} -result {4 12 34 56 78} +test scan-5.10 {integer scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d -} {2 1 2 {} {}} +} -result {2 1 2 {} {}} # -# The behavior for scaning intergers larger than MAX_INT is -# not defined by the ANSI spec. Some implementations wrap the -# input (-16) some return MAX_INT. +# The behavior for scaning intergers larger than MAX_INT is not defined by the +# ANSI spec. Some implementations wrap the input (-16) some return MAX_INT. # -test scan-5.11 {integer scanning} {nonPortable} { - set a {}; set b {}; +test scan-5.11 {integer scanning} -constraints {nonPortable} -setup { + set a {}; set b {} +} -body { list [scan "4294967280 4294967280" "%u %d" a b] $a \ [expr {$b == -16 || $b == 0x7fffffff}] -} {2 4294967280 1} -test scan-5.12 {integer scanning} {wideIs64bit} { +} -result {2 4294967280 1} +test scan-5.12 {integer scanning} -constraints {wideIs64bit} -setup { set a {}; set b {}; set c {} +} -body { list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \ %ld,%lx,%lo a b c] $a $b $c -} {3 7810179016327718216 7810179016327718216 7810179016327718216} +} -result {3 7810179016327718216 7810179016327718216 7810179016327718216} test scan-5.13 {integer scanning and overflow} { # This test used to fail on some 64-bit systems. [Bug 1011860] scan {300000000 3000000000 30000000000} {%ld %ld %ld} @@ -435,153 +527,184 @@ test scan-5.14 {integer scanning} { scan 0xff %u } 0 -test scan-6.1 {floating-point scanning} { +test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d -} {3 2.1 -300000000.0 0.99962 {}} -test scan-6.2 {floating-point scanning} { +} -result {3 2.1 -300000000.0 0.99962 {}} +test scan-6.2 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d -} {4 -1.0 234.0 5.0 8.2} -test scan-6.3 {floating-point scanning} { +} -result {4 -1.0 234.0 5.0 8.2} +test scan-6.3 {floating-point scanning} -setup { set a {}; set b {}; set c {} +} -body { list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c -} {3 10000.0 30000.0} +} -result {3 10000.0 30000.0} # -# Some libc implementations consider 3.e- bad input. The ANSI -# spec states that digits must follow the - sign. +# Some libc implementations consider 3.e- bad input. The ANSI spec states +# that digits must follow the - sign. # -test scan-6.4 {floating-point scanning} { +test scan-6.4 {floating-point scanning} -setup { set a {}; set b {}; set c {} +} -body { list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c -} {3 1.0 200.0 3.0} -test scan-6.5 {floating-point scanning} { +} -result {3 1.0 200.0 3.0} +test scan-6.5 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d -} {4 4.6 99999.7 87.643 118.0} -test scan-6.6 {floating-point scanning} { +} -result {4 4.6 99999.7 87.643 118.0} +test scan-6.6 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d -} {4 1.2345 0.697 124.0 5e-5} -test scan-6.7 {floating-point scanning} { +} -result {4 1.2345 0.697 124.0 5e-5} +test scan-6.7 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d -} {1 4.6 {} {} {}} -test scan-6.8 {floating-point scanning} { +} -result {1 4.6 {} {} {}} +test scan-6.8 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d -} {2 4.6 5.2 {} {}} +} -result {2 4.6 5.2 {} {}} -test scan-7.1 {string and character scanning} { +test scan-7.1 {string and character scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d -} {4 abc def ghijk dum} -test scan-7.2 {string and character scanning} { +} -result {4 abc def ghijk dum} +test scan-7.2 {string and character scanning} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "a bcdef" "%c%c%1s %s" a b c d] $a $b $c $d -} {4 97 32 b cdef} -test scan-7.3 {string and character scanning} { +} -result {4 97 32 b cdef} +test scan-7.3 {string and character scanning} -setup { set a {}; set b {}; set c {} +} -body { list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c -} {1 test {} {}} -test scan-7.4 {string and character scanning} { - set a {}; set b {}; set c {}; set d +} -result {1 test {} {}} +test scan-7.4 {string and character scanning} -setup { + set a {}; set b {}; set c {}; set d {} +} -body { list [scan "ababcd01234 f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d -} {4 abab cd {01234 } {f 12345}} -test scan-7.5 {string and character scanning} { +} -result {4 abab cd {01234 } {f 12345}} +test scan-7.5 {string and character scanning} -setup { set a {}; set b {}; set c {} +} -body { list [scan "aaaaaabc aaabcdefg + + XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c -} {3 aabc bcdefg 43} -test scan-7.6 {string and character scanning, unicode} { +} -result {3 aabc bcdefg 43} +test scan-7.6 {string and character scanning, unicode} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d -} "4 abc d\u00c7f ghijk dum" -test scan-7.7 {string and character scanning, unicode} { +} -result "4 abc d\u00c7f ghijk dum" +test scan-7.7 {string and character scanning, unicode} -setup { set a {}; set b {} +} -body { list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b -} "2 199 99" -test scan-7.8 {string and character scanning, unicode} { +} -result "2 199 99" +test scan-7.8 {string and character scanning, unicode} -setup { set a {}; set b {} +} -body { list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a -} "1 ab\ufeff" +} -result "1 ab\ufeff" -test scan-8.1 {error conditions} { - catch {scan a} -} 1 -test scan-8.2 {error conditions} { - catch {scan a} msg - set msg -} {wrong # args: should be "scan string format ?varName ...?"} -test scan-8.3 {error conditions} { - list [catch {scan a %D x} msg] $msg -} {1 {bad scan conversion character "D"}} -test scan-8.4 {error conditions} { - list [catch {scan a %O x} msg] $msg -} {1 {bad scan conversion character "O"}} -test scan-8.5 {error conditions} { - list [catch {scan a %X x} msg] $msg -} {1 {bad scan conversion character "X"}} -test scan-8.6 {error conditions} { - list [catch {scan a %F x} msg] $msg -} {1 {bad scan conversion character "F"}} -test scan-8.7 {error conditions} { - list [catch {scan a %E x} msg] $msg -} {1 {bad scan conversion character "E"}} -test scan-8.8 {error conditions} { - list [catch {scan a "%d %d" a} msg] $msg -} {1 {different numbers of variable names and field specifiers}} -test scan-8.9 {error conditions} { - list [catch {scan a "%d %d" a b c} msg] $msg -} {1 {variable is not assigned by any conversion specifiers}} -test scan-8.10 {error conditions} { +test scan-8.1 {error conditions} -body { + scan a +} -returnCodes error -match glob -result * +test scan-8.2 {error conditions} -returnCodes error -body { + scan a +} -result {wrong # args: should be "scan string format ?varName ...?"} +test scan-8.3 {error conditions} -returnCodes error -body { + scan a %D x +} -result {bad scan conversion character "D"} +test scan-8.4 {error conditions} -returnCodes error -body { + scan a %O x +} -result {bad scan conversion character "O"} +test scan-8.5 {error conditions} -returnCodes error -body { + scan a %X x +} -result {bad scan conversion character "X"} +test scan-8.6 {error conditions} -returnCodes error -body { + scan a %F x +} -result {bad scan conversion character "F"} +test scan-8.7 {error conditions} -returnCodes error -body { + scan a %E x +} -result {bad scan conversion character "E"} +test scan-8.8 {error conditions} -returnCodes error -body { + scan a "%d %d" a +} -result {different numbers of variable names and field specifiers} +test scan-8.9 {error conditions} -returnCodes error -body { + scan a "%d %d" a b c +} -result {variable is not assigned by any conversion specifiers} +test scan-8.10 {error conditions} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [expr {[scan " a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d -} {1 {} {} {} {}} -test scan-8.11 {error conditions} { +} -result {1 {} {} {} {}} +test scan-8.11 {error conditions} -setup { set a {}; set b {}; set c {}; set d {} +} -body { list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d -} {2 1 2 {} {}} -test scan-8.12 {error conditions} { - catch {unset a} +} -result {2 1 2 {} {}} +test scan-8.12 {error conditions} -setup { + unset -nocomplain a +} -body { set a(0) 44 - list [catch {scan 44 %d a} msg] $msg -} {1 {can't set "a": variable is array}} -test scan-8.13 {error conditions} { - catch {unset a} + scan 44 %d a +} -returnCodes error -cleanup { + unset -nocomplain a +} -result {can't set "a": variable is array} +test scan-8.13 {error conditions} -setup { + unset -nocomplain a +} -body { set a(0) 44 - list [catch {scan 44 %c a} msg] $msg -} {1 {can't set "a": variable is array}} -test scan-8.14 {error conditions} { - catch {unset a} + scan 44 %c a +} -returnCodes error -cleanup { + unset -nocomplain a +} -result {can't set "a": variable is array} +test scan-8.14 {error conditions} -setup { + unset -nocomplain a +} -body { set a(0) 44 - list [catch {scan 44 %s a} msg] $msg -} {1 {can't set "a": variable is array}} -test scan-8.15 {error conditions} { - catch {unset a} + scan 44 %s a +} -returnCodes error -cleanup { + unset -nocomplain a +} -result {can't set "a": variable is array} +test scan-8.15 {error conditions} -setup { + unset -nocomplain a +} -body { set a(0) 44 - list [catch {scan 44 %f a} msg] $msg -} {1 {can't set "a": variable is array}} -test scan-8.16 {error conditions} { - catch {unset a} + scan 44 %f a +} -returnCodes error -cleanup { + unset -nocomplain a +} -result {can't set "a": variable is array} +test scan-8.16 {error conditions} -setup { + unset -nocomplain a +} -body { set a(0) 44 - list [catch {scan 44 %f a} msg] $msg -} {1 {can't set "a": variable is array}} -catch {unset a} -test scan-8.17 {error conditions} { - list [catch {scan 44 %2c a} msg] $msg -} {1 {field width may not be specified in %c conversion}} -test scan-8.18 {error conditions} { - list [catch {scan abc {%[} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-8.19 {error conditions} { - list [catch {scan abc {%[^a} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-8.20 {error conditions} { - list [catch {scan abc {%[^]a} x} msg] $msg -} {1 {unmatched [ in format string}} -test scan-8.21 {error conditions} { - list [catch {scan abc {%[]a} x} msg] $msg -} {1 {unmatched [ in format string}} + scan 44 %f a +} -returnCodes error -cleanup { + unset -nocomplain a +} -result {can't set "a": variable is array} +test scan-8.17 {error conditions} -returnCodes error -body { + scan 44 %2c a +} -result {field width may not be specified in %c conversion} +test scan-8.18 {error conditions} -returnCodes error -body { + scan abc {%[} x +} -result {unmatched [ in format string} +test scan-8.19 {error conditions} -returnCodes error -body { + scan abc {%[^a} x +} -result {unmatched [ in format string} +test scan-8.20 {error conditions} -returnCodes error -body { + scan abc {%[^]a} x +} -result {unmatched [ in format string} +test scan-8.21 {error conditions} -returnCodes error -body { + scan abc {%[]a} x +} -result {unmatched [ in format string} test scan-9.1 {lots of arguments} { scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 @@ -591,27 +714,32 @@ test scan-9.2 {lots of arguments} { set a20 } 200 -test scan-10.1 {miscellaneous tests} { +test scan-10.1 {miscellaneous tests} -setup { set a {} +} -body { list [scan ab16c ab%dc a] $a -} {1 16} -test scan-10.2 {miscellaneous tests} { +} -result {1 16} +test scan-10.2 {miscellaneous tests} -setup { set a {} +} -body { list [scan ax16c ab%dc a] $a -} {0 {}} -test scan-10.3 {miscellaneous tests} { +} -result {0 {}} +test scan-10.3 {miscellaneous tests} -setup { set a {} +} -body { list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a -} {0 1 114} -test scan-10.4 {miscellaneous tests} { +} -result {0 1 114} +test scan-10.4 {miscellaneous tests} -setup { set a {} +} -body { list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a -} {0 1 14} -test scan-10.5 {miscellaneous tests} { - catch {unset arr} +} -result {0 1 14} +test scan-10.5 {miscellaneous tests} -setup { + unset -nocomplain arr +} -body { set arr(2) {} list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2) -} {0 1 14} +} -result {0 1 14} test scan-10.6 {miscellaneous tests} { scan 5a {%i%[a]} } {5 a} @@ -671,9 +799,9 @@ test scan-13.1 {Tcl_ScanObjCmd, inline XPG case} { test scan-13.2 {Tcl_ScanObjCmd, inline XPG case} { scan abc {%1$c%2$c%3$c%4$c} } {97 98 99 {}} -test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} { - list [catch {scan abc {%1$c%1$c}} msg] $msg -} {1 {variable is assigned by multiple "%n$" conversion specifiers}} +test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} -returnCodes error -body { + scan abc {%1$c%1$c} +} -result {variable is assigned by multiple "%n$" conversion specifiers} test scan-13.4 {Tcl_ScanObjCmd, inline XPG case} { scan abc {%2$s%1$c} } {{} abc} @@ -692,77 +820,20 @@ test scan-13.8 {Tcl_ScanObjCmd, inline XPG case lots of arguments} { list [llength $msg] [lindex $msg 99] [lindex $msg 4] [lindex $msg 199] } {200 10 20 30} -# Big test for correct ordering of data in [expr] - -proc testIEEE {} { - variable ieeeValues - binary scan [binary format dd -1.0 1.0] c* c - switch -exact -- $c { - {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { - # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ - ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ - ieeeValues(-Normal) - binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ - ieeeValues(-Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \ - ieeeValues(-0) - binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(+0) - binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ - ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ - ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ - ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ - ieeeValues(NaN) - set ieeeValues(littleEndian) 1 - return 1 - } - {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(-Normal) - binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(-Subnormal) - binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(-0) - binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(+0) - binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ - ieeeValues(NaN) - set ieeeValues(littleEndian) 0 - return 1 - } - default { - return 0 - } - } -} - -testConstraint ieeeFloatingPoint [testIEEE] - # scan infinities - not working -test scan-14.1 {infinity} { +test scan-14.1 {positive infinity} { scan Inf %g d - set d + return $d } Inf -test scan-14.2 {infinity} { +test scan-14.2 {negative infinity} { scan -Inf %g d - set d + return $d } -Inf # TODO - also need to scan NaN's + +catch {rename int_range {}} # cleanup ::tcltest::cleanupTests diff --git a/tests/set.test b/tests/set.test index 1d88553..18119f5 100644 --- a/tests/set.test +++ b/tests/set.test @@ -524,6 +524,11 @@ test set-5.1 {error on malformed array name} testset2 { list $msg $msg1 } {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}} +# In a mem-debug build, this test will crash unless Bug 3602706 is fixed. +test set-5.2 {Bug 3602706} -body { + testset2 ::tcl_platform not-in-there +} -returnCodes error -result * -match glob + # cleanup catch {unset a} catch {unset b} diff --git a/tests/stack.test b/tests/stack.test index 873cb08..13bc524 100644 --- a/tests/stack.test +++ b/tests/stack.test @@ -9,10 +9,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* # Note that a failure in this test may result in a crash of the executable. diff --git a/tests/string.test b/tests/string.test index f558d30..740cdc6 100644 --- a/tests/string.test +++ b/tests/string.test @@ -408,13 +408,15 @@ test string-6.35 {string is double, false} { test string-6.36 {string is double, false} { list [string is double -fail var "\n"] $var } {0 0} -test string-6.37 {string is double, false on int overflow} { +test string-6.37 {string is double, false on int overflow} -setup { + set var priorValue +} -body { # Make it the largest int recognizable, with one more digit for overflow # Since bignums arrived in Tcl 8.5, the sense of this test changed. # Now integer values that exceed native limits become bignums, and # bignums can convert to doubles without error. list [string is double -fail var [largest_int]0] $var -} {1 0} +} -result {1 priorValue} # string-6.38 removed, underflow on input is no longer an error. test string-6.39 {string is double, false} { # This test is non-portable because IRIX thinks diff --git a/tests/tcltest.test b/tests/tcltest.test index 86aca6f..ce8d617 100755 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -80,10 +80,7 @@ proc slave {msgVar args} { # Need to capture output in msg - set code [catch {i eval {source $argv0}} foo] -if $code { -#puts "$code: $foo\n$::errorInfo" -} + set code [catch {i eval {source $argv0}}] i eval {close $tcltest::outputChannel} interp delete [namespace current]::i set f [open $of] @@ -99,8 +96,6 @@ if $code { append msg \n$err } return $code - -# return [catch {uplevel 1 [linsert $args 0 exec [interpreter]]} msg] } test tcltest-2.0 {tcltest (verbose default - 'b')} {unixOrPc} { set result [slave msg test.tcl] @@ -549,7 +544,7 @@ set notWriteableDir [file join [temporaryDirectory] notwriteable] makeDirectory notreadable makeDirectory notwriteable switch -- $::tcl_platform(platform) { - "unix" { + unix { file attributes $notReadableDir -permissions 00333 file attributes $notWriteableDir -permissions 00555 } @@ -716,8 +711,8 @@ test tcltest-8.60 {::workingDirectory} { # clean up from directory testing -switch $::tcl_platform(platform) { - "unix" { +switch -- $::tcl_platform(platform) { + unix { file attributes $notReadableDir -permissions 777 file attributes $notWriteableDir -permissions 777 } @@ -727,7 +722,7 @@ switch $::tcl_platform(platform) { } } -file delete -force $notReadableDir $notWriteableDir +file delete -force -- $notReadableDir $notWriteableDir removeFile a.tcl removeFile thisdirectoryisafile removeDirectory normaldirectory @@ -1150,7 +1145,7 @@ test tcltest-19.1 {TCLTEST_OPTIONS default} -setup { } -cleanup { interp delete slave2 interp delete slave1 - if {$oldoptions == "none"} { + if {$oldoptions eq "none"} { unset ::env(TCLTEST_OPTIONS) } else { set ::env(TCLTEST_OPTIONS) $oldoptions diff --git a/tests/thread.test b/tests/thread.test index d79f693..f32ef61 100644 --- a/tests/thread.test +++ b/tests/thread.test @@ -84,28 +84,6 @@ if {[testConstraint testthread]} { } testthread errorproc ThreadError - - set mainThread [testthread id] - - proc ThreadNullError {id info} { - # ignore - } - - proc threadReap {} { - testthread errorproc ThreadNullError - while {[llength [testthread names]] > 1} { - foreach tid [testthread names] { - if {$tid != [testthread id]} { - catch { - testthread send -async $tid {testthread exit} - } - } - } - after 1 - } - testthread errorproc ThreadError - return [llength [testthread names]] - } } # Some tests require manual draining of the event queue diff --git a/tests/tm.test b/tests/tm.test index 149a65d..1b22f8c 100644 --- a/tests/tm.test +++ b/tests/tm.test @@ -200,7 +200,7 @@ test tm-3.11 {tm: module path management, remove ignores unknown path} -setup { proc genpaths {base} { # Normalizing picks up drive letters on windows [Bug 1053568] set base [file normalize $base] - foreach {major minor} [split [info tclversion] .] break + lassign [split [package present Tcl] .] major minor set results {} set base [file join $base tcl$major] lappend results [file join $base site-tcl] diff --git a/tests/trace.test b/tests/trace.test index 0f48dcf..a3a5604 100644 --- a/tests/trace.test +++ b/tests/trace.test @@ -11,10 +11,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest +namespace import ::tcltest::* ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] @@ -32,15 +30,15 @@ proc getbytes {} { proc traceScalar {name1 name2 op} { global info - set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg] + set info [list $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg] } proc traceScalarAppend {name1 name2 op} { global info - lappend info $name1 $name2 $op [catch {uplevel set $name1} msg] $msg + lappend info $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg } proc traceArray {name1 name2 op} { global info - set info [list $name1 $name2 $op [catch {uplevel set [set name1]($name2)} msg] $msg] + set info [list $name1 $name2 $op [catch {uplevel 1 set [set name1]($name2)} msg] $msg] } proc traceArray2 {name1 name2 op} { global info @@ -62,7 +60,7 @@ proc traceCheck {cmd args} { set info [list [catch $cmd msg] $msg] } proc traceCrtElement {value name1 name2 op} { - uplevel set ${name1}($name2) $value + uplevel 1 set ${name1}($name2) $value } proc traceCommand {oldName newName op} { global info @@ -72,10 +70,10 @@ proc traceCommand {oldName newName op} { test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} { # You may need Purify or Electric Fence to reliably # see this one fail. - catch {unset z} + unset -nocomplain z trace add variable z array {set z(foo) 1 ;#} set res "names: [array names z]" - catch {unset ::z} + unset -nocomplain ::z trace variable ::z w {unset ::z; error "memory corruption";#} list [catch {set ::z 1} msg] $msg } {1 {can't set "::z": memory corruption}} @@ -83,40 +81,40 @@ test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} { # Read-tracing on variables test trace-1.1 {trace variable reads} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read traceScalar list [catch {set x} msg] $msg $info } {1 {can't read "x": no such variable} {x {} read 1 {can't read "x": no such variable}}} test trace-1.2 {trace variable reads} { - catch {unset x} + unset -nocomplain x set x 123 set info {} trace add variable x read traceScalar list [catch {set x} msg] $msg $info } {0 123 {x {} read 0 123}} test trace-1.3 {trace variable reads} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read traceScalar set x 123 set info } {} test trace-1.4 {trace array element reads} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(2) read traceArray list [catch {set x(2)} msg] $msg $info } {1 {can't read "x(2)": no such element in array} {x 2 read 1 {can't read "x(2)": no such element in array}}} test trace-1.5 {trace array element reads} { - catch {unset x} + unset -nocomplain x set x(2) zzz set info {} trace add variable x(2) read traceArray list [catch {set x(2)} msg] $msg $info } {0 zzz {x 2 read 0 zzz}} test trace-1.6 {trace array element reads} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read traceArray2 proc p {} { @@ -127,7 +125,7 @@ test trace-1.6 {trace array element reads} { list [catch {p} msg] $msg $info } {0 willi {x 2 read}} test trace-1.7 {trace array element reads, create element undefined if nonexistant} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read q proc q {name1 name2 op} { @@ -144,20 +142,20 @@ test trace-1.7 {trace array element reads, create element undefined if nonexista list [catch {p} msg] $msg $info } {0 wolf {x Y read}} test trace-1.8 {trace reads on whole arrays} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read traceArray list [catch {set x(2)} msg] $msg $info } {1 {can't read "x(2)": no such variable} {}} test trace-1.9 {trace reads on whole arrays} { - catch {unset x} + unset -nocomplain x set x(2) zzz set info {} trace add variable x read traceArray list [catch {set x(2)} msg] $msg $info } {0 zzz {x 2 read 0 zzz}} test trace-1.10 {trace variable reads} { - catch {unset x} + unset -nocomplain x set x 444 set info {} trace add variable x read traceScalar @@ -165,28 +163,28 @@ test trace-1.10 {trace variable reads} { set info } {} test trace-1.11 {read traces that modify the array structure} { - catch {unset x} + unset -nocomplain x set x(bar) 0 trace variable x r {set x(foo) 1 ;#} trace variable x r {unset -nocomplain x(bar) ;#} array get x } {} test trace-1.12 {read traces that modify the array structure} { - catch {unset x} + unset -nocomplain x set x(bar) 0 trace variable x r {unset -nocomplain x(bar) ;#} trace variable x r {set x(foo) 1 ;#} array get x } {} test trace-1.13 {read traces that modify the array structure} { - catch {unset x} + unset -nocomplain x set x(bar) 0 trace variable x r {set x(foo) 1 ;#} trace variable x r {unset -nocomplain x;#} list [catch {array get x} res] $res } {1 {can't read "x(bar)": no such variable}} test trace-1.14 {read traces that modify the array structure} { - catch {unset x} + unset -nocomplain x set x(bar) 0 trace variable x r {unset -nocomplain x;#} trace variable x r {set x(foo) 1 ;#} @@ -196,28 +194,28 @@ test trace-1.14 {read traces that modify the array structure} { # Basic write-tracing on variables test trace-2.1 {trace variable writes} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceScalar set x 123 set info } {x {} write 0 123} test trace-2.2 {trace writes to array elements} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(33) write traceArray set x(33) 444 set info } {x 33 write 0 444} test trace-2.3 {trace writes on whole arrays} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceArray set x(abc) qq set info } {x abc write 0 qq} test trace-2.4 {trace variable writes} { - catch {unset x} + unset -nocomplain x set x 1234 set info {} trace add variable x write traceScalar @@ -225,7 +223,7 @@ test trace-2.4 {trace variable writes} { set info } {} test trace-2.5 {trace variable writes} { - catch {unset x} + unset -nocomplain x set x 1234 set info {} trace add variable x write traceScalar @@ -238,7 +236,7 @@ test trace-2.6 {trace variable writes on compiled local} { # arrays [Bug 1770591]. The corresponding function for read traces is # already indirectly tested in trace-1.7 # - catch {unset x} + unset -nocomplain x set info {} proc p {} { trace add variable x write traceArray @@ -267,7 +265,7 @@ test trace-2.7 {trace variable writes on errorInfo} -body { # trace: after appending all arguments to the list. test trace-3.1 {trace variable read-modify-writes} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read traceScalarAppend append x 123 @@ -276,7 +274,7 @@ test trace-3.1 {trace variable read-modify-writes} { set info } {x {} read 0 123456} test trace-3.2 {trace variable read-modify-writes} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x {read write} traceScalarAppend append x 123 @@ -287,14 +285,14 @@ test trace-3.2 {trace variable read-modify-writes} { # Basic unset-tracing on variables test trace-4.1 {trace variable unsets} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x unset traceScalar - catch {unset x} + unset -nocomplain x set info } {x {} unset 1 {can't read "x": no such variable}} test trace-4.2 {variable mustn't exist during unset trace} { - catch {unset x} + unset -nocomplain x set x 1234 set info {} trace add variable x unset traceScalar @@ -302,7 +300,7 @@ test trace-4.2 {variable mustn't exist during unset trace} { set info } {x {} unset 1 {can't read "x": no such variable}} test trace-4.3 {unset traces mustn't be called during reads and writes} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x unset traceScalar set x 44 @@ -310,15 +308,15 @@ test trace-4.3 {unset traces mustn't be called during reads and writes} { set info } {} test trace-4.4 {trace unsets on array elements} { - catch {unset x} + unset -nocomplain x set x(0) 18 set info {} trace add variable x(1) unset traceArray - catch {unset x(1)} + unset -nocomplain x(1) set info } {x 1 unset 1 {can't read "x(1)": no such element in array}} test trace-4.5 {trace unsets on array elements} { - catch {unset x} + unset -nocomplain x set x(1) 18 set info {} trace add variable x(1) unset traceArray @@ -326,7 +324,7 @@ test trace-4.5 {trace unsets on array elements} { set info } {x 1 unset 1 {can't read "x(1)": no such element in array}} test trace-4.6 {trace unsets on array elements} { - catch {unset x} + unset -nocomplain x set x(1) 18 set info {} trace add variable x(1) unset traceArray @@ -334,15 +332,15 @@ test trace-4.6 {trace unsets on array elements} { set info } {x 1 unset 1 {can't read "x(1)": no such variable}} test trace-4.7 {trace unsets on whole arrays} { - catch {unset x} + unset -nocomplain x set x(1) 18 set info {} trace add variable x unset traceProc - catch {unset x(0)} + unset -nocomplain x(0) set info } {} test trace-4.8 {trace unsets on whole arrays} { - catch {unset x} + unset -nocomplain x set x(1) 18 set x(2) 144 set x(3) 14 @@ -352,7 +350,7 @@ test trace-4.8 {trace unsets on whole arrays} { set info } {x 1 unset} test trace-4.9 {trace unsets on whole arrays} { - catch {unset x} + unset -nocomplain x set x(1) 18 set x(2) 144 set x(3) 14 @@ -364,7 +362,7 @@ test trace-4.9 {trace unsets on whole arrays} { # Array tracing on variables test trace-5.1 {array traces fire on accesses via [array]} { - catch {unset x} + unset -nocomplain x set x(b) 2 trace add variable x array traceArray2 set ::info {} @@ -372,7 +370,7 @@ test trace-5.1 {array traces fire on accesses via [array]} { set ::info } {x {} array} test trace-5.2 {array traces do not fire on normal accesses} { - catch {unset x} + unset -nocomplain x set x(b) 2 trace add variable x array traceArray2 set ::info {} @@ -381,7 +379,7 @@ test trace-5.2 {array traces do not fire on normal accesses} { set ::info } {} test trace-5.3 {array traces do not outlive variable} { - catch {unset x} + unset -nocomplain x trace add variable x array traceArray2 set ::info {} set x(a) 1 @@ -390,19 +388,19 @@ test trace-5.3 {array traces do not outlive variable} { set ::info } {} test trace-5.4 {array traces properly listed in trace information} { - catch {unset x} + unset -nocomplain x trace add variable x array traceArray2 set result [trace info variable x] set result } [list [list array traceArray2]] test trace-5.5 {array traces properly listed in trace information} { - catch {unset x} + unset -nocomplain x trace variable x a traceArray2 set result [trace vinfo x] set result } [list [list a traceArray2]] test trace-5.6 {array traces don't fire on scalar variables} { - catch {unset x} + unset -nocomplain x set x foo trace add variable x array traceArray2 set ::info {} @@ -410,14 +408,14 @@ test trace-5.6 {array traces don't fire on scalar variables} { set ::info } {} test trace-5.7 {array traces fire for undefined variables} { - catch {unset x} + unset -nocomplain x trace add variable x array traceArray2 set ::info {} array set x {a 1} set ::info } {x {} array} test trace-5.8 {array traces fire for undefined variables} { - catch {unset x} + unset -nocomplain x trace add variable x array {set x(foo) 1 ;#} set res "names: [array names x]" } {names: foo} @@ -425,7 +423,7 @@ test trace-5.8 {array traces fire for undefined variables} { # Trace multiple trace types at once. test trace-6.1 {multiple ops traced at once} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x {read write unset} traceProc catch {set x} @@ -436,7 +434,7 @@ test trace-6.1 {multiple ops traced at once} { set info } {x {} read x {} write x {} read x {} write x {} unset} test trace-6.2 {multiple ops traced on array element} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(0) {read write unset} traceProc catch {set x(0)} @@ -448,7 +446,7 @@ test trace-6.2 {multiple ops traced on array element} { set info } {x 0 read x 0 write x 0 read x 0 write x 0 unset} test trace-6.3 {multiple ops traced on whole array} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x {read write unset} traceProc catch {set x(0)} @@ -463,7 +461,7 @@ test trace-6.3 {multiple ops traced on whole array} { # Check order of invocation of traces test trace-7.1 {order of invocation of traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x read "traceTag 1" trace add variable x read "traceTag 2" @@ -474,7 +472,7 @@ test trace-7.1 {order of invocation of traces} { set info } {3 2 1 3 2 1} test trace-7.2 {order of invocation of traces} { - catch {unset x} + unset -nocomplain x set x(0) 44 set info {} trace add variable x(0) read "traceTag 1" @@ -484,7 +482,7 @@ test trace-7.2 {order of invocation of traces} { set info } {3 2 1} test trace-7.3 {order of invocation of traces} { - catch {unset x} + unset -nocomplain x set x(0) 44 set info {} trace add variable x(0) read "traceTag 1" @@ -500,7 +498,7 @@ test trace-7.3 {order of invocation of traces} { # Check effects of errors in trace procedures test trace-8.1 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x 123 set info {} trace add variable x read "traceTag 1" @@ -508,7 +506,7 @@ test trace-8.1 {error returns from traces} { list [catch {set x} msg] $msg $info } {1 {can't read "x": trace returned error} {}} test trace-8.2 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x 123 set info {} trace add variable x write "traceTag 1" @@ -516,14 +514,14 @@ test trace-8.2 {error returns from traces} { list [catch {set x 44} msg] $msg $info } {1 {can't set "x": trace returned error} {}} test trace-8.3 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x 123 set info {} trace add variable x write traceError list [catch {append x 44} msg] $msg $info } {1 {can't set "x": trace returned error} {}} test trace-8.4 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x 123 set info {} trace add variable x unset "traceTag 1" @@ -531,7 +529,7 @@ test trace-8.4 {error returns from traces} { list [catch {unset x} msg] $msg $info } {0 {} 1} test trace-8.5 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x(0) 123 set info {} trace add variable x(0) read "traceTag 1" @@ -541,7 +539,7 @@ test trace-8.5 {error returns from traces} { list [catch {set x(0)} msg] $msg $info } {1 {can't read "x(0)": trace returned error} 3} test trace-8.6 {error returns from traces} { - catch {unset x} + unset -nocomplain x set x 123 trace add variable x unset traceError list [catch {unset x} msg] $msg @@ -550,7 +548,7 @@ test trace-8.7 {error returns from traces} { # This test just makes sure that the memory for the error message # gets deallocated correctly when the trace is invoked again or # when the trace is deleted. - catch {unset x} + unset -nocomplain x set x 123 trace add variable x read traceError catch {set x} @@ -571,7 +569,7 @@ test trace-8.8 {error returns from traces} { trace add variable ::x write [list foo $::x] error "foo" } - catch {unset ::x ::y} + unset -nocomplain ::x ::y set x junk trace add variable ::x write [list foo $x] for {set y 0} {$y<100} {incr y} { @@ -585,31 +583,31 @@ test trace-8.8 {error returns from traces} { # a new copy of the variables. test trace-9.1 {be sure variable is unset before trace is called} { - catch {unset x} + unset -nocomplain x set x 33 set info {} - trace add variable x unset {traceCheck {uplevel set x}} + trace add variable x unset {traceCheck {uplevel 1 set x}} unset x set info } {1 {can't read "x": no such variable}} test trace-9.2 {be sure variable is unset before trace is called} { - catch {unset x} + unset -nocomplain x set x 33 set info {} - trace add variable x unset {traceCheck {uplevel set x 22}} + trace add variable x unset {traceCheck {uplevel 1 set x 22}} unset x concat $info [list [catch {set x} msg] $msg] } {0 22 0 22} test trace-9.3 {be sure traces are cleared before unset trace called} { - catch {unset x} + unset -nocomplain x set x 33 set info {} - trace add variable x unset {traceCheck {uplevel trace info variable x}} + trace add variable x unset {traceCheck {uplevel 1 trace info variable x}} unset x set info } {0 {}} test trace-9.4 {set new trace during unset trace} { - catch {unset x} + unset -nocomplain x set x 33 set info {} trace add variable x unset {traceCheck {global x; trace add variable x unset traceProc}} @@ -618,23 +616,23 @@ test trace-9.4 {set new trace during unset trace} { } {0 {} {unset traceProc}} test trace-10.1 {make sure array elements are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(0) 33 set info {} - trace add variable x(0) unset {traceCheck {uplevel set x(0)}} + trace add variable x(0) unset {traceCheck {uplevel 1 set x(0)}} unset x(0) set info } {1 {can't read "x(0)": no such element in array}} test trace-10.2 {make sure array elements are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(0) 33 set info {} - trace add variable x(0) unset {traceCheck {uplevel set x(0) zzz}} + trace add variable x(0) unset {traceCheck {uplevel 1 set x(0) zzz}} unset x(0) concat $info [list [catch {set x(0)} msg] $msg] } {0 zzz 0 zzz} test trace-10.3 {array elements are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(0) 33 set info {} trace add variable x(0) unset {traceCheck {global x; trace info variable x(0)}} @@ -642,49 +640,49 @@ test trace-10.3 {array elements are unset before traces are called} { set info } {0 {}} test trace-10.4 {set new array element trace during unset trace} { - catch {unset x} + unset -nocomplain x set x(0) 33 set info {} - trace add variable x(0) unset {traceCheck {uplevel {trace add variable x(0) read {}}}} - catch {unset x(0)} + trace add variable x(0) unset {traceCheck {uplevel 1 {trace add variable x(0) read {}}}} + unset -nocomplain x(0) concat $info [trace info variable x(0)] } {0 {} {read {}}} test trace-11.1 {make sure arrays are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(0) 33 set info {} - trace add variable x unset {traceCheck {uplevel set x(0)}} + trace add variable x unset {traceCheck {uplevel 1 set x(0)}} unset x set info } {1 {can't read "x(0)": no such variable}} test trace-11.2 {make sure arrays are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(y) 33 set info {} - trace add variable x unset {traceCheck {uplevel set x(y) 22}} + trace add variable x unset {traceCheck {uplevel 1 set x(y) 22}} unset x concat $info [list [catch {set x(y)} msg] $msg] } {0 22 0 22} test trace-11.3 {make sure arrays are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(y) 33 set info {} - trace add variable x unset {traceCheck {uplevel array exists x}} + trace add variable x unset {traceCheck {uplevel 1 array exists x}} unset x set info } {0 0} test trace-11.4 {make sure arrays are unset before traces are called} { - catch {unset x} + unset -nocomplain x set x(y) 33 set info {} - set cmd {traceCheck {uplevel {trace info variable x}}} + set cmd {traceCheck {uplevel 1 {trace info variable x}}} trace add variable x unset $cmd unset x set info } {0 {}} test trace-11.5 {set new array trace during unset trace} { - catch {unset x} + unset -nocomplain x set x(y) 33 set info {} trace add variable x unset {traceCheck {global x; trace add variable x read {}}} @@ -692,7 +690,7 @@ test trace-11.5 {set new array trace during unset trace} { concat $info [trace info variable x] } {0 {} {read {}}} test trace-11.6 {create scalar during array unset trace} { - catch {unset x} + unset -nocomplain x set x(y) 33 set info {} trace add variable x unset {traceCheck {global x; set x 44}} @@ -703,52 +701,52 @@ test trace-11.6 {create scalar during array unset trace} { # Check special conditions (e.g. errors) in Tcl_TraceVar2. test trace-12.1 {creating array when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(0) write traceProc list [catch {set x 22} msg] $msg } {1 {can't set "x": variable is array}} test trace-12.2 {creating array when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(0) write traceProc list [catch {set x(0)} msg] $msg } {1 {can't read "x(0)": no such element in array}} test trace-12.3 {creating array when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x(0) write traceProc set x(0) 22 set info } {x 0 write} test trace-12.4 {creating variable when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceProc list [catch {set x} msg] $msg } {1 {can't read "x": no such variable}} test trace-12.5 {creating variable when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceProc set x 22 set info } {x {} write} test trace-12.6 {creating variable when setting variable traces} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceProc set x(0) 22 set info } {x 0 write} test trace-12.7 {create array element during read trace} { - catch {unset x} + unset -nocomplain x set x(2) zzz trace add variable x read {traceCrtElement xyzzy} list [catch {set x(3)} msg] $msg } {0 xyzzy} test trace-12.8 {errors when setting variable traces} { - catch {unset x} + unset -nocomplain x set x 44 list [catch {trace add variable x(0) write traceProc} msg] $msg } {1 {can't trace "x(0)": variable isn't array}} @@ -762,7 +760,7 @@ test trace-13.1 {delete one trace from another} { trace remove variable x read {traceTag 3} trace remove variable x read {traceTag 4} } - catch {unset x} + unset -nocomplain x set x 44 set info {} trace add variable x read {traceTag 1} @@ -916,13 +914,13 @@ test trace-14.11 {trace command, "trace variable" errors} { test trace-14.12 {trace command ("remove variable" option)} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceProc trace remove variable x write traceProc } {} test trace-14.13 {trace command ("remove variable" option)} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write traceProc trace remove variable x write traceProc @@ -930,7 +928,7 @@ test trace-14.13 {trace command ("remove variable" option)} { set info } {} test trace-14.14 {trace command ("remove variable" option)} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write {traceTag 1} trace add variable x write traceProc @@ -945,7 +943,7 @@ test trace-14.14 {trace command ("remove variable" option)} { set info } {2 x {} write 1 2 1 2} test trace-14.15 {trace command ("remove variable" option)} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write {traceTag 1} trace remove variable x write non_existent @@ -953,27 +951,27 @@ test trace-14.15 {trace command ("remove variable" option)} { set info } {1} test trace-14.16 {trace command ("info variable" option)} { - catch {unset x} + unset -nocomplain x trace add variable x write {traceTag 1} trace add variable x write traceProc trace add variable x write {traceTag 2} trace info variable x } {{write {traceTag 2}} {write traceProc} {write {traceTag 1}}} test trace-14.17 {trace command ("info variable" option)} { - catch {unset x} + unset -nocomplain x trace info variable x } {} test trace-14.18 {trace command ("info variable" option)} { - catch {unset x} + unset -nocomplain x trace info variable x(0) } {} test trace-14.19 {trace command ("info variable" option)} { - catch {unset x} + unset -nocomplain x set x 44 trace info variable x(0) } {} test trace-14.20 {trace command ("info variable" option)} { - catch {unset x} + unset -nocomplain x set x 44 trace add variable x write {traceTag 1} proc check {} {global x; trace info variable x} @@ -983,7 +981,7 @@ test trace-14.20 {trace command ("info variable" option)} { # Check fancy trace commands (long ones, weird arguments, etc.) test trace-15.1 {long trace command} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x write {traceTag {This is a very very long argument. It's \ designed to test out the facilities of TraceVarProc for dealing \ @@ -1001,14 +999,14 @@ test trace-15.2 {long trace command result to ignore} { proc longResult {args} {return "quite a bit of text, designed to generate a core leak if this command file is invoked over and over again and memory isn't being recycled correctly"} - catch {unset x} + unset -nocomplain x trace add variable x write longResult set x 44 set x 5 set x abcde } abcde test trace-15.3 {special list-handling in trace commands} { - catch {unset "x y z"} + unset -nocomplain "x y z" set "x y z(a\n\{)" 44 set info {} trace add variable "x y z(a\n\{)" write traceProc @@ -1020,18 +1018,18 @@ test trace-15.3 {special list-handling in trace commands} { proc traceUnset {unsetName args} { global info - upvar $unsetName x + upvar 1 $unsetName x lappend info [catch {unset x} msg] $msg [catch {set x} msg] $msg } proc traceReset {unsetName resetName args} { global info - upvar $unsetName x $resetName y + upvar 1 $unsetName x $resetName y lappend info [catch {unset x} msg] $msg [catch {set y xyzzy} msg] $msg } proc traceReset2 {unsetName resetName args} { global info - lappend info [catch {uplevel unset $unsetName} msg] $msg \ - [catch {uplevel set $resetName xyzzy} msg] $msg + lappend info [catch {uplevel 1 unset $unsetName} msg] $msg \ + [catch {uplevel 1 set $resetName xyzzy} msg] $msg } proc traceAppend {string name1 name2 op} { global info @@ -1039,7 +1037,7 @@ proc traceAppend {string name1 name2 op} { } test trace-16.1 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y read {traceUnset y} @@ -1047,49 +1045,49 @@ test trace-16.1 {unsets during read traces} { lappend info [catch {set y} msg] $msg } {unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}} test trace-16.2 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceUnset y(0)} lappend info [catch {set y(0)} msg] $msg } {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such element in array}} test trace-16.3 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceUnset y} lappend info [catch {set y(0)} msg] $msg } {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}} test trace-16.4 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y read {traceReset y y} lappend info [catch {set y} msg] $msg } {0 {} 0 xyzzy 0 xyzzy} test trace-16.5 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceReset y(0) y(0)} lappend info [catch {set y(0)} msg] $msg } {0 {} 0 xyzzy 0 xyzzy} test trace-16.6 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceReset y y(0)} lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 1 {can't set "y": upvar refers to element in deleted array} 1 {can't read "y(0)": no such variable} 1 {can't read "y(0)": no such variable}} test trace-16.7 {unsets during read traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceReset2 y y(0)} lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 0 xyzzy 1 {can't read "y(0)": no such element in array} 0 xyzzy} test trace-16.8 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y write {traceUnset y} @@ -1097,91 +1095,91 @@ test trace-16.8 {unsets during write traces} { lappend info [catch {set y xxx} msg] $msg } {unset 0 {} 1 {can't read "x": no such variable} 0 {}} test trace-16.9 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) write {traceUnset y(0)} lappend info [catch {set y(0) xxx} msg] $msg } {0 {} 1 {can't read "x": no such variable} 0 {}} test trace-16.10 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) write {traceUnset y} lappend info [catch {set y(0) xxx} msg] $msg } {0 {} 1 {can't read "x": no such variable} 0 {}} test trace-16.11 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y write {traceReset y y} lappend info [catch {set y xxx} msg] $msg } {0 {} 0 xyzzy 0 xyzzy} test trace-16.12 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) write {traceReset y(0) y(0)} lappend info [catch {set y(0) xxx} msg] $msg } {0 {} 0 xyzzy 0 xyzzy} test trace-16.13 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) write {traceReset y y(0)} lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 1 {can't set "y": upvar refers to element in deleted array} 0 {} 1 {can't read "y(0)": no such variable}} test trace-16.14 {unsets during write traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) write {traceReset2 y y(0)} lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 0 xyzzy 0 {} 0 xyzzy} test trace-16.15 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y unset {traceUnset y} lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg } {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y": no such variable}} test trace-16.16 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) unset {traceUnset y(0)} lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg } {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such element in array}} test trace-16.17 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) unset {traceUnset y} lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such variable}} test trace-16.18 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y unset {traceReset2 y y} lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg } {1 {can't unset "y": no such variable} 0 xyzzy 0 {} 0 xyzzy} test trace-16.19 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) unset {traceReset2 y(0) y(0)} lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg } {1 {can't unset "y(0)": no such element in array} 0 xyzzy 0 {} 0 xyzzy} test trace-16.20 {unsets during unset traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) unset {traceReset2 y y(0)} lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg } {0 {} 0 xyzzy 0 {} 0 xyzzy} test trace-16.21 {unsets cancelling traces} { - catch {unset y} + unset -nocomplain y set y 1234 set info {} trace add variable y read {traceAppend first} @@ -1191,7 +1189,7 @@ test trace-16.21 {unsets cancelling traces} { lappend info [catch {set y} msg] $msg } {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}} test trace-16.22 {unsets cancelling traces} { - catch {unset y} + unset -nocomplain y set y(0) 1234 set info {} trace add variable y(0) read {traceAppend first} @@ -1204,19 +1202,19 @@ test trace-16.22 {unsets cancelling traces} { # Check various non-interference between traces and other things. test trace-17.1 {trace doesn't prevent unset errors} { - catch {unset x} + unset -nocomplain x set info {} trace add variable x unset {traceProc} list [catch {unset x} msg] $msg $info } {1 {can't unset "x": no such variable} {x {} unset}} test trace-17.2 {traced variables must survive procedure exits} { - catch {unset x} + unset -nocomplain x proc p1 {} {global x; trace add variable x write traceProc} p1 trace info variable x } {{write traceProc}} test trace-17.3 {traced variables must survive procedure exits} { - catch {unset x} + unset -nocomplain x set info {} proc p1 {} {global x; trace add variable x write traceProc} p1 @@ -1229,7 +1227,7 @@ test trace-17.3 {traced variables must survive procedure exits} { test trace-18.1 {unset traces on procedure returns} { proc p1 {x y} {set a 44; p2 14} - proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel {info vars}]}}} + proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel 1 {info vars}]}}} set info {} p1 foo bar set info @@ -1269,8 +1267,7 @@ test trace-18.4 {namespace delete / trace vdelete combo, Bug \#1338280} { # Delete arrays when done, so they can be re-used as scalars # elsewhere. -catch {unset x} -catch {unset y} +unset -nocomplain x y test trace-19.0.1 {trace add command (command existence)} { # Just in case! @@ -1312,6 +1309,7 @@ test trace-19.3 {command rename traces don't fire on command deletion} { test trace-19.4 {trace add command rename doesn't trace recreated commands} { proc foo {} {} catch {rename bar {}} + set info {} trace add command foo rename traceCommand proc foo {} {} rename foo bar @@ -1324,25 +1322,49 @@ test trace-19.5 {trace add command deleted removes traces} { trace info command foo } {} -namespace eval tc {} -proc tc::tcfoo {} {} -test trace-19.6 {trace add command rename in namespace} { +test trace-19.6 {trace add command rename in namespace} -setup { + namespace eval tc {} + proc tc::tcfoo {} {} +} -body { trace add command tc::tcfoo rename traceCommand rename tc::tcfoo tc::tcbar set info -} {::tc::tcfoo ::tc::tcbar rename} -test trace-19.7 {trace add command rename in namespace back again} { +} -cleanup { + namespace delete tc +} -result {::tc::tcfoo ::tc::tcbar rename} +test trace-19.7 {trace add command rename in namespace back again} -setup { + namespace eval tc {} + proc tc::tcfoo {} {} +} -body { + trace add command tc::tcfoo rename traceCommand + rename tc::tcfoo tc::tcbar rename tc::tcbar tc::tcfoo set info -} {::tc::tcbar ::tc::tcfoo rename} -test trace-19.8 {trace add command rename in namespace to out of namespace} { +} -cleanup { + namespace delete tc +} -result {::tc::tcbar ::tc::tcfoo rename} +test trace-19.8 {trace add command rename in namespace to out of namespace} -setup { + namespace eval tc {} + proc tc::tcfoo {} {} +} -body { + trace add command tc::tcfoo rename traceCommand rename tc::tcfoo tcbar set info -} {::tc::tcfoo ::tcbar rename} -test trace-19.9 {trace add command rename back into namespace} { +} -cleanup { + catch {rename tcbar {}} + namespace delete tc +} -result {::tc::tcfoo ::tcbar rename} +test trace-19.9 {trace add command rename back into namespace} -setup { + namespace eval tc {} + proc tc::tcfoo {} {} +} -body { + trace add command tc::tcfoo rename traceCommand + rename tc::tcfoo tcbar rename tcbar tc::tcfoo set info -} {::tcbar ::tc::tcfoo rename} +} -cleanup { + namespace delete tc +} -result {::tcbar ::tc::tcfoo rename} test trace-19.10 {trace add command failed rename doesn't trigger trace} { set info {} proc foo {} {} @@ -1353,11 +1375,18 @@ test trace-19.10 {trace add command failed rename doesn't trigger trace} { } {} catch {rename foo {}} catch {rename bar {}} -test trace-19.11 {trace add command qualifies when renamed in namespace} { + +test trace-19.11 {trace add command qualifies when renamed in namespace} -setup { + namespace eval tc {} + proc tc::tcfoo {} {} +} -body { set info {} + trace add command tc::tcfoo {rename delete} traceCommand namespace eval tc {rename tcfoo tcbar} set info -} {::tc::tcfoo ::tc::tcbar rename} +} -cleanup { + namespace delete tc +} -result {::tc::tcfoo ::tc::tcbar rename} # Make sure it exists again proc foo {} {} @@ -1542,8 +1571,7 @@ proc foo {b} { set a $b } # Delete arrays when done, so they can be re-used as scalars # elsewhere. -catch {unset x} -catch {unset y} +unset -nocomplain x y # Delete procedures when done, so we don't clash with other tests # (e.g. foobar will clash with 'unknown' tests). @@ -1674,6 +1702,16 @@ test trace-21.11 {trace execution and alias} -setup { rename ::x {} } -result {:: ::} +proc set2 args { + set {*}$args +} + +test trace-21.12 {bug 2438181} -setup { + trace add execution set2 leave {puts one two three #;} +} -body { + set2 a hello +} -returnCodes 1 -result {wrong # args: should be "puts ?-nonewline? ?channelId? string"} + proc factorial {n} { if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] } return 1 @@ -2050,7 +2088,7 @@ test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} trace remove execution foo {enter enterstep leavestep leave} \ [list traceExecute foo] rename foo {} - catch {unset a} + unset -nocomplain a join $info "\n" } {foo foo enter foo {set a 1} enterstep @@ -2634,9 +2672,8 @@ catch {rename traceproc {}} catch {rename runbase {}} # Unset the variable when done -catch {unset info} -catch {unset base} +unset -nocomplain info base # cleanup -::tcltest::cleanupTests +cleanupTests return diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test index 2453e01..e4613ed 100644 --- a/tests/unixFCmd.test +++ b/tests/unixFCmd.test @@ -365,20 +365,21 @@ test unixFCmd-17.4 {SetPermissionsAttribute} -setup { close [open foo.test w] set ::i 4 -proc permcheck {testnum permstr expected} { +proc permcheck {testnum permList expected} { test $testnum {SetPermissionsAttribute} {unix notRoot} { + set result {} + foreach permstr $permList { file attributes foo.test -permissions $permstr - file attributes foo.test -permissions + lappend result [file attributes foo.test -permissions] + } + set result } $expected } permcheck unixFCmd-17.5 rwxrwxrwx 00777 permcheck unixFCmd-17.6 r--r---w- 00442 -permcheck unixFCmd-17.7 0 00000 -permcheck unixFCmd-17.8 u+rwx,g+r 00740 -permcheck unixFCmd-17.9 u-w 00540 -permcheck unixFCmd-17.10 o+rwx 00547 +permcheck unixFCmd-17.7 {0 u+rwx,g+r u-w o+rwx} {00000 00740 00540 00547} permcheck unixFCmd-17.11 --x--x--x 00111 -permcheck unixFCmd-17.12 a+rwx 00777 +permcheck unixFCmd-17.12 {0 a+rwx} {00000 00777} file delete -force -- foo.test test unixFCmd-18.1 {Unix pwd} -constraints {unix notRoot nonPortable} -setup { diff --git a/tests/unixInit.test b/tests/unixInit.test index 9ba9c11..05338ed 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -11,7 +11,7 @@ # this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2.2 -namespace import -force ::tcltest::* +namespace import ::tcltest::* unset -nocomplain path catch {set oldlang $env(LANG)} set env(LANG) C @@ -44,11 +44,11 @@ test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} set pipe1 [open "|[list [interpreter]]" r+] puts $pipe1 { proc accept {channel host port} { - puts $channel {puts [fconfigure stdin -peername]; exit} + puts $channel {puts [chan configure stdin -peername]; exit} close $channel exit } - puts [fconfigure [socket -server accept -myaddr 127.0.0.1 0] -sockname] + puts [chan configure [socket -server accept -myaddr 127.0.0.1 0] -sockname] vwait forever \ } # Note the backslash above; this is important to make sure that the whole @@ -64,8 +64,8 @@ test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} set pipe2 [open "|[list [interpreter] <@$sock]" r] set result [gets $pipe2] # Clear any pending data; stops certain kinds of (non-important) errors - fconfigure $pipe1 -blocking 0; gets $pipe1 - fconfigure $pipe2 -blocking 0; gets $pipe2 + chan configure $pipe1 -blocking 0; gets $pipe1 + chan configure $pipe2 -blocking 0; gets $pipe2 # Close the pipes and the socket. close $pipe2 close $pipe1 @@ -329,7 +329,7 @@ test unixInit-3.1 {TclpSetInitialEncodings} -constraints { } -body { set env(LANG) C set f [open "|[list [interpreter]]" w+] - fconfigure $f -buffering none + chan configure $f -buffering none puts $f {puts [encoding system]; exit} set enc [gets $f] close $f @@ -344,7 +344,7 @@ test unixInit-3.2 {TclpSetInitialEncodings} -setup { set env(LANG) japanese set env(LC_ALL) japanese set f [open "|[list [interpreter]]" w+] - fconfigure $f -buffering none + chan configure $f -buffering none puts $f {puts [encoding system]; exit} set enc [gets $f] close $f @@ -390,7 +390,7 @@ test unixInit-7.1 {closed standard channel: Bug 772288} -constraints { } -returnCodes 0 # cleanup -catch {unset env(LANG)} +unset -nocomplain env(LANG) catch {set env(LANG) $oldlang} unset -nocomplain path ::tcltest::cleanupTests diff --git a/tests/unknown.test b/tests/unknown.test index 40be6602..e80d3a6 100644 --- a/tests/unknown.test +++ b/tests/unknown.test @@ -11,12 +11,10 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} +package require tcltest 2 +namespace import ::tcltest::* -catch {unset x} +unset -nocomplain x catch {rename unknown unknown.old} test unknown-1.1 {non-existent "unknown" command} { @@ -59,7 +57,7 @@ test unknown-4.1 {errors in "unknown" procedure} { # cleanup catch {rename unknown {}} catch {rename unknown.old unknown} -::tcltest::cleanupTests +cleanupTests return # Local Variables: diff --git a/tests/var.test b/tests/var.test index ed7e930..5939100 100644 --- a/tests/var.test +++ b/tests/var.test @@ -793,6 +793,75 @@ test var-19.1 {crash when freeing locals hashtable: Bug 3037525} { foo ; # This crashes without the fix for the bug rename foo {} } {} + +test var-20.1 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + global x + array set x {a 1} + }} + array size x +} -result 1 +test var-20.2 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + global x + array set x {} + }} + array size x +} -result 0 +test var-20.3 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + array set ::x {a 1} + }} + array size x +} -result 1 +test var-20.4 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + array set ::x {} + }} + array size x +} -result 0 +test var-20.5 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + global x + eval {array set x {a 1}} + }} + array size x +} -result 1 +test var-20.6 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + global x + eval {array set x {}} + }} + array size x +} -result 0 +test var-20.7 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + eval {array set ::x {a 1}} + }} + array size x +} -result 1 +test var-20.8 {array set compilation correctness: Bug 3603163} -setup { + unset -nocomplain x +} -body { + apply {{} { + eval {array set ::x {}} + }} + array size x +} -result 0 catch {namespace delete ns} catch {unset arr} diff --git a/tests/zlib.test b/tests/zlib.test index 891dba0..c469eea 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -366,6 +366,25 @@ test zlib-8.15 {transformtion and fconfigure} -setup { catch {close $inSide} catch {$strm close} } -result {358 358} +test zlib-8.16 {Bug 3603553: buffer transfer with large writes} -setup { + # Actual data isn't very important; needs to be substantially larger than + # the internal buffer (32kB) and incompressible. + set largeData {} + for {set i 0;expr srand(1)} {$i < 100000} {incr i} { + append largeData [lindex "a b c d e f g h i j k l m n o p" \ + [expr {int(16*rand())}]] + } + set file [makeFile {} test.gz] +} -constraints zlib -body { + set f [open $file wb] + fconfigure $f -buffering none + zlib push gzip $f + puts -nonewline $f $largeData + close $f + file size $file +} -cleanup { + removeFile $file +} -result 57647 test zlib-9.1 "check fcopy with push" -constraints zlib -setup { set sfile [makeFile {} testsrc.gz] diff --git a/unix/Makefile.in b/unix/Makefile.in index ee31282..00e694d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -839,20 +839,20 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \ done; - @echo "Installing package http 2.8.6 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.6.tm; + @echo "Installing package http 2.8.7 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.7.tm; @echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"; @for i in $(TOP_DIR)/library/opt/*.tcl ; \ do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; - @echo "Installing package msgcat 1.5.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.0.tm; + @echo "Installing package msgcat 1.5.1 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.1.tm; @echo "Installing package tcltest 2.3.5 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.5.tm; - @echo "Installing package platform 1.0.10 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.10.tm; + @echo "Installing package platform 1.0.11 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.11.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; @@ -866,10 +866,39 @@ install-libraries: libraries "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ fi -install-tzdata: ${NATIVE_TCLSH} +install-tzdata: + @for i in tzdata; \ + do \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ + echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ + else true; \ + fi; \ + done; @echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/" - @${NATIVE_TCLSH} $(TOOL_DIR)/installData.tcl \ - $(TOP_DIR)/library/tzdata "$(SCRIPT_INSTALL_DIR)"/tzdata + @for i in $(TOP_DIR)/library/tzdata/* ; do \ + if [ -d $$i ] ; then \ + ii=`basename $$i`; \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii ] ; then \ + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \ + fi; \ + for j in $$i/* ; do \ + if [ -d $$j ] ; then \ + jj=`basename $$j`; \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj ] ; then \ + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \ + fi; \ + for k in $$j/* ; do \ + $(INSTALL_DATA) $$k "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \ + done; \ + else \ + $(INSTALL_DATA) $$j "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \ + fi; \ + done; \ + else \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/tzdata; \ + fi; \ + done; install-msgs: @for i in msgs; \ @@ -1718,7 +1747,7 @@ install-packages: packages fi; \ done -test-packages: tcltest packages +test-packages: ${TCLTEST_EXE} packages @for i in $(PKGS_DIR)/*; do \ if [ -d $$i ]; then \ pkg=`basename $$i`; \ diff --git a/unix/configure b/unix/configure index f778a7b..c178bf1 100755 --- a/unix/configure +++ b/unix/configure @@ -7577,7 +7577,7 @@ fi fi ;; - Linux*) + Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" @@ -7683,21 +7683,6 @@ fi fi ;; - GNU*) - SHLIB_CFLAGS="-fPIC" - SHLIB_SUFFIX=".so" - - SHLIB_LD='${CC} -shared' - DL_OBJS="" - DL_LIBS="-ldl" - LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - if test "`uname -m`" = "alpha"; then - CFLAGS="$CFLAGS -mieee" -fi - - ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" @@ -13239,14 +13224,16 @@ fi fi #--------------------------------------------------------------------------- -# Determine which interface to use to talk to the serial port. -# Note that #include lines must begin in leftmost column for -# some compilers to recognize them as preprocessor directives. +# Check for serial port interface. +# +# termios.h is present on all POSIX systems. +# sys/ioctl.h is almost always present, though what it contains +# is system-specific. +# sys/modem.h is needed on HP-UX. #--------------------------------------------------------------------------- - -for ac_header in sys/modem.h +for ac_header in termios.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -13395,310 +13382,305 @@ fi done - echo "$as_me:$LINENO: checking termios vs. termio vs. sgtty" >&5 -echo $ECHO_N "checking termios vs. termio vs. sgtty... $ECHO_C" >&6 -if test "${tcl_cv_api_serial+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=no +for ac_header in sys/ioctl.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - cat >conftest.$ac_ext <<_ACEOF + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -#include <termios.h> - -int main() { - struct termios t; - if (tcgetattr(0, &t) == 0) { - cfsetospeed(&t, 0); - t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -} +$ac_includes_default +#include <$ac_header> _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_serial=termios -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_api_serial=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - if test $tcl_cv_api_serial = no ; then - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include <termio.h> - -int main() { - struct termio t; - if (ioctl(0, TCGETA, &t) == 0) { - t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - tcl_cv_api_serial=termio + ac_header_compiler=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -tcl_cv_api_serial=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +ac_header_compiler=no fi - fi - if test $tcl_cv_api_serial = no ; then - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=no -else - cat >conftest.$ac_ext <<_ACEOF +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -#include <sgtty.h> - -int main() { - struct sgttyb t; - if (ioctl(0, TIOCGETP, &t) == 0) { - t.sg_ospeed = 0; - t.sg_flags |= ODDP | EVENP | RAW; - return 0; - } - return 1; -} +#include <$ac_header> _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_serial=sgtty + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -tcl_cv_api_serial=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_header_preproc=no fi - fi - if test $tcl_cv_api_serial = no ; then - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 -#include <termios.h> -#include <errno.h> +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -int main() { - struct termios t; - if (tcgetattr(0, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - cfsetospeed(&t, 0); - t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -} +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_serial=termios -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -tcl_cv_api_serial=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + +done + + +for ac_header in sys/modem.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 fi - fi - if test $tcl_cv_api_serial = no; then - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=no +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - cat >conftest.$ac_ext <<_ACEOF + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -#include <termio.h> -#include <errno.h> - -int main() { - struct termio t; - if (ioctl(0, TCGETA, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; - } +$ac_includes_default +#include <$ac_header> _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - tcl_cv_api_serial=termio + ac_header_compiler=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -tcl_cv_api_serial=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +ac_header_compiler=no fi - fi - if test $tcl_cv_api_serial = no; then - if test "$cross_compiling" = yes; then - tcl_cv_api_serial=none -else - cat >conftest.$ac_ext <<_ACEOF +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -#include <sgtty.h> -#include <errno.h> - -int main() { - struct sgttyb t; - if (ioctl(0, TIOCGETP, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - t.sg_ospeed = 0; - t.sg_flags |= ODDP | EVENP | RAW; - return 0; - } - return 1; -} +#include <$ac_header> _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_serial=sgtty + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -tcl_cv_api_serial=none + ac_header_preproc=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" fi - fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + fi -echo "$as_me:$LINENO: result: $tcl_cv_api_serial" >&5 -echo "${ECHO_T}$tcl_cv_api_serial" >&6 - case $tcl_cv_api_serial in - termios) -cat >>confdefs.h <<\_ACEOF -#define USE_TERMIOS 1 -_ACEOF -;; - termio) -cat >>confdefs.h <<\_ACEOF -#define USE_TERMIO 1 -_ACEOF -;; - sgtty) -cat >>confdefs.h <<\_ACEOF -#define USE_SGTTY 1 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF -;; - esac + +fi + +done #-------------------------------------------------------------------- diff --git a/unix/configure.in b/unix/configure.in index 087bb05..19db579 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -259,12 +259,17 @@ if test "${TCL_THREADS}" = 1; then fi #--------------------------------------------------------------------------- -# Determine which interface to use to talk to the serial port. -# Note that #include lines must begin in leftmost column for -# some compilers to recognize them as preprocessor directives. +# Check for serial port interface. +# +# termios.h is present on all POSIX systems. +# sys/ioctl.h is almost always present, though what it contains +# is system-specific. +# sys/modem.h is needed on HP-UX. #--------------------------------------------------------------------------- -SC_SERIAL_PORT +AC_CHECK_HEADERS(termios.h) +AC_CHECK_HEADERS(sys/ioctl.h) +AC_CHECK_HEADERS(sys/modem.h) #-------------------------------------------------------------------- # Include sys/select.h if it exists and if it supplies things diff --git a/unix/tcl.m4 b/unix/tcl.m4 index b13fddd..3fa6abe 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1398,7 +1398,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ ]) ]) ;; - Linux*) + Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" @@ -1436,18 +1436,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; - GNU*) - SHLIB_CFLAGS="-fPIC" - SHLIB_SUFFIX=".so" - - SHLIB_LD='${CC} -shared' - DL_OBJS="" - DL_LIBS="-ldl" - LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) - ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" @@ -2191,124 +2179,6 @@ dnl # preprocessing tests use only CPPFLAGS. ]) #-------------------------------------------------------------------- -# SC_SERIAL_PORT -# -# Determine which interface to use to talk to the serial port. -# Note that #include lines must begin in leftmost column for -# some compilers to recognize them as preprocessor directives, -# and some build environments have stdin not pointing at a -# pseudo-terminal (usually /dev/null instead.) -# -# Arguments: -# none -# -# Results: -# -# Defines only one of the following vars: -# HAVE_SYS_MODEM_H -# USE_TERMIOS -# USE_TERMIO -# USE_SGTTY -# -#-------------------------------------------------------------------- - -AC_DEFUN([SC_SERIAL_PORT], [ - AC_CHECK_HEADERS(sys/modem.h) - AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ - AC_TRY_RUN([ -#include <termios.h> - -int main() { - struct termios t; - if (tcgetattr(0, &t) == 0) { - cfsetospeed(&t, 0); - t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) - if test $tcl_cv_api_serial = no ; then - AC_TRY_RUN([ -#include <termio.h> - -int main() { - struct termio t; - if (ioctl(0, TCGETA, &t) == 0) { - t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) - fi - if test $tcl_cv_api_serial = no ; then - AC_TRY_RUN([ -#include <sgtty.h> - -int main() { - struct sgttyb t; - if (ioctl(0, TIOCGETP, &t) == 0) { - t.sg_ospeed = 0; - t.sg_flags |= ODDP | EVENP | RAW; - return 0; - } - return 1; -}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no) - fi - if test $tcl_cv_api_serial = no ; then - AC_TRY_RUN([ -#include <termios.h> -#include <errno.h> - -int main() { - struct termios t; - if (tcgetattr(0, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - cfsetospeed(&t, 0); - t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; -}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) - fi - if test $tcl_cv_api_serial = no; then - AC_TRY_RUN([ -#include <termio.h> -#include <errno.h> - -int main() { - struct termio t; - if (ioctl(0, TCGETA, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; - return 0; - } - return 1; - }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) - fi - if test $tcl_cv_api_serial = no; then - AC_TRY_RUN([ -#include <sgtty.h> -#include <errno.h> - -int main() { - struct sgttyb t; - if (ioctl(0, TIOCGETP, &t) == 0 - || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { - t.sg_ospeed = 0; - t.sg_flags |= ODDP | EVENP | RAW; - return 0; - } - return 1; -}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) - fi]) - case $tcl_cv_api_serial in - termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; - termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; - sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; - esac -]) - -#-------------------------------------------------------------------- # SC_MISSING_POSIX_HEADERS # # Supply substitutes for missing POSIX header files. Special diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 159bbd8..f3edcff 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -48,7 +48,7 @@ MODULE_SCOPE int main(int, char **); */ #ifdef TCL_LOCAL_MAIN_HOOK -extern int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv); +MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv); #endif /* @@ -150,9 +150,11 @@ Tcl_AppInit( */ #ifdef DJGPP - (Tcl_SetVar)(interp, "tcl_rcFileName", "~/tclsh.rc", TCL_GLOBAL_ONLY); + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/tclsh.rc", -1), TCL_GLOBAL_ONLY); #else - (Tcl_SetVar)(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/.tclshrc", -1), TCL_GLOBAL_ONLY); #endif return TCL_OK; diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index f171cce..8069b68 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -433,15 +433,6 @@ /* Should we use FIONBIO? */ #undef USE_FIONBIO -/* Use the sgtty API for serial lines */ -#undef USE_SGTTY - -/* Use the termio API for serial lines */ -#undef USE_TERMIO - -/* Use the termios API for serial lines */ -#undef USE_TERMIOS - /* Do we want to use the threaded memory allocator? */ #undef USE_THREAD_ALLOC diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 9ee37f1..fdc9d1d 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -14,16 +14,9 @@ #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tclIO.h" /* To get Channel type declaration. */ -#define SUPPORTS_TTY - -#undef DIRECT_BAUD -#ifdef B4800 -# if (B4800 == 4800) -# define DIRECT_BAUD -# endif /* B4800 == 4800 */ -#endif /* B4800 */ - -#ifdef USE_TERMIOS +#undef SUPPORTS_TTY +#if defined(HAVE_TERMIOS_H) +# define SUPPORTS_TTY 1 # include <termios.h> # ifdef HAVE_SYS_IOCTL_H # include <sys/ioctl.h> @@ -31,60 +24,29 @@ # ifdef HAVE_SYS_MODEM_H # include <sys/modem.h> # endif /* HAVE_SYS_MODEM_H */ -# define IOSTATE struct termios -# define GETIOSTATE(fd, statePtr) tcgetattr((fd), (statePtr)) -# define SETIOSTATE(fd, statePtr) tcsetattr((fd), TCSADRAIN, (statePtr)) -# define GETCONTROL(fd, intPtr) ioctl((fd), TIOCMGET, (intPtr)) -# define SETCONTROL(fd, intPtr) ioctl((fd), TIOCMSET, (intPtr)) # ifdef FIONREAD # define GETREADQUEUE(fd, int) ioctl((fd), FIONREAD, &(int)) # elif defined(FIORDCHK) # define GETREADQUEUE(fd, int) int = ioctl((fd), FIORDCHK, NULL) -# endif /* FIONREAD */ +# else +# define GETREADQUEUE(fd, int) int = 0 +# endif + # ifdef TIOCOUTQ # define GETWRITEQUEUE(fd, int) ioctl((fd), TIOCOUTQ, &(int)) -# endif /* TIOCOUTQ */ -# if defined(TIOCSBRK) && defined(TIOCCBRK) - -/* - * Can't use ?: operator below because that messes up types on either Linux or - * Solaris (the two are mutually exclusive!) - */ +# else +# define GETWRITEQUEUE(fd, int) int = 0 +# endif -# define SETBREAK(fd, flag) \ - if (flag) { \ - ioctl((fd), TIOCSBRK, NULL); \ - } else { \ - ioctl((fd), TIOCCBRK, NULL); \ - } -# endif /* TIOCSBRK&TIOCCBRK */ # if !defined(CRTSCTS) && defined(CNEW_RTSCTS) # define CRTSCTS CNEW_RTSCTS # endif /* !CRTSCTS&CNEW_RTSCTS */ # if !defined(PAREXT) && defined(CMSPAR) # define PAREXT CMSPAR # endif /* !PAREXT&&CMSPAR */ -#else /* !USE_TERMIOS */ - -#ifdef USE_TERMIO -# include <termio.h> -# define IOSTATE struct termio -# define GETIOSTATE(fd, statePtr) ioctl((fd), TCGETA, (statePtr)) -# define SETIOSTATE(fd, statePtr) ioctl((fd), TCSETAW, (statePtr)) -#else /* !USE_TERMIO */ - -#ifdef USE_SGTTY -# include <sgtty.h> -# define IOSTATE struct sgttyb -# define GETIOSTATE(fd, statePtr) ioctl((fd), TIOCGETP, (statePtr)) -# define SETIOSTATE(fd, statePtr) ioctl((fd), TIOCSETP, (statePtr)) -#else /* !USE_SGTTY */ -# undef SUPPORTS_TTY -#endif /* !USE_SGTTY */ - -#endif /* !USE_TERMIO */ -#endif /* !USE_TERMIOS */ + +#endif /* HAVE_TERMIOS_H */ /* * Helper macros to make parts of this file clearer. The macros do exactly @@ -110,18 +72,6 @@ typedef struct FileState { #ifdef SUPPORTS_TTY /* - * The following structure describes per-instance state of a tty-based - * channel. - */ - -typedef struct TtyState { - FileState fs; /* Per-instance state of the file descriptor. - * Must be the first field. */ - IOSTATE savedState; /* Initial state of device. Used to reset - * state when device closed. */ -} TtyState; - -/* * The following structure is used to set or get the serial port attributes in * a platform-independant manner. */ @@ -167,15 +117,12 @@ static void TtyGetAttributes(int fd, TtyAttrs *ttyPtr); static int TtyGetOptionProc(ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *dsPtr); -#ifndef DIRECT_BAUD -static int TtyGetBaud(unsigned long speed); -static unsigned long TtyGetSpeed(int baud); -#endif /* DIRECT_BAUD */ -static FileState * TtyInit(int fd, int initialize); +static int TtyGetBaud(speed_t speed); +static speed_t TtyGetSpeed(int baud); +static void TtyInit(int fd); static void TtyModemStatusStr(int status, Tcl_DString *dsPtr); static int TtyParseMode(Tcl_Interp *interp, const char *mode, - int *speedPtr, int *parityPtr, int *dataPtr, - int *stopPtr); + TtyAttrs *ttyPtr); static void TtySetAttributes(int fd, TtyAttrs *ttyPtr); static int TtySetOptionProc(ClientData instanceData, Tcl_Interp *interp, const char *optionName, @@ -573,7 +520,6 @@ FileGetHandleProc( } #ifdef SUPPORTS_TTY -#ifdef USE_TERMIOS /* *---------------------------------------------------------------------- * @@ -606,7 +552,6 @@ TtyModemStatusStr( Tcl_DStringAppendElement(dsPtr, (status & TIOCM_CD) ? "1" : "0"); #endif /* TIOCM_CD */ } -#endif /* USE_TERMIOS */ /* *---------------------------------------------------------------------- @@ -636,11 +581,9 @@ TtySetOptionProc( FileState *fsPtr = instanceData; unsigned int len, vlen; TtyAttrs tty; -#ifdef USE_TERMIOS - int flag, control, argc; + int argc; const char **argv; - IOSTATE iostate; -#endif /* USE_TERMIOS */ + struct termios iostate; len = strlen(optionName); vlen = strlen(value); @@ -650,8 +593,7 @@ TtySetOptionProc( */ if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) { - if (TtyParseMode(interp, value, &tty.baud, &tty.parity, &tty.data, - &tty.stop) != TCL_OK) { + if (TtyParseMode(interp, value, &tty) != TCL_OK) { return TCL_ERROR; } @@ -663,7 +605,6 @@ TtySetOptionProc( return TCL_OK; } -#ifdef USE_TERMIOS /* * Option -handshake none|xonxoff|rtscts|dtrdsr @@ -674,25 +615,25 @@ TtySetOptionProc( * Reset all handshake options. DTR and RTS are ON by default. */ - GETIOSTATE(fsPtr->fd, &iostate); + tcgetattr(fsPtr->fd, &iostate); CLEAR_BITS(iostate.c_iflag, IXON | IXOFF | IXANY); #ifdef CRTSCTS CLEAR_BITS(iostate.c_cflag, CRTSCTS); #endif /* CRTSCTS */ - if (strncasecmp(value, "NONE", vlen) == 0) { + if (Tcl_UtfNcasecmp(value, "NONE", vlen) == 0) { /* * Leave all handshake options disabled. */ - } else if (strncasecmp(value, "XONXOFF", vlen) == 0) { + } else if (Tcl_UtfNcasecmp(value, "XONXOFF", vlen) == 0) { SET_BITS(iostate.c_iflag, IXON | IXOFF | IXANY); - } else if (strncasecmp(value, "RTSCTS", vlen) == 0) { + } else if (Tcl_UtfNcasecmp(value, "RTSCTS", vlen) == 0) { #ifdef CRTSCTS SET_BITS(iostate.c_cflag, CRTSCTS); #else /* !CRTSTS */ UNSUPPORTED_OPTION("-handshake RTSCTS"); return TCL_ERROR; #endif /* CRTSCTS */ - } else if (strncasecmp(value, "DTRDSR", vlen) == 0) { + } else if (Tcl_UtfNcasecmp(value, "DTRDSR", vlen) == 0) { UNSUPPORTED_OPTION("-handshake DTRDSR"); return TCL_ERROR; } else { @@ -705,7 +646,7 @@ TtySetOptionProc( } return TCL_ERROR; } - SETIOSTATE(fsPtr->fd, &iostate); + tcsetattr(fsPtr->fd, TCSADRAIN, &iostate); return TCL_OK; } @@ -730,7 +671,7 @@ TtySetOptionProc( return TCL_ERROR; } - GETIOSTATE(fsPtr->fd, &iostate); + tcgetattr(fsPtr->fd, &iostate); Tcl_UtfToExternalDString(NULL, argv[0], -1, &ds); iostate.c_cc[VSTART] = *(const cc_t *) Tcl_DStringValue(&ds); @@ -741,7 +682,7 @@ TtySetOptionProc( Tcl_DStringFree(&ds); ckfree(argv); - SETIOSTATE(fsPtr->fd, &iostate); + tcsetattr(fsPtr->fd, TCSADRAIN, &iostate); return TCL_OK; } @@ -752,22 +693,22 @@ TtySetOptionProc( if ((len > 2) && (strncmp(optionName, "-timeout", len) == 0)) { int msec; - GETIOSTATE(fsPtr->fd, &iostate); + tcgetattr(fsPtr->fd, &iostate); if (Tcl_GetInt(interp, value, &msec) != TCL_OK) { return TCL_ERROR; } iostate.c_cc[VMIN] = 0; iostate.c_cc[VTIME] = (msec==0) ? 0 : (msec<100) ? 1 : (msec+50)/100; - SETIOSTATE(fsPtr->fd, &iostate); + tcsetattr(fsPtr->fd, TCSADRAIN, &iostate); return TCL_OK; } /* * Option -ttycontrol {DTR 1 RTS 0 BREAK 0} */ - if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) { - int i; +#if defined(TIOCMGET) && defined(TIOCMSET) + int i, control, flag; if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; @@ -784,44 +725,36 @@ TtySetOptionProc( return TCL_ERROR; } - GETCONTROL(fsPtr->fd, &control); + ioctl(fsPtr->fd, TIOCMGET, &control); for (i = 0; i < argc-1; i += 2) { if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) { ckfree(argv); return TCL_ERROR; } - if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) { -#ifdef TIOCM_DTR + if (Tcl_UtfNcasecmp(argv[i], "DTR", strlen(argv[i])) == 0) { if (flag) { SET_BITS(control, TIOCM_DTR); } else { CLEAR_BITS(control, TIOCM_DTR); } -#else /* !TIOCM_DTR */ - UNSUPPORTED_OPTION("-ttycontrol DTR"); - ckfree(argv); - return TCL_ERROR; -#endif /* TIOCM_DTR */ - } else if (strncasecmp(argv[i], "RTS", strlen(argv[i])) == 0) { -#ifdef TIOCM_RTS + } else if (Tcl_UtfNcasecmp(argv[i], "RTS", strlen(argv[i])) == 0) { if (flag) { SET_BITS(control, TIOCM_RTS); } else { CLEAR_BITS(control, TIOCM_RTS); } -#else /* !TIOCM_RTS*/ - UNSUPPORTED_OPTION("-ttycontrol RTS"); - ckfree(argv); - return TCL_ERROR; -#endif /* TIOCM_RTS*/ - } else if (strncasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) { -#ifdef SETBREAK - SETBREAK(fsPtr->fd, flag); -#else /* !SETBREAK */ + } else if (Tcl_UtfNcasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) { +#if defined(TIOCSBRK) && defined(TIOCCBRK) + if (flag) { + ioctl(fsPtr->fd, TIOCSBRK, NULL); + } else { + ioctl(fsPtr->fd, TIOCCBRK, NULL); + } +#else /* TIOCSBRK & TIOCCBRK */ UNSUPPORTED_OPTION("-ttycontrol BREAK"); ckfree(argv); return TCL_ERROR; -#endif /* SETBREAK */ +#endif /* TIOCSBRK & TIOCCBRK */ } else { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -835,17 +768,16 @@ TtySetOptionProc( } } /* -ttycontrol options loop */ - SETCONTROL(fsPtr->fd, &control); + ioctl(fsPtr->fd, TIOCMSET, &control); ckfree(argv); return TCL_OK; +#else /* TIOCMGET&TIOCMSET */ + UNSUPPORTED_OPTION("-ttycontrol"); +#endif /* TIOCMGET&TIOCMSET */ } return Tcl_BadChannelOption(interp, optionName, "mode handshake timeout ttycontrol xchar"); - -#else /* !USE_TERMIOS */ - return Tcl_BadChannelOption(interp, optionName, "mode"); -#endif /* USE_TERMIOS */ } /* @@ -860,12 +792,8 @@ TtySetOptionProc( * * Results: * A standard Tcl result. Also sets the supplied DString to the string - * value of the option(s) returned. - * - * Side effects: - * The string returned by this function is in static storage and may be - * reused at any time subsequent to the call. Sets error message if - * needed (by calling Tcl_BadChannelOption). + * value of the option(s) returned. Sets error message if needed + * (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */ @@ -899,7 +827,6 @@ TtyGetOptionProc( Tcl_DStringAppendElement(dsPtr, buf); } -#ifdef USE_TERMIOS /* * Get option -xchar */ @@ -909,11 +836,11 @@ TtyGetOptionProc( Tcl_DStringStartSublist(dsPtr); } if (len==0 || (len>1 && strncmp(optionName, "-xchar", len)==0)) { - IOSTATE iostate; + struct termios iostate; Tcl_DString ds; valid = 1; - GETIOSTATE(fsPtr->fd, &iostate); + tcgetattr(fsPtr->fd, &iostate); Tcl_DStringInit(&ds); Tcl_ExternalToUtfDString(NULL, (char *) &iostate.c_cc[VSTART], 1, &ds); @@ -938,12 +865,8 @@ TtyGetOptionProc( int inQueue=0, outQueue=0, inBuffered, outBuffered; valid = 1; -#ifdef GETREADQUEUE GETREADQUEUE(fsPtr->fd, inQueue); -#endif /* GETREADQUEUE */ -#ifdef GETWRITEQUEUE GETWRITEQUEUE(fsPtr->fd, outQueue); -#endif /* GETWRITEQUEUE */ inBuffered = Tcl_InputBuffered(fsPtr->channel); outBuffered = Tcl_OutputBuffered(fsPtr->channel); @@ -953,37 +876,31 @@ TtyGetOptionProc( Tcl_DStringAppendElement(dsPtr, buf); } +#if defined(TIOCMGET) /* * Get option -ttystatus * Option is readonly and returned by [fconfigure chan -ttystatus] but not * returned by unnamed [fconfigure chan]. */ - if ((len > 4) && (strncmp(optionName, "-ttystatus", len) == 0)) { int status; valid = 1; - GETCONTROL(fsPtr->fd, &status); + ioctl(fsPtr->fd, TIOCMGET, &status); TtyModemStatusStr(status, dsPtr); } -#endif /* USE_TERMIOS */ +#endif /* TIOCMGET */ if (valid) { return TCL_OK; } return Tcl_BadChannelOption(interp, optionName, "mode" -#ifdef USE_TERMIOS " queue ttystatus xchar" -#endif /* USE_TERMIOS */ ); } -#ifdef DIRECT_BAUD -# define TtyGetSpeed(baud) ((unsigned) (baud)) -# define TtyGetBaud(speed) ((int) (speed)) -#else /* !DIRECT_BAUD */ -static const struct {int baud; unsigned long speed;} speeds[] = { +static const struct {int baud; speed_t speed;} speeds[] = { #ifdef B0 {0, B0}, #endif @@ -1079,20 +996,16 @@ static const struct {int baud; unsigned long speed;} speeds[] = { * * TtyGetSpeed -- * - * Given a baud rate, get the mask value that should be stored in the - * termios, termio, or sgttyb structure in order to select that baud - * rate. + * Given an integer baud rate, get the speed_t value that should be + * used to select that baud rate. * * Results: * As above. * - * Side effects: - * None. - * *--------------------------------------------------------------------------- */ -static unsigned long +static speed_t TtyGetSpeed( int baud) /* The baud rate to look up. */ { @@ -1125,21 +1038,17 @@ TtyGetSpeed( * * TtyGetBaud -- * - * Given a speed mask value from a termios, termio, or sgttyb structure, - * get the baus rate that corresponds to that mask value. + * Return the integer baud rate corresponding to a given speed_t value. * * Results: * As above. If the mask value was not recognized, 0 is returned. * - * Side effects: - * None. - * *--------------------------------------------------------------------------- */ static int TtyGetBaud( - unsigned long speed) /* Speed mask value to look up. */ + speed_t speed) /* Speed mask value to look up. */ { int i; @@ -1150,7 +1059,6 @@ TtyGetBaud( } return 0; } -#endif /* !DIRECT_BAUD */ /* *--------------------------------------------------------------------------- @@ -1175,12 +1083,11 @@ TtyGetAttributes( TtyAttrs *ttyPtr) /* Buffer filled with serial port * attributes. */ { - IOSTATE iostate; + struct termios iostate; int baud, parity, data, stop; - GETIOSTATE(fd, &iostate); + tcgetattr(fd, &iostate); -#ifdef USE_TERMIOS baud = TtyGetBaud(cfgetospeed(&iostate)); parity = 'n'; @@ -1202,39 +1109,6 @@ TtyGetAttributes( data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8; stop = (iostate.c_cflag & CSTOPB) ? 2 : 1; -#endif /* USE_TERMIOS */ - -#ifdef USE_TERMIO - baud = TtyGetBaud(iostate.c_cflag & CBAUD); - - parity = 'n'; - switch (iostate.c_cflag & (PARENB | PARODD | PAREXT)) { - case PARENB : parity = 'e'; break; - case PARENB | PARODD : parity = 'o'; break; - case PARENB | PAREXT : parity = 's'; break; - case PARENB | PARODD | PAREXT : parity = 'm'; break; - } - - data = iostate.c_cflag & CSIZE; - data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8; - - stop = (iostate.c_cflag & CSTOPB) ? 2 : 1; -#endif /* USE_TERMIO */ - -#ifdef USE_SGTTY - baud = TtyGetBaud(iostate.sg_ospeed); - - parity = 'n'; - if (iostate.sg_flags & EVENP) { - parity = 'e'; - } else if (iostate.sg_flags & ODDP) { - parity = 'o'; - } - - data = (iostate.sg_flags & (EVENP | ODDP)) ? 7 : 8; - - stop = 1; -#endif /* USE_SGTTY */ ttyPtr->baud = baud; ttyPtr->parity = parity; @@ -1265,12 +1139,10 @@ TtySetAttributes( TtyAttrs *ttyPtr) /* Buffer containing new attributes for serial * port. */ { - IOSTATE iostate; - -#ifdef USE_TERMIOS + struct termios iostate; int parity, data, flag; - GETIOSTATE(fd, &iostate); + tcgetattr(fd, &iostate); cfsetospeed(&iostate, TtyGetSpeed(ttyPtr->baud)); cfsetispeed(&iostate, TtyGetSpeed(ttyPtr->baud)); @@ -1300,58 +1172,7 @@ TtySetAttributes( CLEAR_BITS(iostate.c_cflag, PARENB | PARODD | CSIZE | CSTOPB); SET_BITS(iostate.c_cflag, flag); -#endif /* USE_TERMIOS */ - -#ifdef USE_TERMIO - int parity, data, flag; - - GETIOSTATE(fd, &iostate); - CLEAR_BITS(iostate.c_cflag, CBAUD); - SET_BITS(iostate.c_cflag, TtyGetSpeed(ttyPtr->baud)); - - flag = 0; - parity = ttyPtr->parity; - if (parity != 'n') { - SET_BITS(flag, PARENB); - if ((parity == 'm') || (parity == 's')) { - SET_BITS(flag, PAREXT); - } - if ((parity == 'm') || (parity == 'o')) { - SET_BITS(flag, PARODD); - } - } - data = ttyPtr->data; - SET_BITS(flag, - (data == 5) ? CS5 : - (data == 6) ? CS6 : - (data == 7) ? CS7 : CS8); - if (ttyPtr->stop == 2) { - SET_BITS(flag, CSTOPB); - } - - CLEAR_BITS(iostate.c_cflag, PARENB | PARODD | PAREXT | CSIZE | CSTOPB); - SET_BITS(iostate.c_cflag, flag); - -#endif /* USE_TERMIO */ - -#ifdef USE_SGTTY - int parity; - - GETIOSTATE(fd, &iostate); - iostate.sg_ospeed = TtyGetSpeed(ttyPtr->baud); - iostate.sg_ispeed = TtyGetSpeed(ttyPtr->baud); - - parity = ttyPtr->parity; - if (parity == 'e') { - CLEAR_BITS(iostate.sg_flags, ODDP); - SET_BITS(iostate.sg_flags, EVENP); - } else if (parity == 'o') { - CLEAR_BITS(iostate.sg_flags, EVENP); - SET_BITS(iostate.sg_flags, ODDP); - } -#endif /* USE_SGTTY */ - - SETIOSTATE(fd, &iostate); + tcsetattr(fd, TCSADRAIN, &iostate); } /* @@ -1367,9 +1188,6 @@ TtySetAttributes( * TCL_ERROR otherwise. If TCL_ERROR is returned, an error message is * left in the interp's result (if interp is non-NULL). * - * Side effects: - * None. - * *--------------------------------------------------------------------------- */ @@ -1377,17 +1195,17 @@ static int TtyParseMode( Tcl_Interp *interp, /* If non-NULL, interp for error return. */ const char *mode, /* Mode string to be parsed. */ - int *speedPtr, /* Filled with baud rate from mode string. */ - int *parityPtr, /* Filled with parity from mode string. */ - int *dataPtr, /* Filled with data bits from mode string. */ - int *stopPtr) /* Filled with stop bits from mode string. */ + TtyAttrs *ttyPtr) /* Filled with data from mode string */ { int i, end; char parity; - static const char *bad = "bad value for -mode"; + const char *bad = "bad value for -mode"; - i = sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr, - stopPtr, &end); + i = sscanf(mode, "%d,%c,%d,%d%n", + &ttyPtr->baud, + &parity, + &ttyPtr->data, + &ttyPtr->stop, &end); if ((i != 4) || (mode[end] != '\0')) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -1407,27 +1225,27 @@ TtyParseMode( */ if ( -#if defined(PAREXT) || defined(USE_TERMIO) +#if defined(PAREXT) strchr("noems", parity) #else strchr("noe", parity) -#endif /* PAREXT|USE_TERMIO */ +#endif /* PAREXT */ == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s parity: should be %s", bad, -#if defined(PAREXT) || defined(USE_TERMIO) +#if defined(PAREXT) "n, o, e, m, or s" #else "n, o, or e" -#endif /* PAREXT|USE_TERMIO */ +#endif /* PAREXT */ )); Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL); } return TCL_ERROR; } - *parityPtr = parity; - if ((*dataPtr < 5) || (*dataPtr > 8)) { + ttyPtr->parity = parity; + if ((ttyPtr->data < 5) || (ttyPtr->data > 8)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s data: should be 5, 6, 7, or 8", bad)); @@ -1435,7 +1253,7 @@ TtyParseMode( } return TCL_ERROR; } - if ((*stopPtr < 0) || (*stopPtr > 2)) { + if ((ttyPtr->stop < 0) || (ttyPtr->stop > 2)) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s stop: should be 1 or 2", bad)); @@ -1453,71 +1271,38 @@ TtyParseMode( * * Given file descriptor that refers to a serial port, initialize the * serial port to a set of sane values so that Tcl can talk to a device - * located on the serial port. Note that no initialization happens if the - * initialize flag is not set; this is necessary for the correct handling - * of UNIX console TTYs at startup. - * - * Results: - * A pointer to a FileState suitable for use with Tcl_CreateChannel and - * the ttyChannelType structure. + * located on the serial port. * * Side effects: * Serial device initialized to non-blocking raw mode, similar to sockets - * (if initialize flag is non-zero.) All other modes can be simulated on - * top of this in Tcl. + * All other modes can be simulated on top of this in Tcl. * *--------------------------------------------------------------------------- */ -static FileState * +static void TtyInit( - int fd, /* Open file descriptor for serial port to be - * initialized. */ - int initialize) + int fd) /* Open file descriptor for serial port to be initialized. */ { - TtyState *ttyPtr = ckalloc(sizeof(TtyState)); - int stateUpdated = 0; - - GETIOSTATE(fd, &ttyPtr->savedState); - if (initialize) { - IOSTATE iostate = ttyPtr->savedState; - -#if defined(USE_TERMIOS) || defined(USE_TERMIO) - if (iostate.c_iflag != IGNBRK - || iostate.c_oflag != 0 - || iostate.c_lflag != 0 - || iostate.c_cflag & CREAD - || iostate.c_cc[VMIN] != 1 - || iostate.c_cc[VTIME] != 0) { - stateUpdated = 1; - } + struct termios iostate; + tcgetattr(fd, &iostate); + + if (iostate.c_iflag != IGNBRK + || iostate.c_oflag != 0 + || iostate.c_lflag != 0 + || iostate.c_cflag & CREAD + || iostate.c_cc[VMIN] != 1 + || iostate.c_cc[VTIME] != 0) + { iostate.c_iflag = IGNBRK; iostate.c_oflag = 0; iostate.c_lflag = 0; - SET_BITS(iostate.c_cflag, CREAD); + iostate.c_cflag |= CREAD; iostate.c_cc[VMIN] = 1; iostate.c_cc[VTIME] = 0; -#endif /* USE_TERMIOS|USE_TERMIO */ - -#ifdef USE_SGTTY - if ((iostate.sg_flags & (EVENP | ODDP)) - || !(iostate.sg_flags & RAW)) { - ttyPtr->stateUpdated = 1; - } - iostate.sg_flags &= EVENP | ODDP; - SET_BITS(iostate.sg_flags, RAW); -#endif /* USE_SGTTY */ - - /* - * Only update if we're changing anything to avoid possible blocking. - */ - if (stateUpdated) { - SETIOSTATE(fd, &iostate); - } + tcsetattr(fd, TCSADRAIN, &iostate); } - - return &ttyPtr->fs; } #endif /* SUPPORTS_TTY */ @@ -1621,15 +1406,15 @@ TclpOpenFileChannel( translation = "auto crlf"; channelTypePtr = &ttyChannelType; - fsPtr = TtyInit(fd, 1); + TtyInit(fd); } else #endif /* SUPPORTS_TTY */ { translation = NULL; channelTypePtr = &fileChannelType; - fsPtr = ckalloc(sizeof(FileState)); } + fsPtr = ckalloc(sizeof(FileState)); fsPtr->validMask = channelPermissions | TCL_EXCEPTION; fsPtr->fd = fd; @@ -1692,7 +1477,6 @@ Tcl_MakeFileChannel( #ifdef SUPPORTS_TTY if (isatty(fd)) { - fsPtr = TtyInit(fd, 0); channelTypePtr = &ttyChannelType; sprintf(channelName, "serial%d", fd); } else @@ -1703,10 +1487,10 @@ Tcl_MakeFileChannel( return TclpMakeTcpClientChannelMode(INT2PTR(fd), mode); } else { channelTypePtr = &fileChannelType; - fsPtr = ckalloc(sizeof(FileState)); sprintf(channelName, "file%d", fd); } + fsPtr = ckalloc(sizeof(FileState)); fsPtr->fd = fd; fsPtr->validMask = mode | TCL_EXCEPTION; fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName, diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index e201018..2a68f7f 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -995,12 +995,19 @@ TclWinCPUID( /* See: <http://en.wikipedia.org/wiki/CPUID> */ #if defined(HAVE_CPUID) - __asm__ __volatile__("mov %%ebx, %%edi \n\t" /* save %ebx */ +#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) + __asm__ __volatile__("movq %%rbx, %%rsi \n\t" /* save %rbx */ "cpuid \n\t" - "mov %%ebx, %%esi \n\t" /* save what cpuid just put in %ebx */ - "mov %%edi, %%ebx \n\t" /* restore the old %ebx */ + "xchgq %%rsi, %%rbx \n\t" /* restore the old %rbx */ : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) - : "a"(index) : "edi"); + : "a"(index)); +#else + __asm__ __volatile__("mov %%ebx, %%esi \n\t" /* save %ebx */ + "cpuid \n\t" + "xchg %%esi, %%ebx \n\t" /* restore the old %ebx */ + : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3]) + : "a"(index)); +#endif status = TCL_OK; #endif return status; diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index 559992f..6f443a9 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -244,7 +244,7 @@ MODULE_SCOPE long tclMacOSXDarwinRelease; #endif /* NO_REALPATH */ #ifdef HAVE_FTS -#ifdef HAVE_STRUCT_STAT64 +#if defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__) /* fts doesn't do stat64 */ # define noFtsStat 1 #elif defined(__APPLE__) && defined(__LP64__) && \ diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 38504d9..5bfe5d9 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -1181,9 +1181,10 @@ TclpUtime( int TclOSstat( const char *name, - Tcl_StatBuf *statBuf) + void *cygstat) { struct stat buf; + Tcl_StatBuf *statBuf = cygstat; int result = stat(name, &buf); statBuf->st_mode = buf.st_mode; @@ -1203,9 +1204,10 @@ TclOSstat( int TclOSlstat( const char *name, - Tcl_StatBuf *statBuf) + void *cygstat) { struct stat buf; + Tcl_StatBuf *statBuf = cygstat; int result = lstat(name, &buf); statBuf->st_mode = buf.st_mode; diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index 63c500d..636c760 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -21,10 +21,6 @@ #ifndef _TCLUNIXPORT #define _TCLUNIXPORT - -#ifndef MODULE_SCOPE -#define MODULE_SCOPE extern -#endif /* *--------------------------------------------------------------------------- @@ -89,26 +85,26 @@ typedef off_t Tcl_SeekOffset; # define SOCKET unsigned int # define WSAEWOULDBLOCK 10035 typedef unsigned short WCHAR; - DLLIMPORT extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *); - DLLIMPORT extern __stdcall int GetModuleFileNameW(void *, const char *, int); - DLLIMPORT extern __stdcall int WideCharToMultiByte(int, int, const char *, int, + __declspec(dllimport) extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *); + __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int); + __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); - DLLIMPORT extern __stdcall int MultiByteToWideChar(int, int, const char *, int, + __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int, WCHAR *, int); - DLLIMPORT extern __stdcall void OutputDebugStringW(const WCHAR *); - DLLIMPORT extern __stdcall int IsDebuggerPresent(); + __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *); + __declspec(dllimport) extern __stdcall int IsDebuggerPresent(); - DLLIMPORT extern int cygwin_conv_path(int, const void *, void *, int); - DLLIMPORT extern int cygwin_conv_path_list(int, const void *, void *, int); + __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); + __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); # define USE_PUTENV 1 # define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ # define environ __cygwin_environ # define timezone _timezone - DLLIMPORT extern char **__cygwin_environ; - MODULE_SCOPE int TclOSstat(const char *name, Tcl_StatBuf *statBuf); - MODULE_SCOPE int TclOSlstat(const char *name, Tcl_StatBuf *statBuf); -#elif defined(HAVE_STRUCT_STAT64) + extern char **__cygwin_environ; + extern int TclOSstat(const char *name, void *statBuf); + extern int TclOSlstat(const char *name, void *statBuf); +#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__) # define TclOSstat stat64 # define TclOSlstat lstat64 #else @@ -126,9 +122,7 @@ typedef off_t Tcl_SeekOffset; #ifdef HAVE_SYS_SELECT_H # include <sys/select.h> #endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif +#include <sys/stat.h> #if TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> @@ -159,7 +153,7 @@ typedef off_t Tcl_SeekOffset; # include "../compat/unistd.h" #endif -MODULE_SCOPE int TclUnixSetBlockingMode(int fd, int mode); +extern int TclUnixSetBlockingMode(int fd, int mode); #include <utime.h> @@ -319,7 +313,7 @@ MODULE_SCOPE int TclUnixSetBlockingMode(int fd, int mode); #endif #ifdef GETTOD_NOT_DECLARED -MODULE_SCOPE int gettimeofday(struct timeval *tp, +extern int gettimeofday(struct timeval *tp, struct timezone *tzp); #endif @@ -584,19 +578,6 @@ extern char ** environ; /* *--------------------------------------------------------------------------- - * The termios configure test program relies on the configure script being run - * from a terminal, which is not the case e.g., when configuring from Xcode. - * Since termios is known to be present on all Mac OS X releases since 10.0, - * override the configure defines for serial API here. [Bug 497147] - *--------------------------------------------------------------------------- - */ - -# define USE_TERMIOS 1 -# undef USE_TERMIO -# undef USE_SGTTY - -/* - *--------------------------------------------------------------------------- * Include AvailabilityMacros.h here (when available) to ensure any symbolic * MAC_OS_X_VERSION_* constants passed on the command line are translated. *--------------------------------------------------------------------------- @@ -737,15 +718,15 @@ typedef int socklen_t; #include <pwd.h> #include <grp.h> -MODULE_SCOPE struct passwd * TclpGetPwNam(const char *name); -MODULE_SCOPE struct group * TclpGetGrNam(const char *name); -MODULE_SCOPE struct passwd * TclpGetPwUid(uid_t uid); -MODULE_SCOPE struct group * TclpGetGrGid(gid_t gid); -MODULE_SCOPE struct hostent * TclpGetHostByName(const char *name); -MODULE_SCOPE struct hostent * TclpGetHostByAddr(const char *addr, +extern struct passwd * TclpGetPwNam(const char *name); +extern struct group * TclpGetGrNam(const char *name); +extern struct passwd * TclpGetPwUid(uid_t uid); +extern struct group * TclpGetGrGid(gid_t gid); +extern struct hostent * TclpGetHostByName(const char *name); +extern struct hostent * TclpGetHostByAddr(const char *addr, int length, int type); -MODULE_SCOPE Tcl_Channel TclpMakeTcpClientChannelMode( - ClientData tcpSocket, int mode); +extern void *TclpMakeTcpClientChannelMode( + void *tcpSocket, int mode); #endif /* _TCLUNIXPORT */ diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 31daa62..528f009 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1202,7 +1202,7 @@ Tcl_Channel Tcl_MakeTcpClientChannel( ClientData sock) /* The socket to wrap up into a channel. */ { - return TclpMakeTcpClientChannelMode(sock, (TCL_READABLE | TCL_WRITABLE)); + return (Tcl_Channel) TclpMakeTcpClientChannelMode(sock, (TCL_READABLE | TCL_WRITABLE)); } /* @@ -1222,9 +1222,9 @@ Tcl_MakeTcpClientChannel( *---------------------------------------------------------------------- */ -Tcl_Channel +void * TclpMakeTcpClientChannelMode( - ClientData sock, /* The socket to wrap up into a channel. */ + void *sock, /* The socket to wrap up into a channel. */ int mode) /* ORed combination of TCL_READABLE and * TCL_WRITABLE to indicate file mode. */ { diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c index 46fc972..c10225d 100644 --- a/unix/tclUnixTest.c +++ b/unix/tclUnixTest.c @@ -200,7 +200,7 @@ TestfilehandlerCmd( return TCL_ERROR; } sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "create") == 0) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", @@ -217,8 +217,8 @@ TestfilehandlerCmd( fcntl(GetFd(pipePtr->readFile), F_SETFL, O_NONBLOCK); fcntl(GetFd(pipePtr->writeFile), F_SETFL, O_NONBLOCK); #else - Tcl_SetResult(interp, "can't make pipes non-blocking", - TCL_STATIC); + Tcl_AppendResult(interp, "can't make pipes non-blocking", + NULL); return TCL_ERROR; #endif } @@ -281,7 +281,7 @@ TestfilehandlerCmd( memset(buffer, 'b', 10); TclFormatInt(buf, write(GetFd(pipePtr->writeFile), buffer, 10)); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "oneevent") == 0) { Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT); } else if (strcmp(argv[1], "wait") == 0) { @@ -390,7 +390,7 @@ TestfilewaitCmd( if (Tcl_GetChannelHandle(channel, (mask & TCL_READABLE) ? TCL_READABLE : TCL_WRITABLE, (ClientData*) &data) != TCL_OK) { - Tcl_SetResult(interp, "couldn't get channel file", TCL_STATIC); + Tcl_AppendResult(interp, "couldn't get channel file", NULL); return TCL_ERROR; } fd = PTR2INT(data); diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index c7921fe..926e8f4 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -503,7 +503,7 @@ SetTZIfNecessary(void) if (lastTZ == NULL) { Tcl_CreateExitHandler(CleanupMemory, NULL); } else { - Tcl_Free(lastTZ); + ckfree(lastTZ); } lastTZ = ckalloc(strlen(newTZ) + 1); strcpy(lastTZ, newTZ); diff --git a/win/Makefile.in b/win/Makefile.in index d0e14c6..bfc4e0d 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -82,6 +82,11 @@ CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@ #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE +# To compile without backward compatibility and deprecated code uncomment the +# following +NO_DEPRECATED_FLAGS = +#NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED + # To enable compilation debugging reverse the comment characters on one of the # following lines. COMPILE_DEBUG_FLAGS = @@ -187,7 +192,7 @@ COPY = cp CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} -I"${ZLIB_DIR}" \ -I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" \ -I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \ -${COMPILE_DEBUG_FLAGS} +${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS} CC_OBJNAME = @CC_OBJNAME@ CC_EXENAME = @CC_EXENAME@ @@ -634,19 +639,19 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \ done; - @echo "Installing package http 2.8.6 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.6.tm; + @echo "Installing package http 2.8.7 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl7/8.6/http-2.8.7.tm; @echo "Installing library opt0.4 directory"; @for j in $(ROOT_DIR)/library/opt/*.tcl; \ do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; - @echo "Installing package msgcat 1.5.0 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.0.tm; + @echo "Installing package msgcat 1.5.1 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.1.tm; @echo "Installing package tcltest 2.3.5 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.5.tm; - @echo "Installing package platform 1.0.10 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.10.tm; + @echo "Installing package platform 1.0.11 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.11.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform/shell-1.1.4.tm; @echo "Installing encodings"; diff --git a/win/configure b/win/configure index 03a20b4..0b07e9f 100755 --- a/win/configure +++ b/win/configure @@ -3146,7 +3146,8 @@ echo "${ECHO_T}shared" >&6 echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6 SHARED_BUILD=0 - cat >>confdefs.h <<\_ACEOF + +cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF @@ -3,50 +3,124 @@ # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags -# Currently a no-op for Windows # # Arguments: -# PATCH_LEVEL The patch level for Tcl if any. +# none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # -# Sets the following vars: -# TCL_BIN_DIR Full path to the tclConfig.sh file +# Defines the following vars: +# TCL_BIN_DIR Full path to the directory containing +# the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_TCLCONFIG], [ - AC_MSG_CHECKING([the location of tclConfig.sh]) + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # - if test -d ../../tcl8.6$1/win; then - TCL_BIN_DIR_DEFAULT=../../tcl8.6$1/win - elif test -d ../../tcl8.6/win; then - TCL_BIN_DIR_DEFAULT=../../tcl8.6/win - else - TCL_BIN_DIR_DEFAULT=../../tcl/win - fi + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + AC_ARG_WITH(tcl, + AC_HELP_STRING([--with-tcl], + [directory containing tcl configuration (tclConfig.sh)]), + with_tclconfig="${withval}") + AC_MSG_CHECKING([for Tcl configuration]) + AC_CACHE_VAL(ac_cv_c_tclconfig,[ + + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + case "${with_tclconfig}" in + */tclConfig.sh ) + if test -f "${with_tclconfig}"; then + AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) + with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" + else + AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) + fi + fi - AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.6 binaries from DIR], - TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DIR_DEFAULT; pwd`) - if test ! -d $TCL_BIN_DIR; then - AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist) - fi - if test ! -f $TCL_BIN_DIR/tclConfig.sh; then - if test ! -f $TCL_BIN_DIR/../unix/tclConfig.sh; then - AC_MSG_ERROR(There is no tclConfig.sh in $TCL_BIN_DIR: perhaps you did not specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?) + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /cygdrive/c/Tcl/lib 2>/dev/null` \ + `ls -d /cygdrive/c/Progra~1/Tcl/lib 2>/dev/null` \ + `ls -d /c/Tcl/lib 2>/dev/null` \ + `ls -d /c/Progra~1/Tcl/lib 2>/dev/null` \ + `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + done + fi + ]) + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) + else + no_tcl= + TCL_BIN_DIR="${ac_cv_c_tclconfig}" + AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi - TCL_BIN_DIR=`cd ${TCL_BIN_DIR}/../unix; pwd` fi - AC_MSG_RESULT($TCL_BIN_DIR/tclConfig.sh) ]) #------------------------------------------------------------------------ # SC_PATH_TKCONFIG -- # # Locate the tkConfig.sh file -# Currently a no-op for Windows # # Arguments: # none @@ -56,31 +130,109 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ # Adds the following arguments to configure: # --with-tk=... # -# Sets the following vars: -# TK_BIN_DIR Full path to the tkConfig.sh file +# Defines the following vars: +# TK_BIN_DIR Full path to the directory containing +# the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_TKCONFIG], [ - AC_MSG_CHECKING([the location of tkConfig.sh]) + # + # Ok, lets find the tk configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tk + # - if test -d ../../tk8.6$1/win; then - TK_BIN_DIR_DEFAULT=../../tk8.6$1/win - elif test -d ../../tk8.6/win; then - TK_BIN_DIR_DEFAULT=../../tk8.6/win - else - TK_BIN_DIR_DEFAULT=../../tk/win - fi + if test x"${no_tk}" = x ; then + # we reset no_tk in case something fails here + no_tk=true + AC_ARG_WITH(tk, + AC_HELP_STRING([--with-tk], + [directory containing tk configuration (tkConfig.sh)]), + with_tkconfig="${withval}") + AC_MSG_CHECKING([for Tk configuration]) + AC_CACHE_VAL(ac_cv_c_tkconfig,[ + + # First check to see if --with-tkconfig was specified. + if test x"${with_tkconfig}" != x ; then + case "${with_tkconfig}" in + */tkConfig.sh ) + if test -f "${with_tkconfig}"; then + AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) + with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tkconfig}/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" + else + AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) + fi + fi - AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.6 binaries from DIR], - TK_BIN_DIR=$withval, TK_BIN_DIR=`cd $TK_BIN_DIR_DEFAULT; pwd`) - if test ! -d $TK_BIN_DIR; then - AC_MSG_ERROR(Tk directory $TK_BIN_DIR does not exist) - fi - if test ! -f $TK_BIN_DIR/tkConfig.sh; then - AC_MSG_ERROR(There is no tkConfig.sh in $TK_BIN_DIR: perhaps you did not specify the Tk *build* directory (not the toplevel Tk directory) or you forgot to configure Tk?) - fi + # then check for a private Tk library + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ../tk \ + `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../tk \ + `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../../tk \ + `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + done + fi - AC_MSG_RESULT([$TK_BIN_DIR/tkConfig.sh]) + # check in a few common install locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /cygdrive/c/Tcl/lib 2>/dev/null` \ + `ls -d /cygdrive/c/Progra~1/Tcl/lib 2>/dev/null` \ + `ls -d /c/Tcl/lib 2>/dev/null` \ + `ls -d /c/Progra~1/Tcl/lib 2>/dev/null` \ + `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ${srcdir}/../tk \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + done + fi + ]) + + if test x"${ac_cv_c_tkconfig}" = x ; then + TK_BIN_DIR="# no Tk configs found" + AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) + else + no_tk= + TK_BIN_DIR="${ac_cv_c_tkconfig}" + AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) + fi + fi ]) #------------------------------------------------------------------------ @@ -103,13 +255,13 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TCLCONFIG], [ - AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) + AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) - if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then + if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) - . $TCL_BIN_DIR/tclConfig.sh + . "${TCL_BIN_DIR}/tclConfig.sh" else - AC_MSG_RESULT([file not found]) + AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # @@ -158,7 +310,6 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ # SC_LOAD_TKCONFIG -- # # Load the tkConfig.sh file -# Currently a no-op for Windows # # Arguments: # @@ -172,13 +323,13 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TKCONFIG], [ - AC_MSG_CHECKING([for existence of $TK_BIN_DIR/tkConfig.sh]) + AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) - if test -f "$TK_BIN_DIR/tkConfig.sh" ; then + if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) - . $TK_BIN_DIR/tkConfig.sh + . "${TK_BIN_DIR}/tkConfig.sh" else - AC_MSG_RESULT([could not find $TK_BIN_DIR/tkConfig.sh]) + AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi @@ -212,7 +363,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, [ --enable-shared build and link with shared libraries (default: on)], - [tcl_ok=$enableval], [tcl_ok=yes]) + [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" @@ -227,7 +378,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [ else AC_MSG_RESULT([static]) SHARED_BUILD=0 - AC_DEFINE(STATIC_BUILD) + AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi ]) @@ -270,7 +421,7 @@ AC_DEFUN([SC_ENABLE_THREADS], [ #------------------------------------------------------------------------ # SC_ENABLE_SYMBOLS -- # -# Specify if debugging symbols should be used +# Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging # can also be enabled. # diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 56f45a0..753eaff 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -45,7 +45,10 @@ static void setargv(int *argcPtr, TCHAR ***argvPtr); #ifndef TCL_LOCAL_APPINIT #define TCL_LOCAL_APPINIT Tcl_AppInit #endif -extern int TCL_LOCAL_APPINIT(Tcl_Interp *interp); +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif +MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); /* * The following #if block allows you to change how Tcl finds the startup @@ -54,7 +57,7 @@ extern int TCL_LOCAL_APPINIT(Tcl_Interp *interp); */ #ifdef TCL_LOCAL_MAIN_HOOK -extern int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); +MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); #endif /* @@ -193,7 +196,8 @@ Tcl_AppInit( * specific startup file will be run under any conditions. */ - (Tcl_SetVar)(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY); + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY); return TCL_OK; } diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 5aab255..65e4aed 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -11,7 +11,6 @@ */ #include "tclWinInt.h" -#include <sys/stat.h> /* * The following variable is used to tell whether this module has been diff --git a/win/tclWinDde.c b/win/tclWinDde.c index d0600e6..ce0b413 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -11,8 +11,9 @@ */ #undef STATIC_BUILD -#undef USE_TCL_STUBS -#define USE_TCL_STUBS +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif #include "tclInt.h" #include <dde.h> #include <ddeml.h> @@ -385,7 +386,8 @@ DdeSetServerName( Tcl_DStringSetLength(&dString, offset + sizeof(TCHAR) * TCL_INTEGER_SPACE); actualName = (TCHAR *) Tcl_DStringValue(&dString); } - _stprintf((TCHAR *) (Tcl_DStringValue(&dString) + offset), TEXT("%d"), suffix); + _sntprintf((TCHAR *) (Tcl_DStringValue(&dString) + offset), + TCL_INTEGER_SPACE, TEXT("%d"), suffix); } /* diff --git a/win/tclWinFile.c b/win/tclWinFile.c index a4512ec..8e517d1 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -15,7 +15,6 @@ #include "tclWinInt.h" #include "tclFileSystem.h" #include <winioctl.h> -#include <sys/stat.h> #include <shlobj.h> #include <lm.h> /* For TclpGetUserHome(). */ @@ -1538,14 +1537,9 @@ NativeAccess( * File might not exist. */ - WIN32_FIND_DATA ffd; - HANDLE hFind; - hFind = FindFirstFile(nativePath, &ffd); - if (hFind != INVALID_HANDLE_VALUE) { - attr = ffd.dwFileAttributes; - FindClose(hFind); - } else { - TclWinConvertError(GetLastError()); + DWORD lasterror = GetLastError(); + if (lasterror != ERROR_SHARING_VIOLATION) { + TclWinConvertError(lasterror); return -1; } } @@ -2003,15 +1997,17 @@ NativeStat( if (GetFileAttributesEx(nativePath, GetFileExInfoStandard, &data) != TRUE) { - /* - * We might have just been denied access - */ - + HANDLE hFind; WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(nativePath, &ffd); + DWORD lasterror = GetLastError(); + if (lasterror != ERROR_SHARING_VIOLATION) { + TclWinConvertError(lasterror); + return -1; + } + hFind = FindFirstFile(nativePath, &ffd); if (hFind == INVALID_HANDLE_VALUE) { - Tcl_SetErrno(ENOENT); + TclWinConvertError(GetLastError()); return -1; } memcpy(&data, &ffd, sizeof(data)); @@ -2476,6 +2472,12 @@ TclpObjNormalizePath( } Tcl_DStringAppend(&dsNorm, nativePath, len); lastValidPathEnd = currentPathEndPosition; + } else if (nextCheckpoint == 0) { + /* Path starts with a drive designation + * that's not actually on the system. + * We still must normalize up past the + * first separator. [Bug 3603434] */ + currentPathEndPosition++; } } Tcl_DStringFree(&ds); @@ -2616,6 +2618,12 @@ TclpObjNormalizePath( (const char *)nativePath, (int)(sizeof(WCHAR) * len)); lastValidPathEnd = currentPathEndPosition; + } else if (nextCheckpoint == 0) { + /* Path starts with a drive designation + * that's not actually on the system. + * We still must normalize up past the + * first separator. [Bug 3603434] */ + currentPathEndPosition++; } } Tcl_DStringFree(&ds); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 36ae58a..d418a3e 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -12,8 +12,6 @@ #include "tclWinInt.h" -#include <sys/stat.h> - /* * The following variable is used to tell whether this module has been * initialized. diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 6ac5caf..327e4a3 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -13,9 +13,9 @@ */ #undef STATIC_BUILD -#undef USE_TCL_STUBS -#define USE_TCL_STUBS - +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif #include "tclInt.h" #ifdef _MSC_VER # pragma comment (lib, "advapi32.lib") diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 458b05b..75d5ffc 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -14,8 +14,6 @@ #include "tclWinInt.h" -#include <sys/stat.h> - /* * The following variable is used to tell whether this module has been * initialized. diff --git a/win/tclWinTest.c b/win/tclWinTest.c index 136c4db..b83c0ba 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -211,7 +211,7 @@ TestvolumetypeCmd( TclWinConvertError(GetLastError()); return TCL_ERROR; } - Tcl_SetResult(interp, volType, TCL_VOLATILE); + Tcl_AppendResult(interp, volType, NULL); return TCL_OK; #undef VOL_BUF_SIZE } diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index 7b0f6f8..1c9d483 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -14,7 +14,6 @@ #include "tclWinInt.h" #include <float.h> -#include <sys/stat.h> /* Workaround for mingw versions which don't provide this in float.h */ #ifndef _MCW_EM |