Compare commits

...
541 Commits
Author SHA1 Message Date
jan.nijtmans 118be26821 merge trunk 2013-04-19 09:39:20 +00:00
jan.nijtmans 8474c20bc6 Implement many Tcl_*Var* functions and Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct 2013-04-19 09:12:12 +00:00
jan.nijtmans 1197921203 Implement many Tcl_*Var* functions and Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct 2013-04-19 08:41:15 +00:00
jan.nijtmans 911c3a02b5 Implement many Tcl_*Var* functions and Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct 2013-04-19 08:19:07 +00:00
dgp 1de5433c5d merge-mark 2013-04-16 20:20:39 +00:00
dgp 5cbeb42aff 3610404 When we let go of commandPtr in TclEvalObjvInternal, NULL out the
variable so we don't mistakenly try to use the value later after we freed it.
2013-04-16 20:18:19 +00:00
jan.nijtmans 6b60065860 Implement Tcl_Pkg* functions as macro's around Tcl_Pkg*Ex. This saves stack space, is (marginally) faster, while still being fully up/down compatible. It makes pkgb.so loadable in "novem" without the need to change the Tcl_PkgProvide() call to Tcl_PkgProvideEx(). 2013-04-12 11:27:37 +00:00
jan.nijtmans 9b0ea3ca88 Implement Tcl_Pkg* functions as macro's around Tcl_Pkg*Ex. This saves stack space, is (marginally) faster, while still being fully up/down compatible. It makes pkgb.so loadable in "novem" without the need to change the Tcl_PkgProvide() call to Tcl_PkgProvideEx(). 2013-04-12 11:22:43 +00:00
jan.nijtmans a0b6194b82 Implement Tcl_Pkg* functions as macro's around Tcl_Pkg*Ex. This saves stack space, is (marginally) faster, while still being fully up/down compatible. It makes pkgb.so loadable in "novem" without the need to change the Tcl_PkgProvide() call to Tcl_PkgProvideEx(). 2013-04-12 11:08:18 +00:00
dgp 5c4737c8d8 merge mark 2013-04-11 12:26:45 +00:00
jan.nijtmans f2aea5424e merge-mark 2013-04-09 11:06:43 +00:00
jan.nijtmans 7bfc04bfbe Allow URLs that don't have a path, but a query, e.g. http://example.com?foo=bar and bump http to 2.5.8. 2013-04-09 11:04:49 +00:00
jan.nijtmans f972f06872 Make (deprecated) Tcl_EvalObj/Tcl_GlobalEvalObj macro's always, not only when using stubs. 2013-04-09 10:10:34 +00:00
jan.nijtmans 71d2777cfd fix http package installation 2013-04-08 20:29:44 +00:00
dgp 1ba9a90c6e 3610026 Stop crash when the number of "colors" in a regular expression
overflows a short int.  Thanks to Heikki Linnakangas for the report and
the patch.
2013-04-08 20:07:07 +00:00
dgp 55102c2b83 3610026 Stop crash when the number of "colors" in a regular expression
overflows a short int.  Thanks to Heikki Linnakangas for the report and
the patch.
2013-04-08 19:59:03 +00:00
dgp 7ff52157ed 3610026 Stop crash when the number of "colors" in a regular expression
overflows a short int.  Thanks to Heikki Linnakangas for the report and
the patch.
2013-04-08 19:45:55 +00:00
dgp 2e7505ce3d Demand the error message indicating the purpose of the test. 2013-04-08 19:30:51 +00:00
dgp 93b8f2696a Documentation fix. 2013-04-08 15:58:47 +00:00
dgp b6f570180b 3610026 Stop segfault when regexp overflows color limits. 2013-04-08 15:15:40 +00:00
dgp e6f4d201ce merge-mark 2013-04-04 17:18:35 +00:00
max e0dbb5bd62 Allow URLs that don't have a path, but a query,
e.g. http://example.com?foo=bar and bump http to 2.7.12.
2013-04-04 17:08:43 +00:00
max 8b102ddebc Bump http to 2.8.7 in the other dozen places as well. 2013-04-04 15:00:49 +00:00
max ddfc3d80c5 Bump http to 2.8.7 2013-04-04 14:52:54 +00:00
max 2eed34dc23 Allow URLs that don't have a path, but a query query, e.g. http://example.com?foo=bar . 2013-04-04 14:42:19 +00:00
jan.nijtmans b065abd46c Make Tcl_EvalObj/Tcl_GlobalEvalObj a macro always, not only when using stubs. 2013-04-04 07:07:28 +00:00
jan.nijtmans b5b700cbbd Make Tcl_EvalObj/Tcl_GlobalEvalObj a macro always, not only when using stubs. 2013-04-04 07:03:05 +00:00
jan.nijtmans 2c3cfcfe88 merge trunk 2013-04-03 21:27:52 +00:00
jan.nijtmans bce112e425 some more "ignore-glob" patterns 2013-04-03 20:50:43 +00:00
jan.nijtmans a5be6def4c some more "ignore-glob" patterns 2013-04-03 20:48:38 +00:00
jan.nijtmans 0185f66f16 some more "ignore-glob" patterns 2013-04-03 20:46:41 +00:00
jan.nijtmans 5d03958f22 merge-mark 2013-04-03 13:27:25 +00:00
jan.nijtmans a411cd47dc [Bug 3205320]: stack space detection defeated by inlining. Now fixed in the cross-compile case as well. 2013-04-03 13:26:16 +00:00
dgp 776001cd14 merge-mark 2013-04-03 13:15:47 +00:00
dgp f786fd625e merge release to 8.5 2013-04-03 13:12:47 +00:00
jan.nijtmans 6c3c75da93 Prevent inlining of StackGrowsDown(), in case of cross-compiling 2013-04-02 10:57:56 +00:00
jan.nijtmans 659ee6daa5 Use more macros in stead of thin wrapper functions. 2013-03-31 19:12:06 +00:00
dgp 10d04319d3 Redate. Retag RC1. 2013-03-29 15:08:29 +00:00
dgp be834cf113 Merge 8.5. Tag RC1. 2013-03-28 18:31:02 +00:00
jan.nijtmans a76ebfc825 merge-mark 2013-03-28 14:49:44 +00:00
jan.nijtmans 8f82227afd Undo [6a9ee3273c]. Last commit in Tk's core-8-5-branch makes this change no longer necessary. 2013-03-28 14:48:08 +00:00
dgp 3105dcac7e Tolerate NULL interps 2013-03-27 18:48:07 +00:00
jan.nijtmans 79ad7f2edc merge-mark 2013-03-27 14:13:04 +00:00
jan.nijtmans 6da116b888 Add dummy (undocumented) TclCanceled function in stub table (not exported as symbol or macro), which always returns TCL_OK. Needed for Tk 8.5.14 when running in Tcl 8.6 for properly clean-up when a (Tcl 8.6) thread is canceled. 2013-03-27 14:06:03 +00:00
jan.nijtmans de97184949 merge-mark 2013-03-27 10:49:47 +00:00
jan.nijtmans 0c849580cb remove unneccessary duplication 2013-03-27 10:48:00 +00:00
dgp 0c75115ede Update tzdata and release tags 2013-03-23 20:25:04 +00:00
venkat 4c095a869b Update to tzdata2013b 2013-03-22 23:08:53 +00:00
venkat 1a456da516 Update to tzdata2013b 2013-03-22 23:05:52 +00:00
dgp bbe81d1e5e Tag for release 2013-03-22 16:11:02 +00:00
jan.nijtmans 52cbdda306 If TCL_NO_DEPRECATED is defined, don't depend on Tcl_CreateMathFunc()/Tcl_SaveResult() in testcases any more.
Prevent endless loop in Tcl_AddObjErrorInfo, when TCL_NO_DEPRECATED is defined.
2013-03-22 13:22:40 +00:00
dgp eea431a4b8 Completed changes. 2013-03-22 12:47:36 +00:00
dkf 817b517764 Minor: version number correction. 2013-03-22 09:30:41 +00:00
dgp 0a4e67a3e5 changes WIP 2013-03-22 04:18:04 +00:00
dgp 423209e9fe Release branch for Tcl 8.5.14. 2013-03-21 19:09:25 +00:00
jan.nijtmans 88a893a388 merge-mark 2013-03-21 14:56:44 +00:00
jan.nijtmans 12d983adae Tcl 8.5 doesn't have [try] 2013-03-21 14:56:00 +00:00
jan.nijtmans 453c878fa9 Remove duplicated tests. The enhancements to fCmd-30.[12] and the new test case fCmd-30.3 were backported from Tcl8.6, but the original tests were not removed. 2013-03-21 14:45:09 +00:00
dgp d9db7b2587 test suite hygiene 2013-03-21 14:42:07 +00:00
dgp 29a0269cc5 test suite hygiene 2013-03-21 14:39:17 +00:00
dgp 4c35f9a03a 2102614 Add ensemble indexing support to [auto_mkindex]. Thanks Brian Griffin. 2013-03-21 14:35:34 +00:00
jan.nijtmans f13a861181 Remove duplicated tests. The enhancements to fCmd-30.[12] and the new test case fCmd-30.3 were backported from Tcl8.6, but the original tests were not removed. 2013-03-21 14:32:32 +00:00
jan.nijtmans 4102bfec1a Remove duplicated tests. The enhancements to fCmd-30.[12] and the new test case fCmd-30.3 were backported from Tcl8.6, but the original tests were not removed. 2013-03-21 14:30:27 +00:00
dgp fff161d582 2102614 Add ensemble indexing support to [auto_mkindex]. Thanks Brian Griffin. 2013-03-21 14:28:59 +00:00
dgp fc2ae2acaf Bring forward tests to trunk 2013-03-20 15:39:48 +00:00
dgp f47c327136 dup test names 2013-03-20 15:26:57 +00:00
jan.nijtmans 09d7c9d217 Slightly more correct: If FindFirstFile() fails, the error should be "no such file or directory" (ENOENT) not "permission denied" (EACCES). 2013-03-20 13:41:50 +00:00
jan.nijtmans 4146517b3b Slightly more correct: If FindFirstFile() fails, the error should be "no such file or directory" (ENOENT) not "permission denied" (EACCES). 2013-03-20 13:39:50 +00:00
jan.nijtmans ebd4c75aaa Slightly more correct: If FindFirstFile() fails, the error should be "no such file or directory" (ENOENT) not "permission denied" (EACCES). 2013-03-20 11:18:39 +00:00
jan.nijtmans c988bb3c5d Handle the (unlikely) case that the file is deleted in between. Suggested by Harald Oehlmann (Thanks!) 2013-03-19 14:59:26 +00:00
jan.nijtmans 2c75cac14e Handle the (unlikely) case that the file is deleted in between. Suggested by Harald Oehlmann (Thanks!) 2013-03-19 14:57:45 +00:00
jan.nijtmans fe3f8f0dbc Handle the (unlikely) case that the file is deleted in between. Suggested by Harald Oehlmann (Thanks!) 2013-03-19 14:55:47 +00:00
dgp 06a824d706 3597000 Consistent [file copy] result. 2013-03-19 14:39:09 +00:00
dgp a0b87265ce 3597000 Consistent [file copy] result. 2013-03-19 14:31:56 +00:00
dgp d16b233ed8 3597000 Consistent [file copy] result. 2013-03-19 14:26:10 +00:00
jan.nijtmans 39e89c1b69 [Bug 3608360]: Incompatible behaviour of "file exists". 2013-03-19 13:57:30 +00:00
jan.nijtmans ddc36ee473 [Bug 2893771]: file stat fails on locked files on win32. 2013-03-19 13:48:37 +00:00
jan.nijtmans e22aa5854d make sure that [file stat] returns the right data, even for locked files. 2013-03-19 13:37:40 +00:00
dgp dbafb5fcfc Test independence in fCmd.test 2013-03-19 13:13:37 +00:00
dgp 6f7bddf8cd Test independence in fCmd.test. 2013-03-19 13:11:44 +00:00
jan.nijtmans 91e20aef42 [Bug 2893771]: file stat fails on locked files on win32. 2013-03-19 12:43:21 +00:00
jan.nijtmans 2d0dd29466 Back out bug fix for [Bug 2893771], because it was the cause of the regression. 2013-03-19 11:55:47 +00:00
dkf 28d2c1e4cf [Bug 3606390]: Fix isolation of test string-6.37. 2013-03-19 10:18:18 +00:00
dkf db361019ca [Bug 3606390]: Fix isolation of test string-6.37. 2013-03-19 10:16:12 +00:00
dkf a01b89976f [Bug 3606387]: Fix isolation of test scan-7.4. 2013-03-19 10:06:01 +00:00
dkf b2c63a9461 [Bug 3606387]: Fix isolation of test scan-7.4.
Also updated scan.test to use tcltest 2 properly.
2013-03-19 10:01:26 +00:00
dgp aad97a767b Test independence in fileSystem.test 2013-03-18 18:37:39 +00:00
dgp 8a98d2846f Test independence in fileSystem.test 2013-03-18 18:35:09 +00:00
dgp 3d4bb88f48 Test independence in unixFCmd.test 2013-03-18 18:00:12 +00:00
dgp 520932e706 Test independence in unixFCmd.test. 2013-03-18 17:59:25 +00:00
dkf f8b482aafe [Bug 3608360]: Test to make sure we never let [file exists] do globbing. 2013-03-18 14:30:32 +00:00
dkf 04b2d343ff [Bug 3608360]: Test to make sure we never let [file exists] do globbing. 2013-03-18 14:25:54 +00:00
dkf 480262ad96 [Bug 3608360]: Test to make sure we never let [file exists] do globbing. 2013-03-18 14:22:50 +00:00
dgp cbf4785848 Regenerate configure with autoconf-2.13. Mostly repairs line numbers. 2013-03-12 12:00:18 +00:00
jan.nijtmans 84d3dc55fc Patch by Andrew Shadura, providing better support for three architectures they have in Debian. 2013-03-12 08:47:52 +00:00
jan.nijtmans 57769fb109 Patch by Andrew Shadura, providing better support for three architectures they have in Debian. 2013-03-12 08:45:04 +00:00
jan.nijtmans 3b61982dbe re-generate configure 2013-03-12 08:32:59 +00:00
jan.nijtmans 132dc963f2 Patch by Andrew Shadura, providing better support for three architectures they have in Debian.
(regeneration of "configure" not done yet)
2013-03-12 08:26:15 +00:00
dgp a3d5ba530a 3606391 trace.test test independence. 2013-03-11 19:06:23 +00:00
dgp 1ef6ae9359 3606391 trace.test test independence 2013-03-11 19:05:11 +00:00
dgp 852b1c4ad2 Greater protection against double TclFreeObj() calls in TCL_MEM_DEBUG mode. 2013-03-11 17:40:14 +00:00
dgp 4830e0f883 Greater protection against double TclFreeObj() calls in TCL_MEM_DEBUG mode. 2013-03-11 17:37:15 +00:00
dgp b2f133f23c 3607246,3607372 Unbalanced refcounts of literals in the global literal table. 2013-03-11 12:55:29 +00:00
dgp 21601a3a4a 3607372 Correct literal refcounting. 2013-03-08 21:14:07 +00:00
jan.nijtmans 0ffeb7dd6e Some more ignore-glob settings for msvc, mac, hp .... 2013-03-08 21:12:27 +00:00
jan.nijtmans 57fa6f9669 msvc compiler warning: signed-unsigned mismatch. 2013-03-08 20:57:11 +00:00
dgp 1355f9df46 Correct unbalanced effect of TclInvalidateCmdLiteral() on the refcounts
of literals in the global table.
2013-03-07 21:16:29 +00:00
dgp 31f7c64e7d Cleaner error handling in fixempties(). 2013-03-06 21:55:29 +00:00
dgp 1bee0d67c6 Cleaner error handling in fixempties(). 2013-03-06 21:54:37 +00:00
dgp 139ae23a7a Cleaner error handling in fixempties(). 2013-03-06 21:51:23 +00:00
dgp 1d6248a516 3604074,3606683 Rewrite of the fixempties() routine (and supporting routines)
to completely eliminate the infinite loop hazard.  Thanks to Tom Lane for the
much improved solution.
2013-03-06 20:50:53 +00:00
dgp 7cd2194d47 3604074,3606683 Rewrite of the fixempties() routine (and supporting routines)
to completely eliminate the infinite loop hazard.  Thanks to Tom Lane for the
much improved solution.
2013-03-06 20:28:10 +00:00
dgp b9e95ae529 merge trunk 2013-03-06 20:25:37 +00:00
dgp f233a71161 Rework into Tcl 8.5+ coding style. 2013-03-06 20:19:34 +00:00
dgp 1446f739b6 merge 8.5 2013-03-06 19:56:31 +00:00
dgp 69524610e8 Rework into Tcl 8.5+ coding style. 2013-03-06 19:53:42 +00:00
dgp 738fb82952 3604074,3606683 Rewrite of the fixempties() routine (and supporting routines)
to completely eliminate the infinite loop hazard.  Thanks to Tom Lane for the
much improved solution.
2013-03-06 19:25:41 +00:00
dgp 25986b142b merge 8.4 2013-03-06 19:12:46 +00:00
dgp 648b51cf6b Rework into Tcl 8.4 coding style (closer to original Spencer). 2013-03-06 19:11:44 +00:00
dgp 41cb679571 Indent reduction in fixempties() 2013-03-06 18:10:30 +00:00
dgp c16dc009d7 Indent reduction in fixempties() 2013-03-06 18:01:24 +00:00
dgp 3995d93d0e Indent reduction in fixempties(). 2013-03-06 18:00:21 +00:00
dgp 7b9e7f283b Use flag argument to combine copy(nonempty)* routines into copy* routines. 2013-03-06 17:33:39 +00:00
dgp 2fbb537054 Use flag argument to combine copy(nonempty)* routines into copy* routines. 2013-03-06 17:30:14 +00:00
dgp 9980a32679 Use flag argument to combine copy(nonempty)* routines into copy* routines. 2013-03-06 16:57:41 +00:00
dgp 1a11145339 New routine hasnonemptyout() for minor improvement to new fixempties(). 2013-03-06 16:27:38 +00:00
dgp 55174c7e8a New routine hasnonemptyout() for minor improvement to new fixempties(). 2013-03-06 16:26:18 +00:00
dgp 422a712363 New routine hasnonemptyout() for minor improvement to new fixempties(). 2013-03-06 16:07:14 +00:00
jan.nijtmans eb2860258b Tell fossil and Eclipse that the default eol-convention is LF.
Tell fossil which files are binary and which files should never be committed. 
Tell Eclipse that the default encoding is UTF-8
2013-03-06 12:26:23 +00:00
jan.nijtmans 0af55d7cf3 Add Eclipse .project too 2013-03-06 12:22:55 +00:00
jan.nijtmans 79e3f7f55b Tell fossil and Eclipse that the default eol-convention is LF.
Tell fossil which files are binary and which files should never be committed. 
Tell Eclipse that the default encoding is UTF-8
2013-03-06 12:19:02 +00:00
jan.nijtmans 6e6786882d Tell fossil and Eclipse that the default eol-convention is LF.
Tell fossil which files are binary and which files should never be committed. 
Tell Eclipse that the default encoding is UTF-8
2013-03-06 12:08:46 +00:00
dgp 86eba6192a New internal routine TclFetchLiteral() for better CompileEnv encapsulation. 2013-03-05 22:13:30 +00:00
dgp b96c6536cb Remove from tclCompile.h declarations used in only one source file. 2013-03-05 20:19:14 +00:00
dgp ec4c4a2957 Remove from tclCompile.h declarations used in only one source file. 2013-03-05 20:16:41 +00:00
dgp 48a03a59dc Remove TclInitCompilation() declaration with no definition. 2013-03-05 19:48:42 +00:00
dgp af80656fbe Remove TclInitCompilation() declaration with no definition. 2013-03-05 19:44:57 +00:00
dgp 51f835ba96 Remove TclInitCompilation() declaration that's never had a definition
(14 years!).
2013-03-05 19:39:48 +00:00
dgp aa05129946 Contributed patch from Tom Lane <tgl@users.sf.net>. Merge conflicts due to
different coding style and lingering obsolete compiler support resolved.
2013-03-05 14:38:10 +00:00
dgp 5281598746 Contributed regexp engine patch from Tom Lane. Backports clean from trunk. 2013-03-05 14:04:17 +00:00
dgp 78af51451a Contributed patch from Tom Lane <tgl@users.sf.net>.
Rewrites parts of the regexp engine to avoid infinite loops.
2013-03-05 14:01:48 +00:00
dgp 64e9416261 merge mark 2013-03-04 15:41:59 +00:00
dgp 8141863583 merge mark 2013-03-04 15:40:57 +00:00
dgp 4c642c410e New scheme for keeping the per-process tcl_precision value in sync without
the need for mutex locks on every read.  Uses adapted ProcessGlobalValue
machinery backported from Tcl 8.5 where it's been working without reported
problems.  Thanks to Phil Brooks for reporting on tests which highlight the
thread performance problems raised by the old scheme, and to Clif Flynt for
further testing pointing the finger at tcl_precision locks as the main culprit.
2013-03-04 15:38:01 +00:00
jenglish 3562bfb14b unix/configure: regenerated. 2013-03-03 17:58:34 +00:00
joe 80b3ef95a8 Unix terminal and serial port I/O: retire obsolete termio and sgtty code,
general cleanup.  See SF [Bug 3606258] for details.
2013-03-03 17:57:45 +00:00
joe d98d74151e ... which means struct TtyState can be replaced with struct FileState. 2013-03-02 20:32:43 +00:00
joe bf38d5992f Member TtyState.savedState set in TtyInit() but never subsequently used.
This can go away...
2013-03-02 20:06:09 +00:00
jenglish cd57fb7f7d TtyParseMode signature simplification: take single pointer to struct TtyAttrs
instead of separate pointers to each member.
2013-03-02 07:52:05 +00:00
jenglish 87cfb6b250 More ifdef shuffling: GETREADQUEUE and GETWRITEQEUE always defined,
dummy implementations return 0 if the requisite ioctls are not present.
2013-03-02 07:30:15 +00:00
jenglish 22e4896294 Do not use strncasecmp(). It is nonstandard and not portable.
Use Tcl_UtfNcasecmp() instead.
2013-03-02 07:22:21 +00:00
jenglish 05d33e0fe7 unix/configure: regenerated. 2013-03-01 23:57:13 +00:00
jenglish 82b98d6ede Replace broken SC_SERIAL_PORT macro with plain AC_CHECK_HEADERS tests. 2013-03-01 23:53:49 +00:00
jenglish 38d26a919e ifdef shuffling: TIOCMC[GS]ET ioctls are not specified by POSIX,
so we can't assume they are present just because we HAVE_TERMIOS_H.
Conversely, if they are present then the subsidiary flags
TIOCM_{DTR|RTS} are almost certainly there as well, so that
ifdeffery can be removed.

And lastly, ifdefs for TIOCSBRK/TIOCCBRK are still needed.
(Those are logically separate functions even though TIP#35
lumped them together with DTR and RTS in -ttycontrol.
POSIX provides tcsendbreak() for this purpose, but that
interface doesn't fit with the TIP#35 API.)

KNOWN DEFECT: if a hypothetical Unix system is missing TIOCMCGET
but has TIOCSBRK/TIOCCBRK, the latter function will nevertheless
be unavailable.  Accounting for this possibility does not strike
me as being worth the ifdefs.
2013-03-01 21:13:45 +00:00
dkf ab629d99ba [Bug 3606397]: Make test work in isolation, and corrected what was being tested. 2013-03-01 18:47:20 +00:00
dkf 4b31536c4a [Bug 3606542]: Add missing constraint to test. 2013-03-01 18:33:36 +00:00
dkf 4ec51224f4 [Bug 3606542]: Add missing constraint to test. 2013-03-01 18:30:40 +00:00
jenglish a30cdc4ccf TtyGetOptionProc: remove inoperative comment "The string returned by
this function is in static storage [...]"; this is not the case
(and apparently never has been)
2013-02-28 21:52:02 +00:00
dgp 09ea3ba2ca Revise TclReleaseLiteral() to tolerate a NULL interp argument.
Update callers and revise mistaken comments.
2013-02-28 17:08:43 +00:00
mig 0fa1988fb0 fix coroutine-4.6 so that it runs in isolation, [Bug 3606395] 2013-02-28 14:19:04 +00:00
jan.nijtmans c2f8276ec4 Use more macro's in stead of thin wrapper functions. 2013-02-28 08:47:56 +00:00
jan.nijtmans d3a0c83f09 Allow Tcl to be compiled even if Tcl_Eval, Tcl_GetVar, ... are macros. 2013-02-28 08:29:35 +00:00
jenglish 5436b7c33b TtyGetBaud(), TtyGetSpeed(): use POSIX speed_t typedef
instead of 'unsigned long'.
2013-02-27 23:48:00 +00:00
jenglish 5efbf356ec Remove IOSTATE facade: it's always a struct termios. 2013-02-27 22:30:47 +00:00
jenglish 172de00de5 ifdef reduction - missed a couple spots (#if ... defined(USE_TERMIO)) 2013-02-27 22:12:43 +00:00
jenglish 4a2ab86325 ifdef reduction: SUPPORTS_TTY defined if and only if USE_TERMIOS defined. 2013-02-27 21:09:24 +00:00
jenglish 6765f7766a For termios, we never want DIRECT_BAUD; always use the symbolic constants
as prescribed by POSIX.
2013-02-27 20:33:33 +00:00
jenglish d19847932e termios cleanup step 1: remove USE_TERMIO and USE_SGTTY conditional sections
(mechanical change, done with `unifdef`).
2013-02-27 19:53:04 +00:00
dkf 627504c503 minor: formatting tweaks in the change log 2013-02-27 17:48:10 +00:00
dgp 19a639608f Somewhat tidier, less daunting test. 2013-02-27 15:33:06 +00:00
dgp 900bc4a968 Somewhat tidier, less daunting test. 2013-02-27 15:18:37 +00:00
dgp d2d1deb62a A bit more tidiness expressing the new test expression. 2013-02-27 15:15:30 +00:00
dgp 7c1edfcd97 rejoin the branch 2013-02-27 15:03:10 +00:00
dgp cb554d6c95 Convert test expression into less imposing form. 2013-02-27 14:59:36 +00:00
jan.nijtmans c04398e133 Wrap test-case over multiple lines 2013-02-27 13:26:26 +00:00
jan.nijtmans 04cf158092 Wrap test-case over multiple lines 2013-02-27 13:23:48 +00:00
jan.nijtmans cb0252b19f Wrap test-case over multiple lines. 2013-02-27 13:09:34 +00:00
jan.nijtmans 268394dbb5 Some VOID -> void, Tcl_TraceVar -> Tcl_TraceVar2 and Tcl_VarTraceInfo -> Tcl_VarTraceInfo2 conversions. 2013-02-27 11:42:39 +00:00
jan.nijtmans 5789086c24 [Bug 3606139]: missing error check allows regexp to crash Tcl. Thanks to Tom Lane for providing the test-case and the patch. 2013-02-27 08:19:27 +00:00
jan.nijtmans 40259312fe [Bug 3606139]: missing error check allows regexp to crash Tcl. Thanks to Tom Lane for providing the test-case and the patch. 2013-02-27 08:12:33 +00:00
jan.nijtmans 6332e3ad60 [Bug 3606139]: missing error check allows regexp to crash Tcl. Thanks to Tom Lane for providing the test-case and the patch. 2013-02-27 08:02:36 +00:00
dgp db61e9a4be Remove from tclIO.h structs used only in tclIO.c. 2013-02-26 17:48:09 +00:00
dgp da40794df6 structs *ChannelHandler* GetsState CopyState used only locally.
Remove from tclIO.h.
2013-02-26 17:37:40 +00:00
dgp e3a0ad0f87 structs ChannelHandler ChannelHandlerEvent GetsState CopyState used locally.
Remove from tclIO.h.
2013-02-26 17:15:47 +00:00
dgp 5a5ffc741f struct NextChannelHandler used only locally. Remove from tclIO.h. 2013-02-26 16:38:17 +00:00
dkf ba5b356435 [Bug 3605120]: Stop test chan-io-28.7 from hanging when run standalone. 2013-02-26 13:37:42 +00:00
jan.nijtmans 71c78f086f Don't panic if Tcl_ConvertToType is called for a type that doesn't have a setFromAnyProc, create a proper error message. 2013-02-26 10:17:39 +00:00
jan.nijtmans 93c840992c Don't panic if Tcl_ConvertToType is called for a type that doesn't have a setFromAnyProc, create a proper error message. 2013-02-26 10:15:44 +00:00
dkf 482a2c710e [Bug 3605721]: Test independence fixes for binary-41.* 2013-02-25 18:31:45 +00:00
dgp 39e3f11942 Repair linked list management in Tcl_DeleteCloseHandler().
CloseCallback struct used only locally.  Remove from tclIO.h.
2013-02-25 18:17:26 +00:00
dgp e794120698 Repair linked list management in Tcl_DeleteCloseHandler().
CloseCallback struct used only locally.  Remove from tclIO.h.
2013-02-25 18:15:36 +00:00
dgp 3793c27000 Repair linked list management in Tcl_DeleteCloseHandler().
CloseCallback struct is used only locally.  Remove from tclIO.h.
2013-02-25 18:05:22 +00:00
dgp 96417ebbb8 LimitHandler struct used only locally. Remove from tclInt.h 2013-02-25 16:41:46 +00:00
dgp f974fd8969 LimitHandler struct used only locally. Remove from tclInt.h. 2013-02-25 16:35:07 +00:00
dgp fc262ab6bb Remove unused struct InterpList. 2013-02-25 16:00:48 +00:00
dgp ca06debb81 Remove unused struct InterpList. 2013-02-25 15:57:07 +00:00
dgp 712b68cc80 Array Search struct used only locally. Remove from tclInt.h. 2013-02-25 15:45:13 +00:00
dgp 1136551973 ArraySearch struct used only locally. Remove from tclInt.h. 2013-02-25 15:37:41 +00:00
dgp b436f14398 3605719,3605720 Test independence. Thanks Rolf Ade for patches. 2013-02-25 14:55:17 +00:00
dgp cf7969886b 3605719,3605720 Test independence. Thanks Rolf Ade for patches. 2013-02-25 14:54:14 +00:00
jan.nijtmans e594dd2267 For Unicode 6.3, mongolian vowel separator (U+180e) is nominated to change character class from Space to Control character.
Make sure that "string is space" will continue to return 1 for this character. See TIP #413.
2013-02-25 13:16:21 +00:00
jan.nijtmans ef6c187c6e Bug [3599194]: compat/fake-rfc2553.c is broken 2013-02-23 20:00:49 +00:00
dgp 1a5673d6d1 unused variables 2013-02-22 19:10:32 +00:00
dgp 4cc2a56649 Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine.
Stop crashes when the hookProc raises an error.
2013-02-22 19:05:56 +00:00
dgp 65c016d4a0 Restore the ReleaseCmdWordData cleanup routine from 8.4, to plug very
rare memory leak.
2013-02-22 18:54:56 +00:00
dgp 290b2159a2 Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine.
Stop crashes when the hookProc raises an error.
2013-02-22 18:26:10 +00:00
dgp 6083020b04 Use iPtr field instead of source field to mark a CompileEnv as uninitialized.
envPtr->source == NULL can actually be valid (at least when merging forward).
2013-02-22 18:24:24 +00:00
dgp b4dbbf2a3b Shift more burden of smart cleanup onto the TclFreeCompileEnv() routine.
Stop crashes when the hookProc raises an error.
2013-02-22 17:38:16 +00:00
dgp eaf64a7a9c Protect against multiple uses of a CompileEnv with only one initialization.
Make TclFreeCompileEnv smarter about cleanup so all callers do not have to be.
Revise TclSetByteCodeFromAny() so that when hookProc raises an error, bytecode
is not generated.  This was rumored to cause crashes.
2013-02-21 21:14:55 +00:00
dgp cf93250674 3605447 Make sure the -clear option to [namespace export] always clears,
whether or not new export patterns are specified.
2013-02-21 03:24:19 +00:00
dgp 3e947f695b 3605447 Make sure the -clear option to [namespace export] always clears,
whether or not new export patterns are specified.
2013-02-21 03:16:21 +00:00
dgp 73b3a480c8 3605447 Make sure the -clear option to [namespace export] always clears,
whether or not new export patterns are specified.
2013-02-21 03:04:32 +00:00
dgp 795332afad added test 2013-02-21 02:54:05 +00:00
dgp 5c85215ca6 The flag TCL_LEAVE_ERR_MSG has no effect on the routine
TclGetNamespaceForQualName() so for goodness sake stop making any
special efforts to add it in when making calls.
2013-02-21 02:15:58 +00:00
dgp 23fa2a37a9 refinement 2013-02-20 20:16:16 +00:00
dgp 7b382936b6 36054447 Convert [namespace export -clear] interface to something less stupid.
Test suite does not demand the stupidity continue, thank goodness.
2013-02-20 19:18:42 +00:00
jan.nijtmans e878a050b2 [Bug 3605401]: Compiler error with latest mingw-w64 headers. 2013-02-20 11:43:28 +00:00
jan.nijtmans 4144a690cb [Bug 3605401]: Compiler error with latest mingw-w64 headers. 2013-02-20 11:40:10 +00:00
jan.nijtmans 8c18c33bb8 Bug 3605401: Compiler error with latest mingw-w64 headers 2013-02-20 10:25:59 +00:00
jan.nijtmans 1973e8e40f Fix bug #2438181: Incorrect error reporting in traces.
Test-case and fix provided by Poor Yorick.
2013-02-19 11:36:12 +00:00
jan.nijtmans a01b1afbdd revert mangling with "code" variable. This caused unrelated var.test failures. 2013-02-19 10:53:29 +00:00
jan.nijtmans a2fa2a169f Fix bug #2438181: Incorrect error reporting in traces.
Test-case and fix provided by Poor Yorick.
2013-02-19 10:34:31 +00:00
jan.nijtmans 54ab86e08c Add test-case for Bug #2438181 (which passes in Tcl 8.4 but fails in 8.5/8.6).
Provided by Poor Yorick
2013-02-19 09:50:12 +00:00
jan.nijtmans 08bc505b41 Use (preferred) Tcl_ObjSetVar2 in stead of Tcl_SetVar in tclAppInit.c, both UNIX and Win. 2013-02-17 21:03:56 +00:00
dgp 76602aa738 3604074 Fix regexp optimization to stop hanging on the expression
((((((((a)*)*)*)*)*)*)*)* .  Thanks to Bjørn Grathwohl for discovery.
2013-02-15 15:32:30 +00:00
dgp 24e58b6dcd 3604074 Fix regexp optimization to stop hanging on the expression
((((((((a)*)*)*)*)*)*)*)* .  Thanks to Bjørn Grathwohl for discovery.
2013-02-15 15:27:07 +00:00
dgp e3bbee7b8a revise test numbering for forward merging 2013-02-15 15:15:48 +00:00
dgp fd4b239676 3604074 Fix regexp optimization to stop hanging on the expression
((((((((a)*)*)*)*)*)*)*)* .  Thanks to Bjørn Grathwohl for discovery.
2013-02-15 14:30:44 +00:00
jan.nijtmans 339bf30461 Eliminate last use of Tcl_SetResult (except the use in the Test suite)
Fix depreciation message in tcl.h
2013-02-15 13:01:43 +00:00
dgp 2eb71ac54f New branch bug-3604074 with improved patch to correct fixempties() failure
to converge.
2013-02-14 21:04:25 +00:00
jan.nijtmans c5687412d6 merge-mark 2013-02-14 13:49:11 +00:00
oehhar 4396044600 ChangeLog corrected: msgcat issue must not be XP specific 2013-02-14 13:24:40 +00:00
oehhar f2d8afbb5b ChangeLog corrected: msgcat issue must not be XP specific 2013-02-14 13:23:54 +00:00
jan.nijtmans 882dc5449d [Bug 3604576]: msgcat-1.5.0.tm error on windows XP 2013-02-14 12:11:55 +00:00
jan.nijtmans e03c7973a6 [Bug 3604576]: msgcat-1.5.0.tm error on windows XP 2013-02-14 12:09:19 +00:00
oehhar 930ffee5b9 Finer granulated catch 2013-02-14 11:09:31 +00:00
jan.nijtmans 04d8202a78 Suggested fix for bug 3604576: msgcat -1.5.0.tm error on windows XP, inclusive bump to version 1.5.1.
Changelog entry still missing.
2013-02-14 09:38:11 +00:00
jan.nijtmans 54cce1ee0e Improve some comments and quoting, no change in functionality.
Only check for refCount == 0x61616161 for TCL_MEM_DEBUG build.
2013-02-14 09:01:37 +00:00
jan.nijtmans 5070f0a86a Improve some comments and quoting, no change in functionality 2013-02-14 08:26:30 +00:00
jan.nijtmans e6b2efbad8 Add some extra paths on Windows for finding tclConfig.sh, for mSys and Cygwin shell. 2013-02-14 06:23:43 +00:00
jan.nijtmans cb19aec8e5 merge-mark 2013-02-12 23:21:56 +00:00
jan.nijtmans 0158239e78 Backport various improvements from Tcl 8.5 2013-02-12 23:13:29 +00:00
dkf 3b9c3fb04e Fix [Bug 3603553]. 2013-02-11 08:57:53 +00:00
dkf 200b0db200 Correction to comment in re key buffer size. 2013-02-11 08:54:09 +00:00
dkf deb93dc75c [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-11 08:11:28 +00:00
jan.nijtmans a5a7ae5f47 Unbreak msvc builds, by depending on tclPort.h for inclusion of <sys/stat.h> 2013-02-10 13:26:33 +00:00
jan.nijtmans 41ac300db8 Unbreak msvc builds, by depending on tclPort.h for inclusion of <sys/stat.h>. 2013-02-10 13:12:20 +00:00
dkf 9a43dd0c3b [Bug 3603695]: Change the way that the [oo::object] '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-09 12:30:32 +00:00
dkf 9ec95d17f8 Apply a fix for the bug. Passes the test suite now. 2013-02-09 12:25:36 +00:00
dkf 995e26088f characterize bug 2013-02-08 14:07:10 +00:00
dkf 2015734692 [3603804]: Improve example to actually be capable of throwing the trapped errors 2013-02-08 09:23:56 +00:00
dkf 9f0660744c [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-08 01:44:17 +00:00
jan.nijtmans 52c2de3cb8 Tcl_InvalidateStringRep -> TclInvalidateStringRep 2013-02-07 13:55:38 +00:00
jan.nijtmans ae8888b894 Tcl_InvalidateStringRep -> TclInvalidateStringRep 2013-02-07 13:53:08 +00:00
dgp aee7d6fea4 [Bug 3603434] Make sure TclpObjNormalizePath() properly declares "a:/" to
be normalized, even when no "A:" drive is present on the system.
2013-02-05 16:56:01 +00:00
dgp 765de9e2ef [Bug 3603434] Make sure TclpObjNormalizePath() properly declares "a:/" to
be normalized, even when no "A:" drive is present on the system.
2013-02-05 16:55:32 +00:00
dgp eec7311e64 [Bug 3603434] Make sure TclpObjNormalizePath() properly declares "a:/" to
be normalized, even when no "A:" drive is present on the system.
2013-02-05 16:54:29 +00:00
dgp 4a235274c9 Fix for Bug 3603434. 2013-02-05 16:47:24 +00:00
dkf 1226e764ba [3433012]: Added dummy version of TclpLoadMemory 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-05 09:21:13 +00:00
dkf 7da7ccee61 [Bug 3433012]: Added dummy version of TclpLoadMemory 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-05 09:17:44 +00:00
dgp bfab34ad8b Merge in fix for 3602706 2013-02-04 20:48:50 +00:00
dgp a65850c981 Fix for Bug 3602706. 2013-02-04 18:51:00 +00:00
dgp 2a2af35014 Cherrypick again. Add test. 2013-02-04 18:38:41 +00:00
dgp ccbed687ed Cherrypick the refcount fixes and comments from mig-review.
I also find the revised "createPart2" values in *Lookup* calls appealing,
but I'm too fearful of breaking things without understanding the implications.
This approach just focuses on fixing the things I broke, without trying
to "fix" things long "broken" in multiple years of releases.
2013-02-04 17:13:49 +00:00
dkf 57a9d5c7a9 [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-02-04 14:40:40 +00:00
dkf e24489dcce [3603163]: Prevent odd crashes in 'eval {array set ...}' 2013-02-04 14:30:05 +00:00
jan.nijtmans 9e6725acf0 Eliminate all Tcl_ConvertToType calls and all direct calls to typePtr->setFromAnyProc (except the call from inside the Tcl_ConvertToType function) from the Tcl core. 2013-02-04 10:51:00 +00:00
jan.nijtmans 9088907888 More symmetric Tcl_(Incr|Decr)RefCount call, preventing bugs like #3601260 and #3602706 2013-02-03 11:34:01 +00:00
jan.nijtmans 7ee439ce0f re-apply [8aca9a8e96], while backporting [d91c86d0da] from trunk.
This fixes bugs #3601260 and #3602706
2013-02-03 11:31:47 +00:00
dkf 877a5f8149 merge trunk 2013-02-01 15:32:19 +00:00
jan.nijtmans 618bdeb4c0 cherry-pick [0f098031c3] 2013-01-31 15:04:52 +00:00
dgp 81d4ce37d0 Branch for fixing 3602706 2013-01-31 14:57:55 +00:00
stwo 271de3bc89 Bug [3598282]: Stop using installData.tcl to install the timezone files. 2013-01-31 13:52:15 +00:00
stwo 8f72fe1eb9 Bug [3598282]: Stop using installData.tcl to install the timezone files. 2013-01-31 13:50:38 +00:00
jan.nijtmans 9a5465ed60 merge-mark 2013-01-31 10:32:43 +00:00
jan.nijtmans 16869d9a05 merge core-8-5-branch 2013-01-31 10:31:55 +00:00
jan.nijtmans cc94362836 Fix bug #3601260 and #3602706 by reverting [8aca9a8e96]. This gives time to investigate the issue without too many people being hindered by that. 2013-01-31 09:49:50 +00:00
jan.nijtmans abc1ba4c1c Use twoPtrValue.ptr1 in stead of otherValuePtr everywhere. This is exactly the same field, but it allows twoPtrValue.ptr2 to be used for other purposes. 2013-01-31 09:42:20 +00:00
dgp 4eaaa750d1 For traces and embedding support, select modernizations from Patrick Fradin. 2013-01-31 04:34:11 +00:00
dgp 8f86b72df7 For embedding support, select modernizations from Patrick Fradin 2013-01-31 04:29:30 +00:00
dgp 6d259f9319 Better testevent cleanup and event loop management 2013-01-31 04:07:11 +00:00
dgp b9069b9577 Remove old vars and tests, now unused, one that collides with tcltest. 2013-01-30 22:40:06 +00:00
dgp c241c33749 missing testevent delete 2013-01-30 22:08:05 +00:00
dgp 37ba1458ac For traces, select modernizations from Patrick Fradlin. 2013-01-30 21:34:24 +00:00
dgp 3c9637c2fe For Parse/eval & msgcat, select modernizations from Patrick Fradin + -debug fix 2013-01-30 20:51:43 +00:00
dgp f034dfb455 For msgcat, select modernizations from Patrick Fradin + -debug fix. 2013-01-30 20:49:03 +00:00
dgp 972b9eeb07 For Parse/eval, select modernizations from Patrick Fradin. 2013-01-30 20:42:10 +00:00
andreask a071678d02 (::platform::LibcVersion): See [Bug 3599098]: Fixed the RE extracting
the version to avoid issues with recent changes to the glibc
banner. Now targeting a less variable part of the string. Bumped
package to version 1.0.11.
2013-01-30 19:27:34 +00:00
andreask 9023ee32ce (::platform::LibcVersion): See [Bug 3599098]: Fixed the RE extracting
the version to avoid issues with recent changes to the glibc
banner. Now targeting a less variable part of the string. Bumped
package to version 1.0.11.
2013-01-30 19:18:52 +00:00
andreask 970473c688 (::platform::LibcVersion): See [Bug 3599098]: Fixed the RE extracting
the version to avoid issues with recent changes to the glibc
banner. Now targeting a less variable part of the string. Bumped
package to version 1.0.11.
2013-01-30 19:04:50 +00:00
dgp 7c1d7acf56 For [package] etc., select modernizations from Patrick Fradin. 2013-01-30 19:00:27 +00:00
dgp 62d19c65eb For [package] etc., select modernizations from Patrick Fradin. 2013-01-30 18:58:37 +00:00
dgp aee1b56cc2 In the script library, selected modernizations from Patrick Fradin. 2013-01-30 17:58:00 +00:00
dgp 91a7a404d2 In the script library, selected modernizations from Patrick Fradin. 2013-01-30 17:46:30 +00:00
dgp 7a00fde1d2 More improvements found browsing tcltest 2013-01-30 17:22:49 +00:00
dgp 1f7f9de685 More improvements found browsing tcltest. 2013-01-30 17:15:06 +00:00
dgp 4e523443fe Fradin improvements in test suite too 2013-01-30 16:52:11 +00:00
dgp 16ee47efcc Fradin improvements in test suite too. 2013-01-30 16:51:36 +00:00
dgp 804b3bb41e For tcltest, selected modernizations and style improvements from Patrick Fradin. 2013-01-30 16:34:10 +00:00
dgp b220f67a4e For tcltest, selected modernizations and style improvements from Patrick Fradin. 2013-01-30 16:27:54 +00:00
mig 1e68029cac empty, to jump over mistake 2013-01-29 17:50:15 +00:00
dkf e87a46437e Improve code generation for some ensemble subcommands in cases where full
compilation is impossible yet full ensemble invoking is unnecessary.
Also fix a few minor doc formatting bugs.
2013-01-28 15:16:59 +00:00
dkf 1139530e78 More extensive use of the techniques to improve other edge cases in ensemble compilation. 2013-01-28 11:43:59 +00:00
dkf 5887924a63 Slightly better compilation of some [array] cases. 2013-01-28 01:27:32 +00:00
dkf 5fea85e6d3 merge trunk 2013-01-28 00:57:04 +00:00
jan.nijtmans 13dcbf7d2f [Bug 3601804]: platformCPUID segmentation fault on Darwin 2013-01-26 16:55:24 +00:00
jan.nijtmans fedbfcec36 [Bug 3601804]: platformCPUID segmentation fault on Darwin 2013-01-26 16:53:59 +00:00
jan.nijtmans 6fe094e1ef [Bug 3601804]: platformCPUID segmentation fault on Darwin 2013-01-26 16:50:22 +00:00
mig 28bc611c7b remove unused code 2013-01-25 18:47:45 +00:00
jan.nijtmans 9177f9a41b Another memory leak, and one Tcl_Free -> ckfree 2013-01-25 13:07:59 +00:00
jan.nijtmans 6ec16f5f96 fix minor memory leak 2013-01-25 11:53:41 +00:00
jan.nijtmans 6abe764edc Eliminate some unneeded usages of Tcl_SetResult, Tcl_AddObjErrorInfo
Fix "make test-packages" on cygwin
2013-01-25 11:48:29 +00:00
jan.nijtmans a0eb86a864 new version of cpuid, which doesn't use the edi register any more. Hopefully that works better on some Darwin. 2013-01-24 22:02:30 +00:00
jan.nijtmans f20449d17d new version of cpuid, which doesn't use the edi register any more. Hopefully that works better on some Darwin. 2013-01-24 22:01:38 +00:00
jan.nijtmans 35cf66b42d new version of cpuid, which doesn't use the edi register any more. Hopefully that works better on some Darwin. 2013-01-24 22:00:50 +00:00
jan.nijtmans f028c958cc revert [8e83219e38]: it doesn't work on i386 2013-01-24 21:31:09 +00:00
jan.nijtmans 9663c3b502 revert [f3509c3d35]: it doesn't work on i386 2013-01-24 21:29:56 +00:00
jan.nijtmans 3c5aa93c4e revert [273bbe926d]: it doesn't work on i386 2013-01-24 21:28:43 +00:00
dgp 1a0cb53eec Silence some compiler warnings. 2013-01-24 20:46:58 +00:00
dgp ba7881d6ea Silence come compiler warnings. 2013-01-24 19:09:33 +00:00
dgp 934f9e851f Silence some compiler warnings. 2013-01-24 18:47:18 +00:00
jan.nijtmans a199dc464d merge core-8-5-branch 2013-01-24 14:56:10 +00:00
jan.nijtmans 587cef5259 Simplify STRING_AT macro.
Protect Tcl_GetIndexFromObjStruct from invalid "offset" values, like 0 or -1. Undocumented, because I don't want to promote people start using that.
2013-01-24 08:22:40 +00:00
jan.nijtmans 53cba5d9ba Simplify STRING_AT macro.
Protect Tcl_GetIndexFromObjStruct from invalid "offset" values, like 0 or -1. Undocumented, because I don't want to promote people start using that.
2013-01-24 08:05:42 +00:00
jan.nijtmans 3a39b4007c Fix [2911139]: connect asynchronously, but without unnecessary internal waits. 2013-01-23 14:04:27 +00:00
jan.nijtmans 56fd1342df Protect Tcl_GetIndexFromObjStruct from invalid "offset" values, like 0 or -1. Undocumented, because I don't want to promote people start using that. 2013-01-23 13:57:30 +00:00
dkf 1d751279fa Fix [2911139]: connect asynchronously, but without unnecessary internal waits. 2013-01-23 09:03:46 +00:00
jan.nijtmans 8a8a8b6a83 Now really fix test-case http-4.14 2013-01-22 22:53:26 +00:00
jan.nijtmans 6c54d4f137 Bug [3601804]: platformCPUID segmentation fault on Darwin 2013-01-22 21:58:18 +00:00
jan.nijtmans 3a2c58f0e3 Bug [3601804]: platformCPUID segmentation fault on Darwin 2013-01-22 21:57:27 +00:00
jan.nijtmans 342194b90d Bug [3601804]: platformCPUID segmentation fault on Darwin 2013-01-22 21:56:27 +00:00
jan.nijtmans 357b0f7709 Fix test-case http-4.14 2013-01-22 08:16:44 +00:00
jan.nijtmans 9085296627 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-21 13:51:11 +00:00
dkf e262c66df2 merge main 8.5 branch 2013-01-19 22:25:58 +00:00
jan.nijtmans 98a40cff2c fix Bug 3598300 on MacOSX too 2013-01-19 17:49:16 +00:00
jan.nijtmans b6eebed4e6 fix Bug 3598300 on MacOSX too 2013-01-19 17:48:11 +00:00
jan.nijtmans 21c3f3fee2 Proposed solution for Bug 3598300 on MacOSX 2013-01-18 15:07:18 +00:00
jan.nijtmans 581c5b94ab [Bug 3598300]: unix: tcl.h does not include sys/stat.h.
(with an exception for OSX, for now)
2013-01-18 14:44:45 +00:00
jan.nijtmans 6b531a4b27 ... and fix cygwin build 2013-01-18 14:30:25 +00:00
jan.nijtmans 816626b12f [Bug 3598300]: unix: tcl.h does not include sys/stat.h.
(with an exception for OSX, for now)
2013-01-18 13:58:32 +00:00
mig a6461e6b0d COMPILE_DEBUG big: fix bug in stack verification for {*} 2013-01-17 15:13:40 +00:00
dkf 0a8b2b3150 [3600328]: Fix problems caused by buggy [array] compilation inside a buggy
ensemble compilation (which had the net result of producing *very* wrong code).
2013-01-17 15:08:46 +00:00
jan.nijtmans 928a5b1970 Bug 3601260: Reverting [8aca9a8e96] fixes it. 2013-01-17 14:56:59 +00:00
dkf d31e503f35 merge trunk 2013-01-17 13:46:52 +00:00
jan.nijtmans 43ce79f987 Proposed fix, by kakaroto, for Bug 2911139: http::geturl abuses vwait on async call 2013-01-17 13:29:07 +00:00
jan.nijtmans 6949095cb4 revert [8abba84224], and make sure that every source file that uses Tcl_StatBuf has an "#include <sys/stat.h>" before including tcl.h 2013-01-17 08:38:41 +00:00
jan.nijtmans d1e73c6065 revert [8abba84224], and make sure that every source file that uses Tcl_StatBuf has an "#include <sys/stat.h>" before including tcl.h 2013-01-17 08:28:41 +00:00
dkf de9162b578 merge trunk 2013-01-16 14:16:34 +00:00
dkf f3fe26d49f [Bug 3601086]: Register zlib config as iso8859-1 (a superset of ascii) as that
is an encoding we guarantee to support without loading encoding files.
2013-01-16 11:01:46 +00:00
jan.nijtmans 423ee90c6a Allow win32 build with -DTCL_NO_DEPRECATED, just as the UNIX build, off by default.
Define Tcl_EvalObj and Tcl_GlobalEvalObj as macros, even when TCL_NO_DEPRECATED is defined, so Tk can benefit from it too.
2013-01-16 09:58:26 +00:00
jan.nijtmans 3bbe089a07 Allow win32 build with -DTCL_NO_DEPRECATED, just as the UNIX build, off by default.
Define Tcl_EvalObj and Tcl_GlobalEvalObj as macros, even when TCL_NO_DEPRECATED is defined, so Tk can benefit from it too (this is not what TCL_NO_DEPRECATED is supposed to do).
2013-01-16 09:17:25 +00:00
jan.nijtmans 09c2f769ba and changelog 2013-01-16 08:55:17 +00:00
jan.nijtmans 929948bad8 Allow win32 build with -DTCL_NO_DEPRECATED, just as the UNIX build, off by default.
Define Tcl_EvalObj and Tcl_GlobalEvalObj as macros, even when TCL_NO_DEPRECATED is defined, so Tk can benefit from it too (this is not what TCL_NO_DEPRECATED is supposed to do).
2013-01-16 08:52:59 +00:00
jan.nijtmans eebca1b422 [Bug 3598300]: unix: tcl.h does not include sys/stat.h 2013-01-15 21:06:32 +00:00
mig 0da09b361f peephole INST_START_CMD before entering the big switch in tebc 2013-01-15 19:37:30 +00:00
mig d7bd3ea929 merge trunk 2013-01-15 19:35:52 +00:00
mig 4a942632c1 remove [4522b11989], it breaks the build on linux 2013-01-15 19:26:45 +00:00
jan.nijtmans 19ba6d24b8 REMOVED FROM TRUNK: buggy, breaks the build on linux. [Bug 3598300]: unix: tcl.h does not include sys/stat.h 2013-01-15 17:38:57 +00:00
jan.nijtmans 5d8dc198ff [Bug 3598300]: unix: tcl.h does not include sys/stat.h 2013-01-15 17:32:13 +00:00
jan.nijtmans 5d071002e5 More flexible search for win32 tclConfig.sh, backported from TEA (not actually used in Tcl, only for Tk) 2013-01-14 20:13:41 +00:00
jan.nijtmans 1415e8eb0e merge trunk
remove some EXTERN and CONST usages in tclUnixPort.h
2013-01-14 19:56:43 +00:00
jan.nijtmans 89971c7559 forgot two #undef's 2013-01-14 15:23:41 +00:00
jan.nijtmans e267380dad 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-14 15:19:18 +00:00
mig 0e4e7f881d Various bits of cleanup, efficiencies, and comment documentation in tclVar.c (from mig-review) 2013-01-13 23:26:02 +00:00
mig 9a14873b85 Various bits of cleanup, efficiencies, and comment documentation in tclVar.c (from mig-review) 2013-01-13 23:15:10 +00:00
ferrieux 89369231f5 Clarify readable fileevent "false positives" in the case of multibyte encodings/transforms [Bug 3436609]. 2013-01-13 18:12:41 +00:00
jan.nijtmans a2021967ac 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-13 09:13:45 +00:00
jan.nijtmans 3327b4aa93 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-13 09:04:10 +00:00
jan.nijtmans 9822c32dd0 Put back TclBackgroundException in internal stub table, so extensions using this, compiled against 8.5 headers still run in Tcl 8.6. 2013-01-12 21:57:24 +00:00
mig 25ab9d5408 discouraging the compiler from re-reading *pc in the peephole loop, part2 (any diff?) 2013-01-12 10:53:23 +00:00
mig 7715309bee discouraging the compiler from re-reading *pc in the peephole loop 2013-01-12 10:49:25 +00:00
mig b4e2d9a5f7 even better ... or so I hope: also inlining INST_PUSH1 in the peephole, checking for ISC after LOAD1 and PUSH1 2013-01-12 10:14:06 +00:00
mig e81a0740ec merge trunk 2013-01-11 23:29:46 +00:00
mig d81457480e better comments 2013-01-11 21:16:07 +00:00
mig eff3ee2c12 fix for consecutive ISC (produced by [while 1 {...}) 2013-01-11 18:05:50 +00:00
dgp e5f2221983 Test for Bug 1884496 (not buggy on trunk). 2013-01-11 17:27:38 +00:00
mig 216a40de66 testing a cheaper(?) INST_START_COMMAND 2013-01-11 15:37:10 +00:00
dkf 793f8e5aba merge trunk 2013-01-11 14:15:12 +00:00
dkf ee55e0197b First attempt at fixing problems caused by [array set] inside [namespace eval],
which caused partial bytecode generation followed by a reject which triggered
the issuing of generic ensemble code with an extra push of the variable name at
the start (which got the stack depth wrong).
2013-01-11 14:04:33 +00:00
mig 43988caaa2 Name functions according to 'what' instead of 'how' in the [tailcall]
machinery, in view of making public some parts of it.
2013-01-11 12:42:14 +00:00
mig d562dc0f60 tailcall now running in a simpler model, with no eval-flags and no nre-stack rewriting; yieldto also requires one fewer bounce. Mostly from mig-nre-mods 2013-01-10 21:18:52 +00:00
mig 9f0eb68928 fix off-by-one error introduced in bd7d7a2061 2013-01-10 18:17:33 +00:00
jan.nijtmans 5c3966aa9c merge-mark 2013-01-09 21:31:23 +00:00
jan.nijtmans 885f2d55e3 Backported [Bug 2882342]: correct struct _REPARSE_DATA_BUFFER in tcl 8.4 2013-01-09 15:43:54 +00:00
jan.nijtmans 8f2f7117fc [Bug 3599395]: http assumes status line is a proper tcl list. 2013-01-09 14:07:08 +00:00
jan.nijtmans 34d5896205 [Bug 3599395]: http assumes status line is a proper tcl list.
Bump http package to 2.7.11.
2013-01-09 14:00:15 +00:00
jan.nijtmans 24b681cb7a $builddir is a local variable 2013-01-08 13:03:01 +00:00
jan.nijtmans f1b40ee639 [Bug 3092089]: [file normalize] can remove path components.
[Bug 3587096] win vista/7: "can't find init.tcl" when called via junction.
2013-01-08 10:27:42 +00:00
jan.nijtmans 638edeffa4 [Bug 3092089]: [file normalize] can remove path components.
[Bug 3587096] win vista/7: "can't find init.tcl" when called via junction.
2013-01-08 10:17:54 +00:00
jan.nijtmans dd0ed45dbb [Bug 3092089]: [file normalize] can remove path components.
[Bug 3587096] win vista/7: "can't find init.tcl" when called via junction.
2013-01-08 10:13:20 +00:00
jan.nijtmans e4b4a00f17 new attempt for better fix 2013-01-08 08:44:33 +00:00
jan.nijtmans ada7e74894 mSys doesn't have $PWD. Reported by Rene Zaumseil on Tcl Core list 2013-01-08 08:08:28 +00:00
jan.nijtmans 978558169e Restrict the stub library to only use 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-07 14:40:56 +00:00
jan.nijtmans 0d214a0a14 merge-mark. Hoping trunk is OK now, again ;-( 2013-01-07 13:00:26 +00:00
jan.nijtmans 4087d33e18 Extend the public stub table with dummy NULL entries, up to the size of the Tcl 8.6 stub tables.
This makes it easier to debug extensions which use Tcl 8.6 features but (erroneously) are attempted to be loaded in Tcl 8.5.
2013-01-07 11:16:50 +00:00
jan.nijtmans 8533669f18 Extend the public and private stub tables with dummy NULL entries, up to the size of the Tcl 8.6 stub tables.
This makes it easier to debug extensions which use Tcl 8.5/8.6 features but (erroneously) are attempted to be loaded in Tcl 8.4.
2013-01-07 11:06:16 +00:00
jan.nijtmans 8a7422b2db Don't call "ulimit" on cygwin: On Cygwin the stack size cannot be modified, and the reported stacksize is much lower than the real one. 2013-01-07 09:59:56 +00:00
jan.nijtmans b2dabdc1eb Don't depend on Spencer-specific regexp syntax (/u and /U) any more in unrelated places
.  Bump http package to 2.8.6.
2013-01-06 20:40:57 +00:00
dkf 4a7aba80a6 merge trunk 2013-01-05 18:16:06 +00:00
mig a8a9d42601 improved stack checking under TCL_COMPILE_DEBUG 2013-01-05 03:43:05 +00:00
jan.nijtmans d223d51178 merge fork 2013-01-05 00:39:21 +00:00
mig 7fbeaf9528 fix the new assertion, it should not trigger when an expansion is in progress 2013-01-05 00:36:25 +00:00
jan.nijtmans 2c5cd34ebe adjust stub library version number 2013-01-05 00:36:25 +00:00
jan.nijtmans 13adf38211 adjust stub library version number 2013-01-05 00:33:21 +00:00
jan.nijtmans 88af143aea adjust stub library version number 2013-01-05 00:28:11 +00:00
mig 9b6ebeae02 Add an assertion that checks the stack depth under TCL_COMPILE_DEBUG *before* stack cleanup. It currently triggers at several spots in the testsuite! 2013-01-05 00:15:19 +00:00
dkf 5bce11a1c8 Fix memory leak in [format] compiler. 2013-01-04 15:01:57 +00:00
dkf 32cc5d8d3c Fix bad memory access problems found by Miguel Sofer when valgrinding. 2013-01-04 14:38:37 +00:00
dkf e2e14fde2d merge trunk 2013-01-04 11:14:59 +00:00
dkf 679963704f Improve code generation for many simple core ensemble subcommands. 2013-01-04 11:14:21 +00:00
dkf 32df42787e Add super-simple compiler to many ensemble subcommands to allow better code
generation where we can detect that we're not in the WrongNumArgs case.
The compiler just checks that the argument count is in the right range and
issues a standard dispatch; that's enough to do an efficient job.
2013-01-04 11:06:14 +00:00
mig 0cf062c388 Insure that PURIFY builds cannot exploit the Tcl stack to hide mem defects. 2013-01-04 05:26:40 +00:00
dkf 207412c303 "Mine eyes deceive, but others catch me when I fall." -- Someone or other 2013-01-03 14:35:07 +00:00
dkf bf368d9079 Channel buffer min size is 1. Issue found by Schelte Bron. 2013-01-03 14:24:48 +00:00
dgp 45c7f36909 speling ficks 2013-01-03 14:02:21 +00:00
dgp 285dd19c62 speling ficks 2013-01-03 14:00:37 +00:00
jan.nijtmans 2410e50d8e suggested fix for Bug 3092089: [file normalize] can remove path component,
and for Bug 3587096: startup error message when exe in folder with junction with limited rights
2013-01-03 11:40:51 +00:00
dkf 240695b9f5 merge trunk 2013-01-03 10:25:23 +00:00
dkf 3aba154e26 Added mechanism for pre-parsing built-in ensembles even when they are not going
to generate specific code. This provides a good speedup in some cases.
2013-01-03 10:23:01 +00:00
jan.nijtmans 1bef171761 test case for bug-3598580: Tcl_ListObjReplace may release deleted elements too early 2013-01-03 09:46:57 +00:00
jan.nijtmans a7affdff05 test case for bug-3598580: Tcl_ListObjReplace may release deleted elements too early 2013-01-03 09:29:18 +00:00
jan.nijtmans 8ddb48c272 test case for bug-3598580: Tcl_ListObjReplace may release deleted elements too early 2013-01-03 09:22:04 +00:00
dkf 3ce1c8d98b Got the test suite passing cleanly. Excellent. 2013-01-03 00:37:29 +00:00
mig ef5aee8d47 no changes, sync with core-8-5-branch to signal the backported fix 2013-01-02 19:28:57 +00:00
mig ca4329f20b remove stray calls to Tcl_Alloc and friends: the core should only use ckalloc to allow MEM_DEBUG to work properly 2013-01-02 19:27:09 +00:00
mig 8d4878fee6 remove stray calls to Tcl_Alloc and friends: the core should only use ckalloc to allow MEM_DEBUG to work properly 2013-01-02 19:20:54 +00:00
dkf b0465ff0e8 merge trunk 2013-01-02 18:35:39 +00:00
dkf f9651e0da6 All tests pass except one; not sure what's wrong there. 2013-01-02 18:33:27 +00:00
dkf 18ab8f43a0 Passing more tests. 2013-01-02 15:10:00 +00:00
jan.nijtmans 77014e3f62 test Tcl_GetErrorLine() forwards/backwards compatibility in pkgb.so as well.
Don't free ctrl.script if thread creation fails: it is a constant string "testthread wait" normally.
2013-01-02 14:37:23 +00:00
jan.nijtmans 46821e04b6 test Tcl_GetErrorLine() forwards/backwards compatibility in pkgb.so as well.
Marked some string subcommands as obsolete, following discussion on tcl-core. 
Don't free ctrl.script if thread creation fails: it is a constant string "testthread wait" normally.
2013-01-02 14:30:30 +00:00
jan.nijtmans 51e5bda476 Don't free ctrl.script if thread creation fails: it is a constant string "testthread wait" normally. 2013-01-02 14:18:15 +00:00
jan.nijtmans 656b2b4f87 Marked some string subcommands as obsolete, following discussion on tcl-core. 2013-01-02 14:16:03 +00:00
jan.nijtmans 0fbd4e16a9 test Tcl_GetErrorLine() forwards/backwards compatibility in pkgb.so as well 2013-01-02 14:12:40 +00:00
dkf c0845253a0 Marked some string subcommands as obsolete, following discussion on tcl-core. 2012-12-31 12:32:13 +00:00
dkf 38ba6bd5d4 Working towards more efficient treatment of non-bytecoded ensemble subcommands. 2012-12-31 02:39:40 +00:00
jan.nijtmans 0c64074372 restore refcounts as they were before the Tcl_ListObjReplace call, in the error situation.
In Tcl9, make this a true Tcl_DecrRefCount, which properly cleans objects with refCount 0
2012-12-29 09:23:24 +00:00
jan.nijtmans 53eb119d0b restore refcounts as they were before the Tcl_ListObjReplace call, in the error situation.
In Tcl9, make this a true Tcl_DecrRefCount, which properly cleans objects with refCount 0
2012-12-29 09:16:43 +00:00
jan.nijtmans 8751239349 For Tcl9, do a real Tcl_DecrRefCount 2012-12-29 00:06:42 +00:00
jan.nijtmans bf14f11c63 restore old refcounts in TCL_ERROR case. 2012-12-27 20:54:31 +00:00
jan.nijtmans d12ee9da30 [Bug 3598580]: Tcl_ListObjReplace may release deleted elements too early 2012-12-27 15:04:11 +00:00
jan.nijtmans 78d91cb253 [Bug 3598580]: Tcl_ListObjReplace may release deleted elements too early 2012-12-27 14:57:32 +00:00
jan.nijtmans 66c2909694 [Bug 3598580]: Tcl_ListObjReplace may release deleted elements too early
Tests!?  Where are the tests!?!

They are in test listobj-11.1
2012-12-27 14:41:15 +00:00
jan.nijtmans d83a20092e proposed fix for Bug 3598300 2012-12-26 10:07:54 +00:00
jan.nijtmans 65013d771a eliminate dependancy of compat/*.h on tcl.h 2012-12-26 09:59:44 +00:00
jan.nijtmans 4b67a9506b eliminate dependancy of compat/*.h on tcl.h 2012-12-26 09:55:45 +00:00
dkf 74cca07e35 merge trunk 2012-12-23 08:18:10 +00:00
dkf e2e451e2e5 Change back to using an isDigit function. We simply don't need to make any
(formally non-portable) assumptions about what happens when an unsigned zero
is decremented, and the code isn't in a performance-critical area.

Remark by jan.nijtmans: The macro is perfectly portable! Not portable is the
exact result of the substraction ('\xB0' - '0' might give 0x80 on some platforms and 0xffffff80 on others), but comparing <= 9 always gives the correct result. We are only checking for digits here! The macro correctly inlines with any compiler, so it's better anyway.

Remark by dkf: But it's less clear. In this code, that's more important than a teeny bit of speed from inlining in a non-critical location.
2012-12-23 08:17:17 +00:00
ferrieux ed156a09fa Stop leaking allocated space when objifying a zero-length DString. [Bug 3598150] spotted by afredd. 2012-12-22 19:05:34 +00:00
dkf 8f40b2b313 merge release 2012-12-22 15:21:56 +00:00
jan.nijtmans 21bd9cf5ad Inline compat Tcl_GetDefaultEncodingDir.
Eliminate unnecessary static HasStubSupport() and isDigit() functions, just do the same inline.
2012-12-21 09:13:31 +00:00
jan.nijtmans ebbf7144d2 Make pkgb.so loadable in Tcl 8.4 as well.
Eliminate unnessarcy static HasStubSupport() and isDigit() functions, just do the same inline.
2012-12-21 08:36:38 +00:00
jan.nijtmans fac8f9d0ae Turn pkgb.so into a Tcl9 interoperability test library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should either result in an error-message, either succeed, but never crash.
Eliminate unnessarcy static HasStubSupport() and isDigit() functions, just do the same inline.
2012-12-21 08:16:50 +00:00
dgp f3a3f7b9e8 merge release 2012-12-21 06:16:00 +00:00
dkf a2afb09b3c Improved the sequence of instructions issued for [subst] when dealing with
simple variable references.
2012-12-18 14:02:43 +00:00
dkf 81a67b9cf4 Better version that can handle simple composite array keys as well. As long as
they are free of command substitutions, we can still safely omit the exception
processor code.
2012-12-18 10:21:34 +00:00
dkf 569360bf40 Generate better code for the common case of subst-ed variables where the
variable is a simple scalar or an array with a simple literal element name.
2012-12-18 09:37:42 +00:00
dkf 59e42de547 merge trunk 2012-12-18 09:02:38 +00:00
dkf fa7a06447d Simpler code to do installation of [info class] and [info object].
We know this is a safe thing to do as we know this is inside Tcl_CreateInterp()
and so no confounding code could have been run.
2012-12-17 14:40:17 +00:00
dkf b13b1c6020 Slim down the code a bit more; we can make more safe assumptions. 2012-12-17 14:27:44 +00:00
dgp d67ebaffd4 merge trunk, update changes and re-tag 2012-12-14 19:25:04 +00:00
dgp 237b1ee14a Various bits of cleanup, efficiencies, and comment documentation in tclVar.c 2012-12-14 17:47:55 +00:00
dgp 8890130ab8 TIP 400 suffered from the same segfaulting flaw as 3595576.
Segfaulting test and fix committed.
2012-12-13 20:20:46 +00:00
dgp 093fb49d43 Simplify the [info object] and [info class] additions. 2012-12-13 19:43:43 +00:00
dgp 0ccb6618bd Restore clarity to macro test. 2012-12-13 16:17:13 +00:00
dgp 989c5bb9a4 Restore clarity to macro test. 2012-12-13 16:16:40 +00:00
dgp 94ada5d31f Restore clarity to macro test. 2012-12-13 16:11:07 +00:00
dgp af92fc0c28 Merge 3595576 tests from 8.5. 2012-12-13 16:08:13 +00:00
dgp 4557297b08 3595576 Tests/fix for mem corruption: [catch] fails to store options in a var. 2012-12-13 15:59:51 +00:00
mig 1d29f93257 Fix for [Bug 3595576], found by andrewsh 2012-12-13 13:37:19 +00:00
jan.nijtmans 9918a06afa Changelog entry, and change macro variable to not conflict with possible outside variable names 2012-12-13 12:14:37 +00:00
jan.nijtmans e1c8f78ed0 Changelog entry, and change macro variable to not conflict with possible outside variable names 2012-12-13 12:09:21 +00:00
jan.nijtmans b9a522a6bf Changelog entry, and change macro variable to not conflict with possible outside variable names 2012-12-13 12:03:51 +00:00
jan.nijtmans eace9319cb Fix Tcl_DecrRefCount macro, not to refer to its objPtr parameter twice. 2012-12-13 11:02:15 +00:00
jan.nijtmans eb7f17ba98 Fix Tcl_DecrRefCount macro, not to refer to its objPtr parameter twice. 2012-12-13 11:00:13 +00:00
jan.nijtmans 2f1b92ba12 Fix Tcl_DecrRefCount macro, not to refer to its objPtr parameter twice. 2012-12-13 10:48:04 +00:00
dgp 6428006e92 Prefer to extract package data from the *contents* not the directory name. 2012-12-12 20:16:13 +00:00
dgp 78a3c34ca2 Tag 8.6.0 for release 2012-12-11 21:31:18 +00:00
dgp c13ee047c8 update changes 2012-12-11 21:19:11 +00:00
dkf c1784e6b4c Improve the generation of HTML documentation in 8.6, allowing for contributed
packages whose non-version name parts are prefixes of others. Also ensure that
documentation builds are complete after distribution, and that we generate a
better error message when using the wrong tclsh version to do the build.
2012-12-10 23:23:50 +00:00
dgp 498562a0e5 merge trunk 2012-12-10 15:58:23 +00:00
dgp 15f02f424c Restore the initialization of tclStubsPtr from the "Tcl" package clientData
so that we don't close off a potential avenue of future innovations.
2012-12-10 14:17:19 +00:00
dgp c20c0a1e75 Restore the initialization of tclStubsPtr from the "Tcl" package clientData
so that we don't close off a potential avenue of future innovations.
2012-12-10 14:15:18 +00:00
dgp 6d80a782d0 Restore the initialization of tclStubsPtr from the "Tcl" package clientData
so that we don't close off a potential avenue of future innovations.
2012-12-10 14:08:59 +00:00
ferrieux 2fd9e3776b [Bug 3594188] Clarifications about commas. 2012-12-09 19:44:57 +00:00
ferrieux 16df5aebc9 Clean up unwanted eofchar side-effect of chan-4.6 leading to a spurious "'" at end of chan.test under certain conditions (see [Bug 3389289] and [Bug 3389251]). 2012-12-09 11:52:04 +00:00
ferrieux 8a282bbf9e Fix busyloop at exit under TCL_FINALIZE_ON_EXIT when there are unflushed nonblocking channels. Thanks Miguel for spotting. 2012-12-08 17:13:03 +00:00
jan.nijtmans 5e55e0d280 just lost one MODULE_SCOPE in the merge 2012-12-07 22:14:26 +00:00
jan.nijtmans bd8d73a7d5 only set tclStubsPtr if all version checks pass 2012-12-07 21:36:34 +00:00
jan.nijtmans b361c43c61 only set tclStubsPtr when all version checks pass 2012-12-07 21:30:31 +00:00
jan.nijtmans 9f45d4d696 only set tclStubsPtr if all version checks pass. Backported from tcl 8.5. 2012-12-07 21:28:49 +00:00
dgp aa34213e75 merge trunk 2012-12-07 19:26:49 +00:00
dgp b54c784f20 3593703 Don't crash on bad input to Tcl_PkgRequire*(). 2012-12-07 18:08:48 +00:00
dgp 5af462da66 3593703 Don't crash on bad input to Tcl_PkgRequire*(). 2012-12-07 18:07:18 +00:00
dgp c46c79caa2 Source compat, rather than stubs compat demo. 2012-12-07 17:03:39 +00:00
mig 2adea0d04e small correction in doc/NRE.3 2012-12-07 15:56:13 +00:00
jan.nijtmans 7720b5d9df fix failing test 2012-12-07 15:53:29 +00:00
jan.nijtmans f894c98ebc add proper runtime-detection to pkgb.so 2012-12-07 15:51:25 +00:00
dgp 1aa7610988 Extended test of [load]ing Tcl 8 compiled extension into Tcl 9 interp. 2012-12-07 14:53:40 +00:00
jan.nijtmans 02929519ba Turn pkgb.so into a Tcl9 interoperability test
library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should
either result in an error-message, either succeed, but never crash.
2012-12-07 09:56:39 +00:00
jan.nijtmans 49e8fc13b0 Turn pkgb.so into a Tcl9 interoperability test
library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should
either result in an error-message, either succeed, but never crash.
2012-12-07 09:53:58 +00:00
dgp 22f216f372 Tcl_InitStubs("8.5",1) would succeed in an "8.50" interp. Fixed. 2012-12-06 21:10:19 +00:00
dgp 55563ee093 Tcl_InitStubs("8.5",1) would succeed in an "8.50" interp. Fixed. 2012-12-06 21:03:22 +00:00
jan.nijtmans 38ee3de94f do some Tcl_EvalEx, for test-purposes, demonstrating a crash 2012-12-05 22:38:20 +00:00
jan.nijtmans c9c4a3ad02 use Tcl_PkgProvideEx everywhere (again, for testing purposes) 2012-12-05 14:42:48 +00:00
jan.nijtmans 43e62982f4 merge trunk
Change TCL_VERSION to "8.6-" everywhere in Tcl_InitStubs. This is not the way how to do it! Just for testing purposes.
2012-12-05 14:21:55 +00:00
jan.nijtmans 59aff80a90 Fix gcc warning in cygwin build: implicitely declared function TclUnixOpenTemporaryFile.
Move the function to slot 30, and define it (as 0) for win32 as well.
2012-12-05 13:31:22 +00:00
dgp 5240308ed2 merge trunk 2012-12-04 20:40:50 +00:00
jan.nijtmans 0dcab1bed4 MODULE_SCOPE symbol names are suppoted to start with 'tcl' (data) or 'Tcl' (code) 2012-12-04 13:39:07 +00:00
dgp 85ca4a31a0 Disable the legacy configuration setting from $::argv only when a setting call
to [configure] is made. Queries should not disturb that support.
Bump to tcltest 2.3.5.
2012-12-03 19:50:03 +00:00
dgp 553348c5f3 Disable the legacy configuration setting from $::argv only when a setting
call to [configure] is made. Queries should not disturb that support.
Bump to tcltest 2.3.5.
2012-12-03 19:19:05 +00:00
dgp 658b4c0ee7 Disable the legacy configuration setting from $::argv only when a setting
call to [configure] is made.  Queries should not disturb that support.
Bump to tcltest 2.2.11.
2012-12-03 19:14:32 +00:00
dgp 41d3318c10 Tcl headers already protect from EXTERN defines 2012-12-03 14:35:43 +00:00
dgp 8354804874 Post-header reform (long long ago now) Tcl headers take care of their own
protection from EXTERN definitions.
2012-12-03 14:33:17 +00:00
jan.nijtmans bf4c66a207 Allow http, msgcat and tcltest to be loaded by Tcl 9 as well. I think
that this should be included in tcl8.6.0: Those 3 packages are so
widely used, we don't want to introduce Tcl-level incompatibilities
in Tcl9 such that those packages wouldn't work any more.

Moved to branch novem-support.  For now, novem is a playground.
The trunk is not.  By all means lets track what we need for 
migration, but hold back committing to them until we commit
more meaningfully to where we're going.
2012-12-02 14:35:03 +00:00
dkf 70d1d20609 Inform the HTML builder about the TDBC drivers. 2012-11-30 09:16:16 +00:00
dgp b7ab8113fe 3588687 When detecting incompatibility during stubs initialization, the error
message has always assumed a stubs-disabled 8.0 interp to be the cause. That's
no longer a good assumption. More suitable error message committed.
2012-11-29 14:54:51 +00:00
dgp 80108bef0e 3588687 When detecting incompatibility during stubs initialization, the error
message has always assumed a stubs-disabled 8.0 interp to be the cause. That's
no longer a good assumption. More suitable error message committed.
2012-11-29 14:50:08 +00:00
dgp e2ddd4a2fd 3588687 When detecting incompatibility during stubs initialization, the error
message has always assumed a stubs-disabled 8.0 interp to be the cause.
That's no longer a good assumption.  More suitable error message committed.
2012-11-29 14:47:12 +00:00
dgp 96295b0151 silence compiler warning 2012-11-29 13:15:36 +00:00
dkf 7cd225ff30 Silence some (unimportant) warnings from the MIPSpro compiler. 2012-11-28 08:52:00 +00:00
dkf fa84674fb9 [3590483]: Some compilers cannot initialize with complex non-constants. 2012-11-28 00:04:31 +00:00
max a1beeadf6c Factor out creation of the -sockname and -peername lists from
TcpGetOptionProc() to TcpHostPortList().  Make it robust against
implementations of getnameinfo() that error out if reverse mapping
fails instead of falling back to the numeric representation.
2012-11-26 17:40:29 +00:00
dgp fcf174f284 merge trunk 2012-11-26 15:28:12 +00:00
dgp 29dd55c971 doc formatting goofs 2012-11-26 15:27:44 +00:00
dgp 52e06a03d8 merge trunk 2012-11-22 17:27:03 +00:00
jan.nijtmans 8f22bd9be0 Fix bug reported by Brian Griffin:
<p>[http://code.activestate.com/lists/tcl-core/12524/]
2012-11-22 08:49:46 +00:00
jan.nijtmans 5d659010d2 Fix bug reported by Brian Griffin:
<p>[http://code.activestate.com/lists/tcl-core/12524/]
2012-11-22 08:47:37 +00:00
jan.nijtmans 8e1d78b43a Fix bug reported by Brian Griffin:
<p>[http://code.activestate.com/lists/tcl-core/12524/]
2012-11-22 08:45:39 +00:00
dkf db0645ad80 [Bug 3033307]: fix [binary decode base64] whitespace handling with '=' suffixes 2012-11-20 12:11:57 +00:00
dkf 6e2667d4d2 merge trunk 2012-11-19 22:10:10 +00:00
dgp b670d49ae2 merge trunk 2012-11-19 17:30:33 +00:00
dgp 91d791cd85 merge trunk 2012-11-16 12:52:39 +00:00
dgp 275cdefdd7 merge trunk: 2012-11-15 01:54:58 +00:00
dgp f14b389544 merge trunk 2012-11-14 16:57:23 +00:00
dgp b8076815be merge trunk 2012-11-13 21:31:30 +00:00
dgp 6734623337 merge trunk 2012-11-08 15:44:09 +00:00
dgp ea58b7b66f Declare TclOO portion of the Tcl API to be stable -> TclOO 1.0 2012-11-08 15:43:45 +00:00
dgp 7635c56e5d Create Tcl 8.6.0 release branch 2012-11-08 15:25:30 +00:00
dkf ec58b631ce merge trunk: INST_TAILCALL has bug 2012-11-05 21:47:12 +00:00
dkf 49dd27a4ea merge trunk 2012-11-05 15:17:26 +00:00
218 changed files with 6820 additions and 4344 deletions
+3
View File
@@ -0,0 +1,3 @@
*.bmp
*.gif
*.png
View File
+24
View File
@@ -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
+11
View File
@@ -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>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
+2
View File
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
line.separator=\n
+475
View File
@@ -1,3 +1,477 @@
2013-04-19 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclDecls.h: Implement many Tcl_*Var* functions and
Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp
their Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct.
2013-04-12 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclDecls.h: Implement Tcl_Pkg* functions as
(faster/stack-saving) macros around Tcl_Pkg*Ex functions.
2013-04-08 Don Porter <dgp@users.sourceforge.net>
* generic/regc_color.c: [Bug 3610026] Stop crash when the number of
* generic/regerrs.h: "colors" in a regular expression overflows
* generic/regex.h: a short int. Thanks to Heikki Linnakangas
* generic/regguts.h: for the report and the patch.
* tests/regexp.test:
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 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.
2013-01-06 Jan Nijtmans <nijtmans@users.sf.net>
* library/http/http.tcl: Don't depend on Spencer-specific regexp
* tests/env.test: syntax (/u and /U) any more in unrelated places.
* tests/exec.test:
Bump http package to 2.8.6.
2013-01-04 Donal K. Fellows <dkf@users.sf.net>
* generic/tclEnsemble.c (CompileBasicNArgCommand): Added very simple
compiler (which just compiles to a normal invoke of the implementation
command) for many ensemble subcommands where we can prove that there
is no way for scripts to detect the difference even through error
handling or [info level]/[info frame]. This improves the code produced
from some ensembles (e.g., [info], [string]) to the point where the
ensemble is now not normally seen at the bytecode level at all.
2013-01-04 Miguel Sofer <msofer@users.sf.net>
* generic/tclInt.h: Insure that PURIFY builds cannot exploit the
* generic/tclExecute.c: Tcl stack to hide mem defects.
2013-01-03 Donal K. Fellows <dkf@users.sf.net>
* doc/fconfigure.n, doc/CrtChannel.3: Updated to reflect the fact that
the minimum buffer size is one byte, not ten. Identified by Schelte
Bron on the Tcler's Chat.
* generic/tclExecute.c (TEBCresume:INST_INVOKE_REPLACE):
* generic/tclEnsemble.c (TclCompileEnsemble): Added new mechanism to
allow for more efficient dispatch of non-bytecode-compiled subcommands
of bytecode-compiled ensembles. This can provide substantial speed
benefits in some cases.
2013-01-02 Miguel Sofer <msofer@users.sf.net>
* generic/tclEnsemble.c: Remove stray calls to Tcl_Alloc and friends:
* generic/tclExecute.c: the core should only use ckalloc to allow
* generic/tclIORTrans.c: MEM_DEBUG to work properly.
* generic/tclTomMathInterface.c:
2012-12-31 Donal K. Fellows <dkf@users.sf.net>
* doc/string.n: Noted the obsolescence of the 'bytelength',
'wordstart' and 'wordend' subcommands, and moved them to later in the
file.
2012-12-27 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclListObj.c: [Bug 3598580]: Tcl_ListObjReplace may release
deleted elements too early.
2012-12-22 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
* 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>
* unix/dltest/pkgb.c: Inline compat Tcl_GetDefaultEncodingDir.
* generic/tclStubLib.c: Eliminate unnecessary static HasStubSupport()
and isDigit() functions, just do the same inline.
2012-12-18 Donal K. Fellows <dkf@users.sf.net>
* generic/tclCompCmdsSZ.c (TclSubstCompile): Improved the sequence of
instructions issued for [subst] when dealing with simple variable
references.
2012-12-14 Don Porter <dgp@users.sourceforge.net>
*** 8.6.0 TAGGED FOR RELEASE ***
* changes: updates for 8.6.0
2012-12-13 Don Porter <dgp@users.sourceforge.net>
* generic/tclZlib.c: Repair same issue with misusing the
* tests/zlib.test: 'fire and forget' nature of Tcl_ObjSetVar2
in the new TIP 400 implementation.
2012-12-13 Miguel Sofer <msofer@users.sf.net>
* generic/tclCmdAH.c: (CatchObjCmdCallback): do not decrRefCount
* tests/cmdAH.test: the newValuePtr sent to Tcl_ObjSetVar2:
TOSV2 is 'fire and forget', it decrs on its own.
Fix for [Bug 3595576], found by andrewsh.
2012-12-13 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tcl.h: Fix Tcl_DecrRefCount macro such that it doesn't
access its objPtr parameter twice any more.
2012-12-11 Don Porter <dgp@users.sourceforge.net>
* generic/tcl.h: Bump version number to 8.6.0.
* library/init.tcl:
* unix/configure.in:
* win/configure.in:
* unix/tcl.spec:
* README:
* unix/configure: autoconf-2.59
* win/configure:
2012-12-10 Donal K. Fellows <dkf@users.sf.net>
* tools/tcltk-man2html.tcl (plus-pkgs): Increased robustness of
version number detection code to deal with packages whose names are
prefixes of other packages.
* unix/Makefile.in (dist): Added pkgs/package.list.txt to distribution
builds to ensure that 'make html' will work better.
2012-12-09 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
* tests/chan.test: Clean up unwanted eofchar side-effect of chan-4.6
leading to a spurious "'" at end of chan.test under certain conditions
(see [Bug 3389289] and [Bug 3389251]).
* doc/expr.n: [Bug 3594188]: Clarifications about commas.
2012-12-08 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
* generic/tclIO.c: Fix busyloop at exit under TCL_FINALIZE_ON_EXIT
when there are unflushed nonblocking channels. Thanks Miguel for
spotting.
2012-12-07 Jan Nijtmans <nijtmans@users.sf.net>
* unix/dltest/pkgb.c: Turn pkgb.so into a Tcl9 interoperability test
library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should
either result in an error-message, either succeed, but never crash.
2012-11-28 Donal K. Fellows <dkf@users.sf.net>
* generic/tclZlib.c (ZlibStreamSubcmd): [Bug 3590483]: Use a mechanism
for complex option resolution that has fewer problems with more
finicky compilers.
2012-11-26 Reinhard Max <max@suse.de>
* unix/tclUnixSock.c: Factor out creation of the -sockname and
-peername lists from TcpGetOptionProc() to TcpHostPortList(). Make it
robust against implementations of getnameinfo() that error out if
reverse mapping fails instead of falling back to the numeric
representation.
2012-11-20 Donal K. Fellows <dkf@users.sf.net>
* generic/tclBinary.c (BinaryDecode64): [Bug 3033307]: Corrected
handling of trailing whitespace when decoding base64. Thanks to Anton
Kovalenko for reporting, and Andy Goth for the fix and tests.
2012-11-19 Donal K. Fellows <dkf@users.sf.net>
* generic/tclExecute.c (INST_STR_RANGE_IMM): [Bug 3588366]: Corrected
@@ -3940,6 +4414,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]
+1 -1
View File
@@ -1,5 +1,5 @@
README: Tcl
This is the Tcl 8.6b3 source distribution.
This is the Tcl 8.6.0 source distribution.
http://tcl.sourceforge.net/
You can get any source release of Tcl from the file distributions
link at the above URL.
+39 -1
View File
@@ -8117,11 +8117,49 @@ Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---
2012-09-20 (enhancement) full Unicode support (nijtmans)
=> dde 1.4.0
2012-09-20 (enhancement) update bundled zlib to 1.2.7 (nijtmans)
2012-10-03 (bug fix) exit panic on stacked std channel (griffin,porter)
2012-10-14 (bug fix) [tcl::Bgerror] crash on non-dict options (nijtmans)
2012-10-16 (TIP 400) New [zlib] options to set compression dict (fellows)
2012-10-16 (TIP 405) New commands [lmap] and [dict map] (fellows)
2012-10-24 (enhancement) [dict unset] now bytecompiled (fellows)
2012-11-05 (TIP 413) Revisions to default [string trim*] trimset (nijtmans)
*** POTENTIAL INCOMPATIBILITY ***
2012-11-05 (enhancement) Now bytecompiled: [array exists], [array set],
[array unset], [dict create], [dict exists], [dict merge], [format],
[info commands], [info coroutine], [info level], [info object],
[namespace current], [namespace code], [namespace qualifiers], [namespace tail],
[namespace which], [regsub], [self], [string first], [string last],
[string map], [string range], [tailcall], [yield]. (fellows)
2012-11-06 (bug fix)[3581754] avoid multiple callback on keep-alive (fellows)
=> http 2.8.5
--- Released 8.6.0, ??? ??, 2012 --- See ChangeLog for details ---
2012-11-07 tzdata updated to Olson's tzdata2012i (kenny)
2012-11-13 (bug fix)[3567063] thread fp settings from master (mistachkin)
2012-11-14 (bug fix)[2933003] tempfile creation in $TMPDIR (fellows)
2012-11-15 (TIP 416) New [load] options -global and -lazy (nijtmans)
2012-11-20 (bug fix)[3033307] base64 trail whitespace (kovalenko,goth)
2012-12-03 (bug fix) [configure] query broke init from argv (porter)
=> tcltest 2.3.5
2012-12-13 (bug fix)[3595576] crash: [catch {} -> noSuchNs::var] (sofer,porter)
2012-12-13 (bug fix) crash: [zlib gunzip $data -header noSuchNs::var] (porter)
--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---
-2
View File
@@ -14,8 +14,6 @@
#ifndef _DIRENT
#define _DIRENT
#include "tcl.h"
/*
* Dirent structure, which holds information about a single
* directory entry.
-2
View File
@@ -26,8 +26,6 @@
#ifndef __dlfcn_h__
#define __dlfcn_h__
#include "tcl.h"
#ifdef __cplusplus
extern "C" {
#endif
+3 -3
View File
@@ -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
-2
View File
@@ -13,8 +13,6 @@
#ifndef _STRING
#define _STRING
#include "tcl.h"
/*
* The following #include is needed to define size_t. (This used to include
* sys/stdtypes.h but that doesn't exist on older versions of SunOS, e.g.
-1
View File
@@ -14,7 +14,6 @@
#ifndef _UNISTD
#define _UNISTD
#include "tcl.h"
#include <sys/types.h>
#ifndef NULL
+2 -2
View File
@@ -250,8 +250,8 @@ the default value of 4096 is returned.
.PP
\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
will be allocated in subsequent operations on the channel to store input or
output. The \fIsize\fR argument should be between ten and one million,
allowing buffers of ten bytes to one million bytes. If \fIsize\fR is
output. The \fIsize\fR argument should be between one and one million,
allowing buffers of one byte to one million bytes. If \fIsize\fR is
outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
4096.
.PP
+3 -3
View File
@@ -63,9 +63,9 @@ Define the \fBUSE_TCL_STUBS\fR symbol. Typically, you would include the
\fB\-DUSE_TCL_STUBS\fR flag when compiling the extension.
.IP 3) 5
Link the extension with the Tcl stubs library instead of the standard
Tcl library. For example, to use the Tcl 8.1 ABI on Unix platforms,
the library name is \fIlibtclstub8.1.a\fR; on Windows platforms, the
library name is \fItclstub81.lib\fR.
Tcl library. For example, to use the Tcl 8.6 ABI on Unix platforms,
the library name is \fIlibtclstub8.6.a\fR; on Windows platforms, the
library name is \fItclstub86.lib\fR.
.PP
If the extension also requires the Tk API, it must also call
\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
+1 -1
View File
@@ -31,7 +31,7 @@ Array of names of symbols to be resolved during the load of the library, or
NULL if no symbols are to be resolved. If an array is given, the last entry in
the array must be NULL.
.AP int flags in
The value should normally be 0, but \fITCL_LOAD_GLOBALfR or \fITCL_LOAD_LAZYfR
The value should normally be 0, but \fITCL_LOAD_GLOBAL\fR or \fITCL_LOAD_LAZY\fR
or a combination of those two is allowed as well.
.AP void *procPtrs out
Points to an array that will hold the addresses of the functions described in
+2 -2
View File
@@ -144,7 +144,7 @@ resolution is already known. The \fIcmd\fR parameter gives a
\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
the trampoline; this command must match the word in \fIobjv[0]\fR.
The remaining arguments are as for \fBTcl_NREvalObj\fR.
The remaining arguments are as for \fBTcl_NREvalObjv\fR.
.PP
\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
all accept a \fIflags\fR parameter, which is an OR-ed-together set of
@@ -295,7 +295,7 @@ int
int result)
{
/* \fIdata[0] .. data[3]\fR are the four words of data
* passed to \fBTcl_NREvalObj\fR */
* passed to \fBTcl_NRAddCallback\fR */
\fI... postprocessing ...\fR
+14 -2
View File
@@ -39,9 +39,9 @@ additional operators not found in C.
.SS OPERANDS
.PP
A Tcl expression consists of a combination of operands, operators,
and parentheses.
parentheses and commas.
White space may be used between the operands and operators and
parentheses; it is ignored by the expression's instructions.
parentheses (or commas); it is ignored by the expression's instructions.
Where possible, operands are interpreted as integer values.
Integer values may be specified in decimal (the normal case), in binary
(if the first two characters of the operand are \fB0b\fR), in octal
@@ -283,6 +283,18 @@ rules for resolving functions in namespaces. Either
current]::tcl::mathfunc::sin\fR will satisfy the request, and others
may as well (depending on the current \fBnamespace path\fR setting).
.PP
Some mathematical functions have several arguments, separated by commas like in C. Thus:
.PP
.CS
\fBexpr\fR {hypot($x,$y)}
.CE
.PP
ends up as
.PP
.CS
tcl::mathfunc::hypot $x $y
.CE
.PP
See the \fBmathfunc\fR(n) manual page for the math functions that are
available by default.
.SS "TYPES, OVERFLOW, AND PRECISION"
+2 -2
View File
@@ -72,8 +72,8 @@ initially set to \fBline\fR, and \fBstderr\fR is set to \fBnone\fR.
.
\fINewvalue\fR must be an integer; its value is used to set the size of
buffers, in bytes, subsequently allocated for this channel to store input
or output. \fINewvalue\fR must be between ten and one million, allowing
buffers of ten to one million bytes in size.
or output. \fINewvalue\fR must be between one and one million, allowing
buffers of one to one million bytes in size.
.TP
\fB\-encoding\fR \fIname\fR
.
+10 -7
View File
@@ -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.
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+27 -22
View File
@@ -19,27 +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 bytelength \fIstring\fR
.
Returns a decimal string giving the number of bytes used to represent
\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
represent Unicode characters, the byte length will not be the same as
the character length in general. The cases where a script cares about
the byte length are rare.
.RS
.PP
In almost all cases, you should use the
\fBstring length\fR operation (including determining the length of a
Tcl byte array value). Refer to the \fBTcl_NumUtfChars\fR manual
entry for more details on the UTF\-8 representation.
.PP
\fICompatibility note:\fR it is likely that this subcommand will be
withdrawn in a future version of Tcl. It is better to use the
\fBencoding convertto\fR command to convert a string to a known
encoding and then apply \fBstring length\fR to that.
.RE
.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
@@ -49,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
@@ -354,6 +334,31 @@ Returns a value equal to \fIstring\fR except that any trailing
characters present in the string given by \fIchars\fR are removed. If
\fIchars\fR is not specified then white space is removed (any character
for which \fBstring is space\fR returns 1, and "\0").
.SS "OBSOLETE SUBCOMMANDS"
.PP
These subcommands are currently supported, but are likely to go away in a
future release as their functionality is either virtually never used or highly
misleading.
.TP
\fBstring bytelength \fIstring\fR
.
Returns a decimal string giving the number of bytes used to represent
\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
represent Unicode characters, the byte length will not be the same as
the character length in general. The cases where a script cares about
the byte length are rare.
.RS
.PP
In almost all cases, you should use the
\fBstring length\fR operation (including determining the length of a
Tcl byte array value). Refer to the \fBTcl_NumUtfChars\fR manual
entry for more details on the UTF\-8 representation.
.PP
\fICompatibility note:\fR it is likely that this subcommand will be
withdrawn in a future version of Tcl. It is better to use the
\fBencoding convertto\fR command to convert a string to a known
encoding and then apply \fBstring length\fR to that.
.RE
.TP
\fBstring wordend \fIstring charIndex\fR
.
+1 -1
View File
@@ -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} {} {
+7
View File
@@ -254,7 +254,14 @@ newcolor(
* Oops, must allocate more.
*/
if (cm->max == MAX_COLOR) {
CERR(REG_ECOLORS);
return COLORLESS; /* too many colors */
}
n = cm->ncds * 2;
if (n < MAX_COLOR + 1) {
n = MAX_COLOR + 1;
}
if (cm->cd == cm->cdspace) {
newCd = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
if (newCd != NULL) {
+259 -84
View File
@@ -496,6 +496,62 @@ freearc(
from->free = victim;
}
/*
- 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.
@@ -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;
}
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);
}
}
if (progress && f != NULL) {
dumpnfa(nfa, f);
}
/*
* 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);
}
} while (progress && !NISERR());
}
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? */
struct arc *a;
assert(a->type == EMPTY);
assert(from != nfa->pre && to != nfa->post);
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;
if (from == to) { /* vacuous loop */
freearc(nfa, a);
return 1;
assert(from != to);
/*
* 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);
if (fromouts > toins) {
copyouts(nfa, to, from, 0);
return;
}
if (fromouts < toins) {
copyins(nfa, from, to, 0);
return;
}
/*
* Decide which end to work on.
* 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.
*/
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 (from->nins > to->nouts) {
copyouts(nfa, to, from, 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);
}
}
return 1;
copyins(nfa, from, to, 0);
}
/*
+10 -4
View File
@@ -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);
+1
View File
@@ -17,3 +17,4 @@
{ REG_MIXED, "REG_MIXED", "character widths of regex and string differ" },
{ REG_BADOPT, "REG_BADOPT", "invalid embedded option" },
{ REG_ETOOBIG, "REG_ETOOBIG", "nfa has too many states" },
{ REG_ECOLORS, "REG_ECOLORS", "too many colors" },
+1
View File
@@ -281,6 +281,7 @@ typedef struct {
#define REG_MIXED 17 /* character widths of regex and string differ */
#define REG_BADOPT 18 /* invalid embedded option */
#define REG_ETOOBIG 19 /* nfa has too many states */
#define REG_ECOLORS 20 /* too many colors */
/* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */
+2 -1
View File
@@ -145,6 +145,7 @@
typedef short color; /* colors of characters */
typedef int pcolor; /* what color promotes to */
#define MAX_COLOR SHRT_MAX /* max color value */
#define COLORLESS (-1) /* impossible color */
#define WHITE 0 /* default color, parent of all others */
@@ -366,7 +367,7 @@ struct subre {
*/
struct fns {
VOID FUNCPTR(free, (regex_t *));
void FUNCPTR(free, (regex_t *));
};
/*
+21 -26
View File
@@ -55,11 +55,11 @@ extern "C" {
#define TCL_MAJOR_VERSION 8
#define TCL_MINOR_VERSION 6
#define TCL_RELEASE_LEVEL TCL_BETA_RELEASE
#define TCL_RELEASE_SERIAL 3
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
#define TCL_RELEASE_SERIAL 0
#define TCL_VERSION "8.6"
#define TCL_PATCH_LEVEL "8.6b3"
#define TCL_PATCH_LEVEL "8.6.0"
/*
*----------------------------------------------------------------------------
@@ -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
@@ -854,10 +854,7 @@ typedef struct Tcl_Obj {
* whether an object is shared (i.e. has reference count > 1). Note: clients
* should use Tcl_DecrRefCount() when they are finished using an object, and
* should never call TclFreeObj() directly. TclFreeObj() is only defined and
* made public in tcl.h to support Tcl_DecrRefCount's macro definition. Note
* also that Tcl_DecrRefCount() refers to the parameter "obj" twice. This
* means that you should avoid calling it with an expression that is expensive
* to compute or has side effects.
* made public in tcl.h to support Tcl_DecrRefCount's macro definition.
*/
void Tcl_IncrRefCount(Tcl_Obj *objPtr);
@@ -2452,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 */
@@ -2471,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
@@ -2504,7 +2501,12 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
* http://c2.com/cgi/wiki?TrivialDoWhileLoop
*/
# define Tcl_DecrRefCount(objPtr) \
do { if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr); } while(0)
do { \
Tcl_Obj *_objPtr = (objPtr); \
if (--(_objPtr)->refCount <= 0) { \
TclFreeObj(_objPtr); \
} \
} while(0)
# define Tcl_IsShared(objPtr) \
((objPtr)->refCount > 1)
#endif
@@ -2600,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.
+7 -53
View File
@@ -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;
}
/*
+85 -83
View File
@@ -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(
+33 -28
View File
@@ -127,6 +127,30 @@ static const char B64Digits[65] = {
'='
};
/*
* How to construct the ensembles.
*/
static const EnsembleImplMap binaryMap[] = {
{ "format", BinaryFormatCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
{ "scan", BinaryScanCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0 },
{ "encode", NULL, NULL, NULL, NULL, 0 },
{ "decode", NULL, NULL, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
static const EnsembleImplMap encodeMap[] = {
{ "hex", BinaryEncodeHex, TclCompileBasic1ArgCmd, NULL, (ClientData)HexDigits, 0 },
{ "uuencode", BinaryEncode64, NULL, NULL, (ClientData)UueDigits, 0 },
{ "base64", BinaryEncode64, NULL, NULL, (ClientData)B64Digits, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
static const EnsembleImplMap decodeMap[] = {
{ "hex", BinaryDecodeHex, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{ "uuencode", BinaryDecodeUu, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{ "base64", BinaryDecode64, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
/*
* The following object type represents an array of bytes. An array of bytes
* is not equivalent to an internationalized string. Conceptually, a string is
@@ -180,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)
/*
*----------------------------------------------------------------------
@@ -301,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;
@@ -396,7 +421,7 @@ Tcl_SetByteArrayLength(
byteArrayPtr->allocated = length;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
Tcl_InvalidateStringRep(objPtr);
TclInvalidateStringRep(objPtr);
byteArrayPtr->used = length;
return byteArrayPtr->bytes;
}
@@ -667,7 +692,7 @@ TclAppendBytesToByteArray(
if (len > 0) {
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
byteArrayPtr->used += len;
Tcl_InvalidateStringRep(objPtr);
TclInvalidateStringRep(objPtr);
}
}
@@ -688,26 +713,6 @@ TclAppendBytesToByteArray(
*----------------------------------------------------------------------
*/
static const EnsembleImplMap binaryMap[] = {
{ "format", BinaryFormatCmd, NULL, NULL, NULL, 0 },
{ "scan", BinaryScanCmd, NULL, NULL, NULL, 0 },
{ "encode", NULL, NULL, NULL, NULL, 0 },
{ "decode", NULL, NULL, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
static const EnsembleImplMap encodeMap[] = {
{ "hex", BinaryEncodeHex, NULL, NULL, (ClientData)HexDigits, 0 },
{ "uuencode", BinaryEncode64, NULL, NULL, (ClientData)UueDigits, 0 },
{ "base64", BinaryEncode64, NULL, NULL, (ClientData)B64Digits, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
static const EnsembleImplMap decodeMap[] = {
{ "hex", BinaryDecodeHex, NULL, NULL, NULL, 0 },
{ "uuencode", BinaryDecodeUu, NULL, NULL, NULL, 0 },
{ "base64", BinaryDecode64, NULL, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
Tcl_Command
TclInitBinaryCmd(
Tcl_Interp *interp)
@@ -2357,7 +2362,7 @@ BinaryDecodeHex(
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
Tcl_WrongNumArgs(interp, 1, objv, "data");
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
@@ -2571,7 +2576,7 @@ BinaryDecodeUu(
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
Tcl_WrongNumArgs(interp, 1, objv, "data");
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
@@ -2667,7 +2672,7 @@ BinaryDecode64(
static const char *const optStrings[] = { "-strict", NULL };
if (objc < 2 || objc > 3) {
Tcl_WrongNumArgs(interp, 1, objv, "data");
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
return TCL_ERROR;
}
for (i = 1; i < objc-1; ++i) {
+4
View File
@@ -156,6 +156,10 @@ TclInitDbCkalloc(void)
if (!ckallocInit) {
ckallocInit = 1;
ckallocMutexPtr = Tcl_GetAllocMutex();
#ifndef TCL_THREADS
/* Silence compiler warning */
(void)ckallocMutexPtr;
#endif
}
}
+36 -35
View File
@@ -361,7 +361,8 @@ CatchObjCmdCallback(
if (NULL == Tcl_ObjSetVar2(interp, optionVarNamePtr, NULL,
options, TCL_LEAVE_ERR_MSG)) {
Tcl_DecrRefCount(options);
/* Do not decrRefCount 'options', it was already done by
* Tcl_ObjSetVar2 */
return TCL_ERROR;
}
}
@@ -949,40 +950,40 @@ TclInitFileCmd(
*/
static const EnsembleImplMap initMap[] = {
{"atime", FileAttrAccessTimeCmd, NULL, NULL, NULL, 0},
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
{"channels", TclChannelNamesCmd, NULL, NULL, NULL, 0},
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
{"delete", TclFileDeleteCmd, NULL, NULL, NULL, 0},
{"dirname", PathDirNameCmd, NULL, NULL, NULL, 0},
{"executable", FileAttrIsExecutableCmd, NULL, NULL, NULL, 0},
{"exists", FileAttrIsExistingCmd, NULL, NULL, NULL, 0},
{"extension", PathExtensionCmd, NULL, NULL, NULL, 0},
{"isdirectory", FileAttrIsDirectoryCmd, NULL, NULL, NULL, 0},
{"isfile", FileAttrIsFileCmd, NULL, NULL, NULL, 0},
{"join", PathJoinCmd, NULL, NULL, NULL, 0},
{"link", TclFileLinkCmd, NULL, NULL, NULL, 0},
{"lstat", FileAttrLinkStatCmd, NULL, NULL, NULL, 0},
{"mtime", FileAttrModifyTimeCmd, NULL, NULL, NULL, 0},
{"mkdir", TclFileMakeDirsCmd, NULL, NULL, NULL, 0},
{"nativename", PathNativeNameCmd, NULL, NULL, NULL, 0},
{"normalize", PathNormalizeCmd, NULL, NULL, NULL, 0},
{"owned", FileAttrIsOwnedCmd, NULL, NULL, NULL, 0},
{"pathtype", PathTypeCmd, NULL, NULL, NULL, 0},
{"readable", FileAttrIsReadableCmd, NULL, NULL, NULL, 0},
{"readlink", TclFileReadLinkCmd, NULL, NULL, NULL, 0},
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
{"rootname", PathRootNameCmd, NULL, NULL, NULL, 0},
{"separator", FilesystemSeparatorCmd, NULL, NULL, NULL, 0},
{"size", FileAttrSizeCmd, NULL, NULL, NULL, 0},
{"split", PathSplitCmd, NULL, NULL, NULL, 0},
{"stat", FileAttrStatCmd, NULL, NULL, NULL, 0},
{"system", PathFilesystemCmd, NULL, NULL, NULL, 0},
{"tail", PathTailCmd, NULL, NULL, NULL, 0},
{"tempfile", TclFileTemporaryCmd, NULL, NULL, NULL, 0},
{"type", FileAttrTypeCmd, NULL, NULL, NULL, 0},
{"volumes", FilesystemVolumesCmd, NULL, NULL, NULL, 0},
{"writable", FileAttrIsWritableCmd, NULL, NULL, NULL, 0},
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
{"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
return TclMakeEnsemble(interp, "file", initMap);
+20 -20
View File
@@ -161,30 +161,30 @@ static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr,
*/
static const EnsembleImplMap defaultInfoMap[] = {
{"args", InfoArgsCmd, NULL, NULL, NULL, 0},
{"body", InfoBodyCmd, NULL, NULL, NULL, 0},
{"cmdcount", InfoCmdCountCmd, NULL, NULL, NULL, 0},
{"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0},
{"complete", InfoCompleteCmd, NULL, NULL, NULL, 0},
{"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0},
{"default", InfoDefaultCmd, NULL, NULL, NULL, 0},
{"errorstack", InfoErrorStackCmd, NULL, NULL, NULL, 0},
{"default", InfoDefaultCmd, TclCompileBasic3ArgCmd, NULL, NULL, 0},
{"errorstack", InfoErrorStackCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd, NULL, NULL, 0},
{"frame", InfoFrameCmd, NULL, NULL, NULL, 0},
{"functions", InfoFunctionsCmd, NULL, NULL, NULL, 0},
{"globals", TclInfoGlobalsCmd, NULL, NULL, NULL, 0},
{"hostname", InfoHostnameCmd, NULL, NULL, NULL, 0},
{"frame", InfoFrameCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"functions", InfoFunctionsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"globals", TclInfoGlobalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"hostname", InfoHostnameCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"level", InfoLevelCmd, TclCompileInfoLevelCmd, NULL, NULL, 0},
{"library", InfoLibraryCmd, NULL, NULL, NULL, 0},
{"loaded", InfoLoadedCmd, NULL, NULL, NULL, 0},
{"locals", TclInfoLocalsCmd, NULL, NULL, NULL, 0},
{"nameofexecutable", InfoNameOfExecutableCmd, NULL, NULL, NULL, 0},
{"patchlevel", InfoPatchLevelCmd, NULL, NULL, NULL, 0},
{"procs", InfoProcsCmd, NULL, NULL, NULL, 0},
{"script", InfoScriptCmd, NULL, NULL, NULL, 0},
{"sharedlibextension", InfoSharedlibCmd, NULL, NULL, NULL, 0},
{"tclversion", InfoTclVersionCmd, NULL, NULL, NULL, 0},
{"vars", TclInfoVarsCmd, NULL, NULL, NULL, 0},
{"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
+13 -12
View File
@@ -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 {
@@ -3324,7 +3325,7 @@ TclInitStringCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap stringImplMap[] = {
{"bytelength", StringBytesCmd, NULL, NULL, NULL, 0},
{"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0},
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
@@ -3335,17 +3336,17 @@ TclInitStringCmd(
{"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0},
{"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0},
{"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0},
{"repeat", StringReptCmd, NULL, NULL, NULL, 0},
{"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"replace", StringRplcCmd, NULL, NULL, NULL, 0},
{"reverse", StringRevCmd, NULL, NULL, NULL, 0},
{"tolower", StringLowerCmd, NULL, NULL, NULL, 0},
{"toupper", StringUpperCmd, NULL, NULL, NULL, 0},
{"totitle", StringTitleCmd, NULL, NULL, NULL, 0},
{"trim", StringTrimCmd, NULL, NULL, NULL, 0},
{"trimleft", StringTrimLCmd, NULL, NULL, NULL, 0},
{"trimright", StringTrimRCmd, NULL, NULL, NULL, 0},
{"wordend", StringEndCmd, NULL, NULL, NULL, 0},
{"wordstart", StringStartCmd, NULL, NULL, NULL, 0},
{"reverse", StringRevCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"tolower", StringLowerCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"toupper", StringUpperCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"totitle", StringTitleCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"trim", StringTrimCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"trimleft", StringTrimLCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"trimright", StringTrimRCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"wordend", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"wordstart", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
+83 -54
View File
@@ -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;
@@ -3082,7 +3108,7 @@ TclCompileFormatCmd(
* after our attempt to spot a literal).
*/
for (; --i>=0 ;) {
for (; i>=0 ; i--) {
Tcl_DecrRefCount(objv[i]);
}
ckfree(objv);
@@ -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
@@ -5791,7 +5819,7 @@ TclCompileVariableCmd(
*/
valueTokenPtr = parsePtr->tokenPtr;
for (i=2; i<=numWords; i+=2) {
for (i=1; i<numWords; i+=2) {
varTokenPtr = TokenAfter(valueTokenPtr);
valueTokenPtr = TokenAfter(varTokenPtr);
@@ -5801,15 +5829,15 @@ TclCompileVariableCmd(
return TCL_ERROR;
}
CompileWord(envPtr, varTokenPtr, interp, 1);
CompileWord(envPtr, varTokenPtr, interp, i);
TclEmitInstInt4( INST_VARIABLE, localIndex, envPtr);
if (i != numWords) {
if (i+1 < numWords) {
/*
* A value has been given: set the variable, pop the value
*/
CompileWord(envPtr, valueTokenPtr, interp, 1);
CompileWord(envPtr, valueTokenPtr, interp, i+1);
Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
TclEmitOpcode( INST_POP, envPtr);
}
@@ -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;
+44 -14
View File
@@ -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);
}
/*
@@ -836,6 +836,34 @@ TclSubstCompile(
TclEmitPush(literal, envPtr);
count++;
continue;
case TCL_TOKEN_VARIABLE:
/*
* Check for simple variable access; see if we can only generate
* TCL_OK or TCL_ERROR from the substituted variable read; if so,
* there is no need to generate elaborate exception-management
* code. Note that the first component of TCL_TOKEN_VARIABLE is
* always TCL_TOKEN_TEXT...
*/
if (tokenPtr->numComponents > 1) {
int i, foundCommand = 0;
for (i=2 ; i<=tokenPtr->numComponents ; i++) {
if (tokenPtr[i].type == TCL_TOKEN_COMMAND) {
foundCommand = 1;
break;
}
}
if (foundCommand) {
break;
}
}
envPtr->line = bline;
TclCompileVarSubst(interp, tokenPtr, envPtr);
bline = envPtr->line;
count++;
continue;
}
while (count > 255) {
@@ -1224,12 +1252,7 @@ TclCompileSwitchCmd(
if (TCL_OK != TclFindElement(NULL, bytes, numBytes,
&(bodyTokenArray[numWords].start), &bytes,
&(bodyTokenArray[numWords].size), &literal) || !literal) {
abort:
ckfree((char *) bodyToken);
ckfree((char *) bodyTokenArray);
ckfree((char *) bodyLines);
ckfree((char *) bodyContLines);
return TCL_ERROR;
goto abort;
}
bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
@@ -1254,7 +1277,12 @@ TclCompileSwitchCmd(
numWords++;
}
if (numWords % 2) {
goto abort;
abort:
ckfree((char *) bodyToken);
ckfree((char *) bodyTokenArray);
ckfree((char *) bodyLines);
ckfree((char *) bodyContLines);
return TCL_ERROR;
}
} else if (numWords % 2 || numWords == 0) {
/*
@@ -1925,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;
}
@@ -2709,7 +2739,7 @@ TclCompileUnsetCmd(
flags = 1;
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
leadingWord = Tcl_NewObj();
if (TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
if (numWords > 0 && TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
int len;
const char *bytes = Tcl_GetStringFromObj(leadingWord, &len);
+6 -9
View File
@@ -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)) {
/*
+107 -87
View File
@@ -529,6 +529,11 @@ InstructionDesc const tclInstructionTable[] = {
/* Forces the variable indexed by opnd to be an array. Does not touch
* the stack. */
{"invokeReplace", 6, INT_MIN, 2, {OPERAND_UINT4,OPERAND_UINT1}},
/* Invoke command named objv[0], replacing the first two words with
* the word at the top of the stack;
* <objc,objv> = <op4,top op4 after popping 1> */
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
@@ -552,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,
@@ -568,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
@@ -645,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;
@@ -717,35 +721,14 @@ TclSetByteCodeFromAny(
TclVerifyLocalLiteralTable(&compEnv);
#endif /*TCL_COMPILE_DEBUG*/
TclInitByteCodeObj(objPtr, &compEnv);
if (result == TCL_OK) {
TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
if (tclTraceCompile >= 2) {
TclPrintByteCodeObj(interp, objPtr);
fflush(stdout);
}
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++;
}
#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++;
}
}
TclFreeCompileEnv(&compEnv);
@@ -784,8 +767,7 @@ SetByteCodeFromAny(
if (interp == NULL) {
return TCL_ERROR;
}
TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
return TCL_OK;
return TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
}
/*
@@ -839,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);
@@ -862,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.
*
*----------------------------------------------------------------------
*/
@@ -939,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++) {
@@ -952,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++);
}
}
@@ -987,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);
}
}
@@ -1139,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) {
@@ -1178,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);
}
/*
*----------------------------------------------------------------------
@@ -1417,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);
}
@@ -1433,7 +1437,8 @@ TclFreeCompileEnv(
ckfree(envPtr->auxDataArrayPtr);
}
if (envPtr->extCmdMapPtr) {
ckfree(envPtr->extCmdMapPtr);
ReleaseCmdWordData(envPtr->extCmdMapPtr);
envPtr->extCmdMapPtr = NULL;
}
/*
@@ -1575,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) {
@@ -1887,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 {
/*
@@ -1905,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]);
}
@@ -2214,9 +2222,8 @@ TclCompileTokens(
Tcl_DStringFree(&textBuffer);
if (numCL) {
TclContinuationsEnter(
envPtr->literalArrayPtr[literal].objPtr, numCL,
clPosition);
TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
numCL, clPosition);
}
numCL = 0;
}
@@ -2262,7 +2269,7 @@ TclCompileTokens(
TclEmitPush(literal, envPtr);
numObjsToConcat++;
if (numCL) {
TclContinuationsEnter(envPtr->literalArrayPtr[literal].objPtr,
TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
numCL, clPosition);
}
numCL = 0;
@@ -2509,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;
@@ -2566,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.
@@ -2583,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;
}
}
@@ -2634,7 +2647,7 @@ TclInitByteCodeObj(
*/
TclFreeIntRep(objPtr);
objPtr->internalRep.otherValuePtr = codePtr;
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
objPtr->typePtr = &tclByteCodeType;
/*
@@ -2646,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;
}
@@ -3558,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.
@@ -3574,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). */
@@ -3679,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);
}
/*
@@ -4053,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;
@@ -4558,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);
}
+4 -5
View File
@@ -711,8 +711,10 @@ typedef struct ByteCode {
#define INST_ARRAY_MAKE_STK 161
#define INST_ARRAY_MAKE_IMM 162
#define INST_INVOKE_REPLACE 163
/* The last opcode */
#define LAST_INST_OPCODE 162
#define LAST_INST_OPCODE 163
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
@@ -952,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);
@@ -965,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);
@@ -985,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);
+96
View File
@@ -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,97 @@ extern const TclStubs *tclStubsPtr;
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
#undef Tcl_SeekOld
#undef Tcl_TellOld
#undef Tcl_PkgPresent
#define Tcl_PkgPresent(interp, name, version, exact) \
Tcl_PkgPresentEx(interp, name, version, exact, NULL)
#undef Tcl_PkgProvide
#define Tcl_PkgProvide(interp, name, version) \
Tcl_PkgProvideEx(interp, name, version, NULL)
#undef Tcl_PkgRequire
#define Tcl_PkgRequire(interp, name, version, exact) \
Tcl_PkgRequireEx(interp, name, version, exact, NULL)
#undef Tcl_GetIndexFromObj
#define Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) \
Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, \
sizeof(char *), msg, flags, indexPtr)
#undef Tcl_NewIntObj
#define Tcl_NewIntObj Tcl_NewLongObj
#undef Tcl_SetIntObj
#define Tcl_SetIntObj Tcl_SetLongObj
#undef Tcl_NewBooleanObj
#define Tcl_NewBooleanObj(boolValue) \
Tcl_NewLongObj((boolValue)!=0)
#undef Tcl_DbNewBooleanObj
#define Tcl_DbNewBooleanObj(boolValue, file, line) \
Tcl_DbNewLongObj((boolValue)!=0, file, line)
#undef Tcl_SetBooleanObj
#define Tcl_SetBooleanObj(objPtr, boolValue) \
Tcl_SetLongObj(objPtr, (boolValue)!=0)
#undef Tcl_SetVar
#define Tcl_SetVar(interp, varName, newValue, flags) \
Tcl_SetVar2(interp, varName, NULL, newValue, flags)
#undef Tcl_UnsetVar
#define Tcl_UnsetVar(interp, varName, flags) \
Tcl_UnsetVar2(interp, varName, NULL, flags)
#undef Tcl_GetVar
#define Tcl_GetVar(interp, varName, flags) \
Tcl_GetVar2(interp, varName, NULL, flags)
#undef Tcl_TraceVar
#define Tcl_TraceVar(interp, varName, flags, proc, clientData) \
Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData)
#undef Tcl_UntraceVar
#define Tcl_UntraceVar(interp, varName, flags, proc, clientData) \
Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData)
#undef Tcl_VarTraceInfo
#define Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) \
Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc, prevClientData)
#undef Tcl_UpVar
#define Tcl_UpVar(interp, frameName, varName, localName, flags) \
Tcl_UpVar2(interp, frameName, varName, NULL, localName, flags)
#ifndef TCL_NO_DEPRECATED
#undef Tcl_Eval
#define Tcl_Eval(interp,objPtr) \
Tcl_EvalEx(interp,objPtr,-1,0)
#undef Tcl_GlobalEval
#define Tcl_GlobalEval(interp,objPtr) \
Tcl_EvalEx(interp,objPtr,-1,TCL_EVAL_GLOBAL)
#undef Tcl_AddErrorInfo
#define Tcl_AddErrorInfo(interp, message) \
Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, -1))
#undef Tcl_AddObjErrorInfo
#define Tcl_AddObjErrorInfo(interp, message, length) \
Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, length))
#undef Tcl_SaveResult
#define Tcl_SaveResult(interp, statePtr) \
do { \
(statePtr)->objResultPtr = Tcl_GetObjResult(interp); \
Tcl_IncrRefCount((statePtr)->objResultPtr); \
Tcl_SetObjResult((interp), Tcl_NewObj()); \
} while(0)
#undef Tcl_RestoreResult
#define Tcl_RestoreResult(interp, statePtr) \
do { \
Tcl_ResetResult(interp); \
Tcl_SetObjResult((interp), (statePtr)->objResultPtr); \
Tcl_DecrRefCount((statePtr)->objResultPtr); \
} while(0)
#undef Tcl_DiscardResult
#define Tcl_DiscardResult(statePtr) \
Tcl_DecrRefCount((statePtr)->objResultPtr)
#endif /* TCL_NO_DEPRECATED */
/*
* 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 */
+33 -35
View File
@@ -91,22 +91,22 @@ static const EnsembleImplMap implementationMap[] = {
{"append", DictAppendCmd, TclCompileDictAppendCmd, NULL, NULL, 0 },
{"create", DictCreateCmd, TclCompileDictCreateCmd, NULL, NULL, 0 },
{"exists", DictExistsCmd, TclCompileDictExistsCmd, NULL, NULL, 0 },
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
{"for", NULL, TclCompileDictForCmd, DictForNRCmd, NULL, 0 },
{"get", DictGetCmd, TclCompileDictGetCmd, NULL, NULL, 0 },
{"incr", DictIncrCmd, TclCompileDictIncrCmd, NULL, NULL, 0 },
{"info", DictInfoCmd, NULL, NULL, NULL, 0 },
{"keys", DictKeysCmd, NULL, NULL, NULL, 0 },
{"info", DictInfoCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
{"keys", DictKeysCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{"lappend", DictLappendCmd, TclCompileDictLappendCmd, NULL, NULL, 0 },
{"map", NULL, TclCompileDictMapCmd, DictMapNRCmd, NULL, 0 },
{"merge", DictMergeCmd, TclCompileDictMergeCmd, NULL, NULL, 0 },
{"remove", DictRemoveCmd, NULL, NULL, NULL, 0 },
{"remove", DictRemoveCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
{"replace", DictReplaceCmd, NULL, NULL, NULL, 0 },
{"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 },
{"size", DictSizeCmd, NULL, NULL, NULL, 0 },
{"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
{"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 },
{"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 },
{"values", DictValuesCmd, NULL, NULL, NULL, 0 },
{"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
{"with", DictWithCmd, TclCompileDictWithCmd, NULL, NULL, 0 },
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -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,
+4 -4
View File
@@ -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);
}
/*
+602 -68
View File
@@ -4,7 +4,7 @@
* Contains support for ensembles (see TIP#112), which provide simple
* mechanism for creating composite commands on top of namespaces.
*
* Copyright (c) 2005-2010 Donal K. Fellows.
* Copyright (c) 2005-2013 Donal K. Fellows.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -35,6 +35,15 @@ static void MakeCachedEnsembleCommand(Tcl_Obj *objPtr,
static void FreeEnsembleCmdRep(Tcl_Obj *objPtr);
static void DupEnsembleCmdRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static void StringOfEnsembleCmdRep(Tcl_Obj *objPtr);
static int CompileToCompiledCommand(Tcl_Interp *interp,
Tcl_Parse *parsePtr, int depth, Command *cmdPtr,
CompileEnv *envPtr);
static void CompileToInvokedCommand(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Tcl_Obj *replacements,
Command *cmdPtr, CompileEnv *envPtr);
static int CompileBasicNArgCommand(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
CompileEnv *envPtr);
/*
* The lists of subcommands and options for the [namespace ensemble] command.
@@ -78,6 +87,17 @@ const Tcl_ObjType tclEnsembleCmdType = {
StringOfEnsembleCmdRep, /* updateStringProc */
NULL /* setFromAnyProc */
};
/*
* Copied from tclCompCmds.c
*/
#define DefineLineInformation \
ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
int eclIndex = mapPtr->nuloc - 1
#define SetLineInformation(word) \
envPtr->line = mapPtr->loc[eclIndex].line[(word)]; \
envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
static inline Tcl_Obj *
NewNsObj(
@@ -1565,21 +1585,23 @@ TclMakeEnsemble(
NULL);
}
cmdPtr->compileProc = map[i].compileProc;
if (map[i].compileProc != NULL) {
ensembleFlags |= ENSEMBLE_COMPILE;
}
}
}
Tcl_SetEnsembleMappingDict(interp, ensemble, mapDict);
if (ensembleFlags & ENSEMBLE_COMPILE) {
Tcl_SetEnsembleFlags(interp, ensemble, ensembleFlags);
}
/*
* Switch on compilation always for core ensembles now that we can do
* nice bytecode things with them.
*/
Tcl_SetEnsembleFlags(interp, ensemble,
ensembleFlags | ENSEMBLE_COMPILE);
}
Tcl_DStringFree(&buf);
Tcl_DStringFree(&hiddenBuf);
if (nameParts != NULL) {
Tcl_Free((char *) nameParts);
ckfree((char *) nameParts);
}
return ensemble;
}
@@ -1696,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 &&
@@ -1892,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);
}
@@ -2100,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)) {
@@ -2174,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 {
@@ -2216,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);
@@ -2228,7 +2250,7 @@ MakeCachedEnsembleCommand(
TclFreeIntRep(objPtr);
ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
objPtr->internalRep.otherValuePtr = ensembleCmd;
objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
objPtr->typePtr = &tclEnsembleCmdType;
}
@@ -2623,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);
@@ -2655,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;
@@ -2693,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;
@@ -2731,25 +2753,33 @@ TclCompileEnsemble(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *tokenPtr;
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems;
Tcl_Obj *replaced = Tcl_NewObj(), *replacement;
Tcl_Command ensemble = (Tcl_Command) cmdPtr;
Tcl_Parse synthetic;
int len, result, flags = 0, i;
Command *oldCmdPtr = cmdPtr, *newCmdPtr;
int len, result, flags = 0, i, depth = 1, invokeAnyway = 0;
int ourResult = TCL_ERROR;
unsigned numBytes;
const char *word;
if (parsePtr->numWords < 2) {
return TCL_ERROR;
}
Tcl_IncrRefCount(replaced);
tokenPtr = TokenAfter(parsePtr->tokenPtr);
/*
* This is where we return to if we are parsing multiple nested compiled
* ensembles. [info object] is such a beast.
*/
checkNextWord:
if (parsePtr->numWords < depth + 1) {
goto failed;
}
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
/*
* Too hard.
*/
return TCL_ERROR;
goto failed;
}
word = tokenPtr[1].start;
@@ -2768,7 +2798,7 @@ TclCompileEnsemble(
* to proceed.
*/
return TCL_ERROR;
goto failed;
}
/*
@@ -2782,7 +2812,7 @@ TclCompileEnsemble(
* Figuring out how to compile this has become too much. Bail out.
*/
return TCL_ERROR;
goto failed;
}
/*
@@ -2805,7 +2835,7 @@ TclCompileEnsemble(
Tcl_Obj *matchObj = NULL;
if (Tcl_ListObjGetElements(NULL, listObj, &len, &elems) != TCL_OK) {
return TCL_ERROR;
goto failed;
}
for (i=0 ; i<len ; i++) {
str = Tcl_GetStringFromObj(elems[i], &sclen);
@@ -2816,8 +2846,9 @@ TclCompileEnsemble(
result = Tcl_DictObjGet(NULL, mapObj,elems[i], &targetCmdObj);
if (result != TCL_OK || targetCmdObj == NULL) {
return TCL_ERROR;
goto failed;
}
replacement = elems[i];
goto doneMapLookup;
}
@@ -2833,18 +2864,19 @@ TclCompileEnsemble(
if ((flags & TCL_ENSEMBLE_PREFIX)
&& strncmp(word, str, numBytes) == 0) {
if (matchObj != NULL) {
return TCL_ERROR;
goto failed;
}
matchObj = elems[i];
}
}
if (matchObj == NULL) {
return TCL_ERROR;
goto failed;
}
result = Tcl_DictObjGet(NULL, mapObj, matchObj, &targetCmdObj);
if (result != TCL_OK || targetCmdObj == NULL) {
return TCL_ERROR;
goto failed;
}
replacement = matchObj;
} else {
Tcl_DictSearch s;
int done, matched;
@@ -2856,14 +2888,15 @@ TclCompileEnsemble(
TclNewStringObj(subcmdObj, word, (int) numBytes);
result = Tcl_DictObjGet(NULL, mapObj, subcmdObj, &targetCmdObj);
TclDecrRefCount(subcmdObj);
if (result == TCL_OK && targetCmdObj != NULL) {
/*
* Got it. Skip the fiddling around with prefixes.
*/
replacement = subcmdObj;
goto doneMapLookup;
}
TclDecrRefCount(subcmdObj);
/*
* We've not literally got a valid subcommand. But maybe we have a
@@ -2871,7 +2904,7 @@ TclCompileEnsemble(
*/
if (!(flags & TCL_ENSEMBLE_PREFIX)) {
return TCL_ERROR;
goto failed;
}
/*
@@ -2881,6 +2914,7 @@ TclCompileEnsemble(
Tcl_DictObjFirst(NULL, mapObj, &s, &subcmdObj, &tmpObj, &done);
matched = 0;
replacement = NULL; /* Silence, fool compiler! */
while (!done) {
if (strncmp(TclGetString(subcmdObj), word, numBytes) == 0) {
if (matched++) {
@@ -2891,6 +2925,7 @@ TclCompileEnsemble(
break;
}
replacement = subcmdObj;
targetCmdObj = tmpObj;
}
Tcl_DictObjNext(&s, &subcmdObj, &tmpObj, &done);
@@ -2903,7 +2938,8 @@ TclCompileEnsemble(
*/
if (matched != 1) {
return TCL_ERROR;
invokeAnyway = 1;
goto failed;
}
}
@@ -2917,75 +2953,157 @@ TclCompileEnsemble(
*/
doneMapLookup:
Tcl_ListObjAppendElement(NULL, replaced, replacement);
if (Tcl_ListObjGetElements(NULL, targetCmdObj, &len, &elems) != TCL_OK) {
return TCL_ERROR;
}
if (len > 1 && Tcl_IsSafe(interp)) {
return TCL_ERROR;
goto failed;
} else if (len != 1) {
/*
* Note that at this point we know we can't issue any special
* instruction sequence as the mapping isn't one that we support at
* the compiled level.
*/
goto cleanup;
}
targetCmdObj = elems[0];
oldCmdPtr = cmdPtr;
Tcl_IncrRefCount(targetCmdObj);
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
newCmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
TclDecrRefCount(targetCmdObj);
if (cmdPtr == NULL || cmdPtr->compileProc == NULL
|| cmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION
|| cmdPtr->flags * CMD_HAS_EXEC_TRACES
if (newCmdPtr == NULL || Tcl_IsSafe(interp)
|| newCmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION
|| newCmdPtr->flags & CMD_HAS_EXEC_TRACES
|| ((Interp *)interp)->flags & DONT_COMPILE_CMDS_INLINE) {
/*
* Maps to an undefined command or a command without a compiler.
* Cannot compile.
*/
return TCL_ERROR;
goto cleanup;
}
cmdPtr = newCmdPtr;
depth++;
/*
* See whether we have a nested ensemble. If we do, we can go round the
* mulberry bush again, consuming the next word.
*/
if (cmdPtr->compileProc == TclCompileEnsemble) {
tokenPtr = TokenAfter(tokenPtr);
ensemble = (Tcl_Command) cmdPtr;
goto checkNextWord;
}
/*
* Now we've done the mapping process, can now actually try to compile.
* We do this by handing off to the subcommand's actual compiler. But to
* do that, we have to perform some trickery to rewrite the arguments.
* If there is a subcommand compiler and that successfully produces code,
* we'll use that. Otherwise, we fall back to generating opcodes to do the
* invoke at runtime.
*/
TclParseInit(interp, NULL, 0, &synthetic);
synthetic.numWords = parsePtr->numWords - 2 + len;
TclGrowParseTokenArray(&synthetic, 2*len);
synthetic.numTokens = 2*len;
invokeAnyway = 1;
if (CompileToCompiledCommand(interp, parsePtr, depth, cmdPtr,
envPtr) == TCL_OK) {
ourResult = TCL_OK;
goto cleanup;
}
/*
* Now we have the space to work in, install something rewritten. Note
* that we are here praying for all our might that none of these words are
* a script; the error detection code will crash if that happens and there
* is nothing we can do to avoid it!
* Failed to do a full compile for some reason. Try to do a direct invoke
* instead of going through the ensemble lookup process again.
*/
for (i=0 ; i<len ; i++) {
int sclen;
const char *str = Tcl_GetStringFromObj(elems[i], &sclen);
failed:
if (depth < 250) {
if (depth > 1) {
if (!invokeAnyway) {
cmdPtr = oldCmdPtr;
depth--;
}
(void) Tcl_ListObjReplace(NULL, replaced, depth, 2, 0, NULL);
}
CompileToInvokedCommand(interp, parsePtr, replaced, cmdPtr, envPtr);
ourResult = TCL_OK;
}
synthetic.tokenPtr[2*i].type = TCL_TOKEN_SIMPLE_WORD;
synthetic.tokenPtr[2*i].start = str;
synthetic.tokenPtr[2*i].size = sclen;
synthetic.tokenPtr[2*i].numComponents = 1;
/*
* Release the memory we allocated. If we've got here, we've either done
* something useful or we're in a case that we can't compile at all and
* we're just giving up.
*/
synthetic.tokenPtr[2*i+1].type = TCL_TOKEN_TEXT;
synthetic.tokenPtr[2*i+1].start = str;
synthetic.tokenPtr[2*i+1].size = sclen;
synthetic.tokenPtr[2*i+1].numComponents = 0;
cleanup:
Tcl_DecrRefCount(replaced);
return ourResult;
}
/*
* How to compile a subcommand using its own command compiler. To do that, we
* have to perform some trickery to rewrite the arguments, as compilers *must*
* have parse tokens that refer to addresses in the original script.
*/
static int
CompileToCompiledCommand(
Tcl_Interp *interp,
Tcl_Parse *parsePtr,
int depth,
Command *cmdPtr,
CompileEnv *envPtr) /* Holds resulting instructions. */
{
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;
}
TclParseInit(interp, NULL, 0, &synthetic);
synthetic.numWords = parsePtr->numWords - depth + 1;
TclGrowParseTokenArray(&synthetic, 2);
synthetic.numTokens = 2;
/*
* Now we have the space to work in, install something rewritten. The
* first word will "officially" be the bytes of the structured ensemble
* name. That's technically wrong, but nobody will care; we just need
* *something* here...
*/
synthetic.tokenPtr[0].type = TCL_TOKEN_SIMPLE_WORD;
synthetic.tokenPtr[0].start = parsePtr->tokenPtr[0].start;
synthetic.tokenPtr[0].numComponents = 1;
synthetic.tokenPtr[1].type = TCL_TOKEN_TEXT;
synthetic.tokenPtr[1].start = parsePtr->tokenPtr[0].start;
synthetic.tokenPtr[1].numComponents = 0;
for (i=0,tokenPtr=parsePtr->tokenPtr ; i<depth ; i++) {
int sclen = (tokenPtr->start - synthetic.tokenPtr[0].start)
+ tokenPtr->size;
synthetic.tokenPtr[0].size = sclen;
synthetic.tokenPtr[1].size = sclen;
tokenPtr = TokenAfter(tokenPtr);
}
/*
* Copy over the real argument tokens.
*/
for (i=len; i<synthetic.numWords; i++) {
for (i=1; i<synthetic.numWords; i++) {
int toCopy;
tokenPtr = TokenAfter(tokenPtr);
toCopy = tokenPtr->numComponents + 1;
TclGrowParseTokenArray(&synthetic, toCopy);
memcpy(synthetic.tokenPtr + synthetic.numTokens, tokenPtr,
sizeof(Tcl_Token) * toCopy);
synthetic.numTokens += toCopy;
tokenPtr = TokenAfter(tokenPtr);
}
/*
@@ -2994,6 +3112,17 @@ TclCompileEnsemble(
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.
*/
@@ -3001,6 +3130,411 @@ TclCompileEnsemble(
Tcl_FreeParse(&synthetic);
return result;
}
/*
* How to compile a subcommand to a _replacing_ invoke of its implementation
* command.
*/
static void
CompileToInvokedCommand(
Tcl_Interp *interp,
Tcl_Parse *parsePtr,
Tcl_Obj *replacements,
Command *cmdPtr,
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *tokPtr;
Tcl_Obj *objPtr, **words;
char *bytes;
int length, i, numWords, cmdLit;
DefineLineInformation;
/*
* Push the words of the command. Take care; the command words may be
* scripts that have backslashes in them, and [info frame 0] can see the
* difference. Hence the call to TclContinuationsEnterDerived...
*/
Tcl_ListObjGetElements(NULL, replacements, &numWords, &words);
for (i=0,tokPtr=parsePtr->tokenPtr ; i<parsePtr->numWords ; i++) {
if (i > 0 && i < numWords+1) {
bytes = Tcl_GetStringFromObj(words[i-1], &length);
PushLiteral(envPtr, bytes, length);
} else if (tokPtr->type == TCL_TOKEN_SIMPLE_WORD) {
int literal = TclRegisterNewLiteral(envPtr,
tokPtr[1].start, tokPtr[1].size);
if (envPtr->clNext) {
TclContinuationsEnterDerived(
TclFetchLiteral(envPtr, literal),
tokPtr[1].start - envPtr->source,
mapPtr->loc[eclIndex].next[i]);
}
TclEmitPush(literal, envPtr);
} else {
if (envPtr->clNext) {
SetLineInformation(i);
}
CompileTokens(envPtr, tokPtr, interp);
}
tokPtr = TokenAfter(tokPtr);
}
/*
* Push the name of the command we're actually dispatching to as part of
* the implementation.
*/
objPtr = Tcl_NewObj();
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);
/*
* Do the replacing dispatch.
*/
TclEmitInstInt4(INST_INVOKE_REPLACE, parsePtr->numWords, envPtr);
TclEmitInt1(numWords+1, envPtr);
TclAdjustStackDepth(-1, envPtr); /* Correction to stack depth calcs. */
}
/*
* Helpers that do issuing of instructions for commands that "don't have
* compilers" (well, they do; these). They all work by just generating base
* code to invoke the command; they're intended for ensemble subcommands so
* that the costs of INST_INVOKE_REPLACE can be avoided where we can work out
* that they're not needed.
*
* Note that these are NOT suitable for commands where there's an argument
* that is a script, as an [info level] or [info frame] in the inner context
* can see the difference.
*/
static int
CompileBasicNArgCommand(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Tcl_Token *tokenPtr;
Tcl_Obj *objPtr;
char *bytes;
int length, i, literal;
DefineLineInformation;
/*
* Push the name of the command we're actually dispatching to as part of
* the implementation.
*/
objPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
bytes = Tcl_GetStringFromObj(objPtr, &length);
literal = TclRegisterNewCmdLiteral(envPtr, bytes, length);
TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, literal), cmdPtr);
TclEmitPush(literal, envPtr);
TclDecrRefCount(objPtr);
/*
* Push the words of the command.
*/
tokenPtr = TokenAfter(parsePtr->tokenPtr);
for (i=1 ; i<parsePtr->numWords ; i++) {
if (envPtr->clNext) {
SetLineInformation(i);
}
if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
PushLiteral(envPtr, tokenPtr[1].start, tokenPtr[1].size);
} else {
CompileTokens(envPtr, tokenPtr, interp);
}
tokenPtr = TokenAfter(tokenPtr);
}
/*
* Do the standard dispatch.
*/
if (i <= 255) {
TclEmitInstInt1(INST_INVOKE_STK1, i, envPtr);
} else {
TclEmitInstInt4(INST_INVOKE_STK4, i, envPtr);
}
return TCL_OK;
}
int
TclCompileBasic0ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 1) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic1ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 2) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic2ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 3) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic3ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 4) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic0Or1ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 1 && parsePtr->numWords != 2) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic1Or2ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic2Or3ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic0To2ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords < 1 || parsePtr->numWords > 3) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasic1To3ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords < 2 || parsePtr->numWords > 4) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasicMin0ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords < 1) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasicMin1ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords < 2) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
int
TclCompileBasicMin2ArgCmd(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
* created by Tcl_ParseCommand. */
Command *cmdPtr, /* Points to defintion of command being
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
/*
* Verify that the number of arguments is correct; that's the only case
* that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
* which is the only code that sees the shenanigans of ensemble dispatch.
*/
if (parsePtr->numWords < 3) {
return TCL_ERROR;
}
return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
}
/*
* Local Variables:
+2 -2
View File
@@ -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);
+202 -137
View File
@@ -251,13 +251,27 @@ VarHashCreateVar(
* otherwise, push objResultPtr. If (result < 0), objResultPtr already
* has the correct reference count.
*
* We use the new compile-time assertions to cheack that nCleanup is constant
* We use the new compile-time assertions to check that nCleanup is constant
* and within range.
*/
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
/* Verify the stack depth, only when no expansion is in progress */
#if TCL_COMPILE_DEBUG
#define CHECK_STACK() \
do { \
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \
/*checkStack*/ !(starting || auxObjList)); \
starting = 0; \
} while (0)
#else
#define CHECK_STACK()
#endif
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
do { \
TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2)); \
CHECK_STACK(); \
if (nCleanup == 0) { \
if (resultHandling != 0) { \
if ((resultHandling) > 0) { \
@@ -286,7 +300,8 @@ VarHashCreateVar(
} \
} while (0)
#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
CHECK_STACK(); \
do { \
pc += (pcAdjustment); \
cleanup = (nCleanup); \
@@ -685,7 +700,7 @@ static void PrintByteCodeInfo(ByteCode *codePtr);
static const char * StringForResultCode(int result);
static void ValidatePcAndStackTop(ByteCode *codePtr,
const unsigned char *pc, int stackTop,
int stackLowerBound, int checkStack);
int checkStack);
#endif /* TCL_COMPILE_DEBUG */
static ByteCode * CompileExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void DeleteExecStack(ExecStack *esPtr);
@@ -1048,6 +1063,7 @@ GrowEvaluationStack(
return MEMSTART(markerPtr);
}
} else {
#ifndef PURIFY
Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
int offset = OFFSET(tmpMarkerPtr);
@@ -1064,6 +1080,7 @@ GrowEvaluationStack(
*esPtr->markerPtr = (Tcl_Obj *) markerPtr;
return memStart;
}
#endif
}
/*
@@ -1077,6 +1094,7 @@ GrowEvaluationStack(
}
needed = growth + moveWords + WALLOCALIGN;
/*
* Check if there is enough room in the next stack (if there is one, it
* should be both empty and the last one!)
@@ -1106,10 +1124,15 @@ GrowEvaluationStack(
* including the elements to be copied over and the new marker.
*/
#ifndef PURIFY
newElems = 2*currElems;
while (needed > newElems) {
newElems *= 2;
}
#else
newElems = needed;
#endif
newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);
oldPtr = esPtr;
@@ -1212,7 +1235,7 @@ TclStackFree(
Tcl_Obj **markerPtr, *marker;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
Tcl_Free((char *) freePtr);
ckfree((char *) freePtr);
return;
}
@@ -1258,6 +1281,10 @@ TclStackFree(
}
if (esPtr->prevPtr) {
eePtr->execStackPtr = esPtr->prevPtr;
#ifdef PURIFY
eePtr->execStackPtr->nextPtr = NULL;
DeleteExecStack(esPtr);
#endif
} else {
eePtr->execStackPtr = esPtr;
}
@@ -1272,7 +1299,7 @@ TclStackAlloc(
int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
return (void *) Tcl_Alloc(numBytes);
return (void *) ckalloc(numBytes);
}
return (void *) StackAllocWords(interp, numWords);
@@ -1291,7 +1318,7 @@ TclStackRealloc(
int numWords;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
return (void *) Tcl_Realloc((char *) ptr, numBytes);
return (void *) ckrealloc((char *) ptr, numBytes);
}
eePtr = iPtr->execEnvPtr;
@@ -1467,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)
@@ -1507,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++;
@@ -1579,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);
@@ -1640,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)
@@ -1768,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++;
@@ -2060,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.
@@ -2085,6 +2112,7 @@ TEBCresume(
#endif
#ifdef TCL_COMPILE_DEBUG
int starting = 1;
traceInstructions = (tclTraceExec == 3);
#endif
@@ -2226,24 +2254,6 @@ TEBCresume(
}
cleanup0:
#ifdef TCL_COMPILE_DEBUG
/*
* Skip the stack depth check if an expansion is in progress.
*/
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, 0,
/*checkStack*/ auxObjList == NULL);
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).
@@ -2275,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
@@ -2286,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
switch (*pc) {
#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 */
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);
@@ -2376,7 +2424,6 @@ TEBCresume(
case INST_TAILCALL: {
Tcl_Obj *listPtr, *nsObjPtr;
NRE_callback *tailcallPtr;
opnd = TclGetUInt1AtPtr(pc+1);
@@ -2410,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);
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
if (iPtr->varFramePtr->tailcallPtr) {
Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
}
iPtr->varFramePtr->tailcallPtr = listPtr;
/*
* Unstitch ourselves and do a [return].
*/
tailcallPtr = TOP_CB(interp);
TOP_CB(interp) = tailcallPtr->nextPtr;
iPtr->varFramePtr->tailcallPtr = tailcallPtr;
result = TCL_RETURN;
cleanup = opnd;
goto processExceptionReturn;
@@ -2449,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);
@@ -2475,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;
@@ -2972,6 +2938,70 @@ TEBCresume(
Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_FUNC1 found");
#endif
case INST_INVOKE_REPLACE:
objc = TclGetUInt4AtPtr(pc+1);
opnd = TclGetUInt1AtPtr(pc+5);
objPtr = POP_OBJECT();
objv = &OBJ_AT_DEPTH(objc-1);
cleanup = objc;
#ifdef TCL_COMPILE_DEBUG
if (tclTraceExec >= 2) {
int i;
if (traceInstructions) {
strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
TRACE(("%u => call (implementation %s) ", objc, O2S(objPtr)));
} else {
fprintf(stdout,
"%d: (%u) invoking (using implementation %s) ",
iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
O2S(objPtr));
}
for (i = 0; i < objc; i++) {
if (i < opnd) {
fprintf(stdout, "<");
TclPrintObject(stdout, objv[i], 15);
fprintf(stdout, ">");
} else {
TclPrintObject(stdout, objv[i], 15);
}
fprintf(stdout, " ");
}
fprintf(stdout, "\n");
fflush(stdout);
}
#endif /*TCL_COMPILE_DEBUG*/
{
Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
Tcl_Obj **copyObjv = &listRepPtr->elements;
int i;
listRepPtr->elemCount = objc - opnd + 1;
copyObjv[0] = objPtr;
memcpy(copyObjv+1, objv+opnd, sizeof(Tcl_Obj *) * (objc - opnd));
for (i=1 ; i<objc-opnd+1 ; i++) {
Tcl_IncrRefCount(copyObjv[i]);
}
objPtr = copyPtr;
}
bcFramePtr->data.tebc.pc = (char *) pc;
iPtr->cmdFramePtr = bcFramePtr;
if (iPtr->flags & INTERP_DEBUG_FRAME) {
TclArgumentBCEnter((Tcl_Interp *) iPtr, objv, objc,
codePtr, bcFramePtr, pc - codePtr->codeStart);
}
iPtr->ensembleRewrite.sourceObjs = objv;
iPtr->ensembleRewrite.numRemovedObjs = opnd;
iPtr->ensembleRewrite.numInsertedObjs = 1;
DECACHE_STACK_INFO();
pc += 6;
TEBC_YIELD();
TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL);
TclSkipTailcall(interp);
return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN);
/*
* -----------------------------------------------------------------
* Start of INST_LOAD instructions.
@@ -3433,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;
@@ -7022,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
@@ -8485,11 +8551,10 @@ ValidatePcAndStackTop(
int stackTop, /* Current stack top. Must be between
* stackLowerBound and stackUpperBound
* (inclusive). */
int stackLowerBound, /* Smallest legal value for stackTop. */
int checkStack) /* 0 if the stack depth check should be
* skipped. */
{
int stackUpperBound = stackLowerBound + codePtr->maxStackDepth;
int stackUpperBound = codePtr->maxStackDepth;
/* Greatest legal value for stackTop. */
unsigned relativePc = (unsigned) (pc - codePtr->codeStart);
unsigned long codeStart = (unsigned long) codePtr->codeStart;
@@ -8507,13 +8572,13 @@ ValidatePcAndStackTop(
(unsigned) opCode, relativePc);
Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode");
}
if (checkStack &&
((stackTop < stackLowerBound) || (stackTop > stackUpperBound))) {
if (checkStack &&
((stackTop < 0) || (stackTop > stackUpperBound))) {
int numChars;
const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL);
fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min %i, max %i)",
stackTop, relativePc, stackLowerBound, stackUpperBound);
fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)",
stackTop, relativePc, stackUpperBound);
if (cmd != NULL) {
Tcl_Obj *message;
+7 -10
View File
@@ -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)) {
+1 -1
View File
@@ -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");
}
+119 -3
View File
@@ -15,6 +15,108 @@
#include "tclIO.h"
#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
@@ -43,6 +145,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;
@@ -2472,7 +2588,7 @@ FlushChannel(
* it's a tty channel (dup'ed underneath)
*/
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED) && !TclInExit()) {
SetFlag(statePtr, BG_FLUSH_SCHEDULED);
UpdateInterest(chanPtr);
}
+6 -119
View File
@@ -29,26 +29,6 @@
#error one of EWOULDBLOCK or EAGAIN must be defined
#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:
*
@@ -85,19 +65,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
@@ -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.
@@ -341,89 +311,6 @@ typedef struct ChannelState {
* No further Tcl-level write IO on
* 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.
+19 -19
View File
@@ -1952,25 +1952,25 @@ TclInitChanCmd(
* function at the moment.
*/
static const EnsembleImplMap initMap[] = {
{"blocked", Tcl_FblockedObjCmd, NULL, NULL, NULL, 0},
{"close", Tcl_CloseObjCmd, NULL, NULL, NULL, 0},
{"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
{"create", TclChanCreateObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
{"eof", Tcl_EofObjCmd, NULL, NULL, NULL, 0},
{"event", Tcl_FileEventObjCmd, NULL, NULL, NULL, 0},
{"flush", Tcl_FlushObjCmd, NULL, NULL, NULL, 0},
{"gets", Tcl_GetsObjCmd, NULL, NULL, NULL, 0},
{"names", TclChannelNamesCmd, NULL, NULL, NULL, 0},
{"pending", ChanPendingObjCmd, NULL, NULL, NULL, 0}, /* TIP #287 */
{"pop", TclChanPopObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
{"postevent", TclChanPostEventObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
{"push", TclChanPushObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
{"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
{"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
{"seek", Tcl_SeekObjCmd, NULL, NULL, NULL, 0},
{"pipe", ChanPipeObjCmd, NULL, NULL, NULL, 0}, /* TIP #304 */
{"tell", Tcl_TellObjCmd, NULL, NULL, NULL, 0},
{"truncate", ChanTruncateObjCmd, NULL, NULL, NULL, 0}, /* TIP #208 */
{"blocked", Tcl_FblockedObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"close", Tcl_CloseObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
{"create", TclChanCreateObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
{"eof", Tcl_EofObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"event", Tcl_FileEventObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
{"flush", Tcl_FlushObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"gets", Tcl_GetsObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"names", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"pending", ChanPendingObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #287 */
{"pipe", ChanPipeObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, /* TIP #304 */
{"pop", TclChanPopObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, /* TIP #230 */
{"postevent", TclChanPostEventObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
{"push", TclChanPushObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #230 */
{"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
{"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
{"seek", Tcl_SeekObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
{"tell", Tcl_TellObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"truncate", ChanTruncateObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, /* TIP #208 */
{NULL, NULL, NULL, NULL, NULL, 0}
};
static const char *const extras[] = {
+3 -3
View File
@@ -2942,7 +2942,7 @@ ResultClear(
return;
}
Tcl_Free((char *) rPtr->buf);
ckfree((char *) rPtr->buf);
rPtr->buf = NULL;
rPtr->allocated = 0;
}
@@ -2977,10 +2977,10 @@ ResultAdd(
if (rPtr->allocated == 0) {
rPtr->allocated = toWrite + RB_INCREMENT;
rPtr->buf = UCHARP(Tcl_Alloc(rPtr->allocated));
rPtr->buf = UCHARP(ckalloc(rPtr->allocated));
} else {
rPtr->allocated += toWrite + RB_INCREMENT;
rPtr->buf = UCHARP(Tcl_Realloc((char *) rPtr->buf,
rPtr->buf = UCHARP(ckrealloc((char *) rPtr->buf,
rPtr->allocated));
}
}
-3
View File
@@ -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"
+26 -25
View File
@@ -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;
@@ -302,10 +307,6 @@ Tcl_GetIndexFromObjStruct(
entryPtr = NEXT_ENTRY(entryPtr, offset), idx++) {
for (p1 = key, p2 = *entryPtr; *p1 == *p2; p1++, p2++) {
if (*p1 == '\0') {
if (p1 == key) {
/* empty keys never match */
continue;
}
index = idx;
goto done;
}
@@ -340,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;
@@ -447,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);
@@ -482,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;
}
@@ -511,7 +512,7 @@ static void
FreeIndex(
Tcl_Obj *objPtr)
{
ckfree(objPtr->internalRep.otherValuePtr);
ckfree(objPtr->internalRep.twoPtrValue.ptr1);
objPtr->typePtr = NULL;
}
@@ -537,9 +538,9 @@ TclInitPrefixCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap prefixImplMap[] = {
{"all", PrefixAllObjCmd, NULL, NULL, NULL, 0},
{"longest", PrefixLongestObjCmd, NULL, NULL, NULL, 0},
{"match", PrefixMatchObjCmd, NULL, NULL, NULL, 0},
{"all", PrefixAllObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"longest", PrefixLongestObjCmd,TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"match", PrefixMatchObjCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
Tcl_Command prefixCmd;
@@ -952,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);
@@ -1007,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 {
+35 -36
View File
@@ -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 {
@@ -1148,9 +1148,6 @@ declare 27 win {
declare 28 win {
void TclWinResetInterfaces(void)
}
declare 29 win {
int TclWinCPUID(unsigned int index, unsigned int *regs)
}
################################
# Unix specific functions
@@ -1219,12 +1216,6 @@ declare 14 unix {
const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
}
# Added in 8.6; core of TclpOpenTemporaryFile
declare 20 unix {
int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj,
Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj)
}
################################
# Mac OS X specific functions
@@ -1248,9 +1239,17 @@ declare 18 macosx {
declare 19 macosx {
void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode)
}
declare 29 unix {
declare 29 {win unix} {
int TclWinCPUID(unsigned int index, unsigned int *regs)
}
# Added in 8.6; core of TclpOpenTemporaryFile
declare 30 {win unix} {
int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj,
Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj)
}
# Local Variables:
# mode: tcl
+51 -104
View File
@@ -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.
*/
@@ -588,30 +588,6 @@ typedef struct ActiveVarTrace {
* free'd memory. */
} 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
@@ -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;
@@ -2201,17 +2177,6 @@ typedef struct Interp {
#define TclUnsetCancelFlags(iPtr) \
(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:
@@ -2317,35 +2281,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
@@ -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);
@@ -3716,6 +3655,42 @@ MODULE_SCOPE int TclCompileWhileCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileYieldCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic0ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic1ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic2ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic3ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic0Or1ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic1Or2ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic2Or3ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic0To2ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasic1To3ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasicMin0ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasicMin1ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBasicMin2ArgCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclInvertOpCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
@@ -4008,12 +3983,13 @@ typedef const char *TclDTraceStr;
*/
# define TclAllocObjStorageEx(interp, objPtr) \
(objPtr) = (Tcl_Obj *) Tcl_Alloc(sizeof(Tcl_Obj))
(objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))
# define TclFreeObjStorageEx(interp, objPtr) \
ckfree((char *) (objPtr))
#undef USE_THREAD_ALLOC
#undef USE_TCLALLOC
#elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
/*
@@ -4049,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)
@@ -4062,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; \
} \
@@ -4090,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)
@@ -4771,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))
+98 -28
View File
@@ -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 */
+27 -14
View File
@@ -84,10 +84,7 @@ EXTERN int TclUnixCopyFile(const char *src, const char *dst,
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
/* 20 */
EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj);
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
@@ -98,6 +95,10 @@ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
/* Slot 28 is reserved */
/* 29 */
EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
/* 30 */
EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj);
#endif /* UNIX */
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
/* 0 */
@@ -169,6 +170,10 @@ EXTERN void TclWinFlushDirtyChannels(void);
EXTERN void TclWinResetInterfaces(void);
/* 29 */
EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
/* 30 */
EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 0 */
@@ -228,10 +233,7 @@ EXTERN int TclMacOSXMatchType(Tcl_Interp *interp,
/* 19 */
EXTERN void TclMacOSXNotifierAddRunLoopMode(
const void *runLoopMode);
/* 20 */
EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj);
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
@@ -242,6 +244,10 @@ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
/* Slot 28 is reserved */
/* 29 */
EXTERN int TclWinCPUID(unsigned int index, unsigned int *regs);
/* 30 */
EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj);
#endif /* MACOSX */
typedef struct TclIntPlatStubs {
@@ -269,7 +275,7 @@ typedef struct TclIntPlatStubs {
void (*reserved17)(void);
void (*reserved18)(void);
void (*reserved19)(void);
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 20 */
void (*reserved20)(void);
void (*reserved21)(void);
void (*reserved22)(void);
void (*reserved23)(void);
@@ -279,6 +285,7 @@ typedef struct TclIntPlatStubs {
void (*reserved27)(void);
void (*reserved28)(void);
int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* UNIX */
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
void (*tclWinConvertError) (DWORD errCode); /* 0 */
@@ -311,6 +318,7 @@ typedef struct TclIntPlatStubs {
void (*tclWinFlushDirtyChannels) (void); /* 27 */
void (*tclWinResetInterfaces) (void); /* 28 */
int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
@@ -333,7 +341,7 @@ typedef struct TclIntPlatStubs {
int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */
int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */
void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 20 */
void (*reserved20)(void);
void (*reserved21)(void);
void (*reserved22)(void);
void (*reserved23)(void);
@@ -343,6 +351,7 @@ typedef struct TclIntPlatStubs {
void (*reserved27)(void);
void (*reserved28)(void);
int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
#endif /* MACOSX */
} TclIntPlatStubs;
@@ -395,8 +404,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
/* Slot 17 is reserved */
/* Slot 18 is reserved */
/* Slot 19 is reserved */
#define TclUnixOpenTemporaryFile \
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 20 */
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
@@ -407,6 +415,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
/* Slot 28 is reserved */
#define TclWinCPUID \
(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
#define TclUnixOpenTemporaryFile \
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* UNIX */
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
#define TclWinConvertError \
@@ -467,6 +477,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclWinResetInterfaces) /* 28 */
#define TclWinCPUID \
(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
#define TclUnixOpenTemporaryFile \
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TclGetAndDetachPids \
@@ -508,8 +520,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
(tclIntPlatStubsPtr->tclMacOSXMatchType) /* 18 */
#define TclMacOSXNotifierAddRunLoopMode \
(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
#define TclUnixOpenTemporaryFile \
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 20 */
/* Slot 20 is reserved */
/* Slot 21 is reserved */
/* Slot 22 is reserved */
/* Slot 23 is reserved */
@@ -520,6 +531,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
/* Slot 28 is reserved */
#define TclWinCPUID \
(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
#define TclUnixOpenTemporaryFile \
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
#endif /* MACOSX */
#endif /* defined(USE_TCL_STUBS) */
+33 -2
View File
@@ -178,6 +178,37 @@ typedef struct ScriptLimitCallbackKey {
long type; /* The type of callback that this is. */
} 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);
}
+11 -10
View File
@@ -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);
}
+20 -13
View File
@@ -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;
}
@@ -909,6 +909,10 @@ Tcl_ListObjReplace(
isShared = (listRepPtr->refCount > 1);
numRequired = numElems - count + objc;
for (i = 0; i < objc; i++) {
Tcl_IncrRefCount(objv[i]);
}
if ((numRequired <= listRepPtr->maxElemCount) && !isShared) {
int shift;
@@ -963,6 +967,14 @@ Tcl_ListObjReplace(
if (listRepPtr == NULL) {
listRepPtr = AttemptNewList(interp, numRequired, NULL);
if (listRepPtr == NULL) {
for (i = 0; i < objc; i++) {
/* See bug 3598580 */
#if TCL_MAJOR_VERSION > 8
Tcl_DecrRefCount(objv[i]);
#else
objv[i]->refCount--;
#endif
}
return TCL_ERROR;
}
}
@@ -1027,14 +1039,11 @@ Tcl_ListObjReplace(
}
/*
* Insert the new elements into elemPtrs before "first". We don't do a
* memcpy here because we must increment the reference counts for the
* added elements, so we must explicitly loop anyway.
* Insert the new elements into elemPtrs before "first".
*/
for (i=0,j=first ; i<objc ; i++,j++) {
elemPtrs[j] = objv[i];
Tcl_IncrRefCount(objv[i]);
}
/*
@@ -1048,7 +1057,7 @@ Tcl_ListObjReplace(
* reflects the list's internal representation.
*/
Tcl_InvalidateStringRep(listPtr);
TclInvalidateStringRep(listPtr);
return TCL_OK;
}
@@ -1514,7 +1523,7 @@ TclLsetFlat(
* containing lists.
*/
Tcl_InvalidateStringRep(objPtr);
TclInvalidateStringRep(objPtr);
}
/*
@@ -1550,7 +1559,7 @@ TclLsetFlat(
} else {
TclListObjSetElement(NULL, subListPtr, index, valuePtr);
}
Tcl_InvalidateStringRep(subListPtr);
TclInvalidateStringRep(subListPtr);
Tcl_IncrRefCount(retValuePtr);
return retValuePtr;
}
@@ -1727,8 +1736,6 @@ FreeListInternalRep(
ckfree(listRepPtr);
}
listPtr->internalRep.twoPtrValue.ptr1 = NULL;
listPtr->internalRep.twoPtrValue.ptr2 = NULL;
listPtr->typePtr = NULL;
}
+52 -8
View File
@@ -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);
}
@@ -298,6 +302,33 @@ TclCreateLiteral(
return objPtr;
}
/*
*----------------------------------------------------------------------
*
* 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;
}
/*
*----------------------------------------------------------------------
*
@@ -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",
+33
View File
@@ -81,6 +81,39 @@ TclGuessPackageName(
return 0;
}
/*
* 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
+37 -61
View File
@@ -160,23 +160,23 @@ static const Tcl_ObjType nsNameType = {
*/
static const EnsembleImplMap defaultNamespaceMap[] = {
{"children", NamespaceChildrenCmd, NULL, NULL, NULL, 0},
{"children", NamespaceChildrenCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
{"code", NamespaceCodeCmd, TclCompileNamespaceCodeCmd, NULL, NULL, 0},
{"current", NamespaceCurrentCmd, TclCompileNamespaceCurrentCmd, NULL, NULL, 0},
{"delete", NamespaceDeleteCmd, NULL, NULL, NULL, 0},
{"delete", NamespaceDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"ensemble", TclNamespaceEnsembleCmd, NULL, NULL, NULL, 0},
{"eval", NamespaceEvalCmd, NULL, NRNamespaceEvalCmd, NULL, 0},
{"exists", NamespaceExistsCmd, NULL, NULL, NULL, 0},
{"export", NamespaceExportCmd, NULL, NULL, NULL, 0},
{"forget", NamespaceForgetCmd, NULL, NULL, NULL, 0},
{"import", NamespaceImportCmd, NULL, NULL, NULL, 0},
{"exists", NamespaceExistsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"export", NamespaceExportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"forget", NamespaceForgetCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"import", NamespaceImportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"inscope", NamespaceInscopeCmd, NULL, NRNamespaceInscopeCmd, NULL, 0},
{"origin", NamespaceOriginCmd, NULL, NULL, NULL, 0},
{"parent", NamespaceParentCmd, NULL, NULL, NULL, 0},
{"path", NamespacePathCmd, NULL, NULL, NULL, 0},
{"origin", NamespaceOriginCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"parent", NamespaceParentCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"path", NamespacePathCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"qualifiers", NamespaceQualifiersCmd, TclCompileNamespaceQualifiersCmd, NULL, NULL, 0},
{"tail", NamespaceTailCmd, TclCompileNamespaceTailCmd, NULL, NULL, 0},
{"unknown", NamespaceUnknownCmd, NULL, NULL, NULL, 0},
{"unknown", NamespaceUnknownCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
{"upvar", NamespaceUpvarCmd, TclCompileNamespaceUpvarCmd, NULL, NULL, 0},
{"which", NamespaceWhichCmd, TclCompileNamespaceWhichCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
@@ -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,53 +3431,35 @@ 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...?");
return TCL_ERROR;
}
/*
* Process the optional "-clear" argument.
*/
firstArg = 1;
if (firstArg < objc) {
string = TclGetString(objv[firstArg]);
if (strcmp(string, "-clear") == 0) {
resetListFirst = 1;
firstArg++;
}
}
/*
* If no pattern arguments are given, and "-clear" isn't specified, return
* the namespace's current export pattern list.
*/
patternCt = objc - firstArg;
if (patternCt == 0) {
if (firstArg > 1) {
return TCL_OK;
} else {
/*
* Create list with export patterns.
*/
if (objc == 1) {
Tcl_Obj *listPtr = Tcl_NewObj();
Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
(void) Tcl_AppendExportList(interp, NULL, listPtr);
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
result = Tcl_AppendExportList(interp, (Tcl_Namespace *) currNsPtr,
listPtr);
if (result != TCL_OK) {
return result;
}
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
/*
* Process the optional "-clear" argument.
*/
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;
}
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -39,7 +39,7 @@ extern const char *TclOOInitializeStubs(
* win/tclooConfig.sh
*/
#define TCLOO_VERSION "0.7"
#define TCLOO_VERSION "1.0"
#define TCLOO_PATCHLEVEL TCLOO_VERSION
/*
+27 -28
View File
@@ -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;
+5 -6
View File
@@ -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;
+29 -41
View File
@@ -48,18 +48,18 @@ static Tcl_ObjCmdProc InfoClassVariablesCmd;
*/
static const EnsembleImplMap infoObjectCmds[] = {
{"call", InfoObjectCallCmd, NULL, NULL, NULL, 0},
{"call", InfoObjectCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"class", InfoObjectClassCmd, TclCompileInfoObjectClassCmd, NULL, NULL, 0},
{"definition", InfoObjectDefnCmd, NULL, NULL, NULL, 0},
{"filters", InfoObjectFiltersCmd, NULL, NULL, NULL, 0},
{"forward", InfoObjectForwardCmd, NULL, NULL, NULL, 0},
{"definition", InfoObjectDefnCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"filters", InfoObjectFiltersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"forward", InfoObjectForwardCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"isa", InfoObjectIsACmd, TclCompileInfoObjectIsACmd, NULL, NULL, 0},
{"methods", InfoObjectMethodsCmd, NULL, NULL, NULL, 0},
{"methodtype", InfoObjectMethodTypeCmd, NULL, NULL, NULL, 0},
{"mixins", InfoObjectMixinsCmd, NULL, NULL, NULL, 0},
{"methods", InfoObjectMethodsCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
{"methodtype", InfoObjectMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"mixins", InfoObjectMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"namespace", InfoObjectNsCmd, TclCompileInfoObjectNamespaceCmd, NULL, NULL, 0},
{"variables", InfoObjectVariablesCmd, NULL, NULL, NULL, 0},
{"vars", InfoObjectVarsCmd, NULL, NULL, NULL, 0},
{"variables", InfoObjectVariablesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"vars", InfoObjectVarsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -68,19 +68,19 @@ static const EnsembleImplMap infoObjectCmds[] = {
*/
static const EnsembleImplMap infoClassCmds[] = {
{"call", InfoClassCallCmd, NULL, NULL, NULL, 0},
{"constructor", InfoClassConstrCmd, NULL, NULL, NULL, 0},
{"definition", InfoClassDefnCmd, NULL, NULL, NULL, 0},
{"destructor", InfoClassDestrCmd, NULL, NULL, NULL, 0},
{"filters", InfoClassFiltersCmd, NULL, NULL, NULL, 0},
{"forward", InfoClassForwardCmd, NULL, NULL, NULL, 0},
{"instances", InfoClassInstancesCmd, NULL, NULL, NULL, 0},
{"methods", InfoClassMethodsCmd, NULL, NULL, NULL, 0},
{"methodtype", InfoClassMethodTypeCmd, NULL, NULL, NULL, 0},
{"mixins", InfoClassMixinsCmd, NULL, NULL, NULL, 0},
{"subclasses", InfoClassSubsCmd, NULL, NULL, NULL, 0},
{"superclasses", InfoClassSupersCmd, NULL, NULL, NULL, 0},
{"variables", InfoClassVariablesCmd, NULL, NULL, NULL, 0},
{"call", InfoClassCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"constructor", InfoClassConstrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"definition", InfoClassDefnCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"destructor", InfoClassDestrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"filters", InfoClassFiltersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"forward", InfoClassForwardCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"instances", InfoClassInstancesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"methods", InfoClassMethodsCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
{"methodtype", InfoClassMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"mixins", InfoClassMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"subclasses", InfoClassSubsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"superclasses", InfoClassSupersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"variables", InfoClassVariablesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -100,6 +100,7 @@ TclOOInitInfo(
Tcl_Interp *interp)
{
Tcl_Command infoCmd;
Tcl_Obj *mapDict;
/*
* Build the ensembles used to implement [info object] and [info class].
@@ -113,25 +114,12 @@ TclOOInitInfo(
*/
infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
if (infoCmd != NULL && Tcl_IsEnsemble(infoCmd)) {
Tcl_Obj *mapDict, *objectObj, *classObj;
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
if (mapDict != NULL) {
objectObj = Tcl_NewStringObj("object", -1);
classObj = Tcl_NewStringObj("class", -1);
Tcl_IncrRefCount(objectObj);
Tcl_IncrRefCount(classObj);
Tcl_DictObjPut(NULL, mapDict, objectObj,
Tcl_NewStringObj("::oo::InfoObject", -1));
Tcl_DictObjPut(NULL, mapDict, classObj,
Tcl_NewStringObj("::oo::InfoClass", -1));
Tcl_DecrRefCount(objectObj);
Tcl_DecrRefCount(classObj);
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
}
}
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
Tcl_NewStringObj("::oo::InfoObject", -1));
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
Tcl_NewStringObj("::oo::InfoClass", -1));
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
}
/*
+1 -1
View File
@@ -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;
}
+31 -47
View File
@@ -2,19 +2,6 @@
* ORIGINAL SOURCE: tk/generic/tkStubLib.c, version 1.9 2004/03/17
*/
/*
* We need to ensure that we use the tcl stub macros so that this file
* contains no references to any of the tcl stub functions.
*/
#undef USE_TCL_STUBS
#define USE_TCL_STUBS
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define USE_TCLOO_STUBS 1
#include "tclOOInt.h"
MODULE_SCOPE const TclOOStubs *tclOOStubsPtr;
@@ -35,51 +22,48 @@ const TclOOIntStubs *tclOOIntStubsPtr = NULL;
* to indicate that an error occurred.
*
* Side effects:
* Sets the stub table pointer.
* Sets the stub table pointers.
*
*----------------------------------------------------------------------
*/
MODULE_SCOPE const char *
TclOOInitializeStubs(
Tcl_Interp *interp, const char *version)
Tcl_Interp *interp,
const char *version)
{
int exact = 0;
const char *packageName = "TclOO";
const char *errMsg = NULL;
ClientData clientData = NULL;
const char *actualVersion =
Tcl_PkgRequireEx(interp, packageName,version, exact, &clientData);
TclOOStubs *stubsPtr = NULL;
const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
packageName, version, exact, &stubsPtr);
if (clientData == NULL) {
Tcl_ResetResult(interp);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error loading %s package; package not present or incomplete",
packageName));
return NULL;
} else {
const TclOOStubs * const stubsPtr = clientData;
const TclOOIntStubs * const intStubsPtr = stubsPtr->hooks ?
stubsPtr->hooks->tclOOIntStubs : NULL;
if (!actualVersion) {
return NULL;
}
if (!stubsPtr || !intStubsPtr) {
errMsg = "missing stub table pointer";
goto error;
}
tclOOStubsPtr = stubsPtr;
tclOOIntStubsPtr = intStubsPtr;
return actualVersion;
error:
Tcl_ResetResult(interp);
Tcl_SetObjResult(interp, Tcl_ObjPrintf("Error loading %s package"
" (requested version '%s', loaded version '%s'): %s",
packageName, version, actualVersion, errMsg));
if (actualVersion == NULL) {
return NULL;
}
if (stubsPtr == NULL) {
errMsg = "missing stub table pointer";
} else {
tclOOStubsPtr = stubsPtr;
if (stubsPtr->hooks) {
tclOOIntStubsPtr = stubsPtr->hooks->tclOOIntStubs;
} else {
tclOOIntStubsPtr = NULL;
}
return actualVersion;
}
tclStubsPtr->tcl_ResetResult(interp);
tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
" (requested version ", version, ", actual version ",
actualVersion, "): ", errMsg, NULL);
return NULL;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
+32 -13
View File
@@ -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)) {
/*
+1 -1
View File
@@ -42,7 +42,7 @@
* TYPE_BRACE - Character is a curly brace (either left or right).
*/
const char charTypeTable[] = {
const char tclCharTypeTable[] = {
/*
* Negative character values, from -128 to -1:
*/
+2 -2
View File
@@ -12,6 +12,6 @@
#define TYPE_CLOSE_BRACK 0x20
#define TYPE_BRACE 0x40
#define CHAR_TYPE(c) (charTypeTable+128)[(int)(c)]
#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]
MODULE_SCOPE const char charTypeTable[];
MODULE_SCOPE const char tclCharTypeTable[];
+4 -4
View File
@@ -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);
+9 -2
View File
@@ -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
@@ -356,6 +358,10 @@ PkgRequireCore(
char *script, *pkgVersionI;
Tcl_DString command;
if (TCL_OK != CheckAllRequirements(interp, reqc, reqv)) {
return NULL;
}
/*
* It can take up to three passes to find the package: one pass to run the
* "package unknown" script, one to run the "package ifneeded" script for
@@ -666,6 +672,7 @@ PkgRequireCore(
*----------------------------------------------------------------------
*/
#undef Tcl_PkgPresent
const char *
Tcl_PkgPresent(
Tcl_Interp *interp, /* Interpreter in which package is now
@@ -942,7 +949,7 @@ Tcl_PackageObjCmd(
version = TclGetString(objv[3]);
}
}
Tcl_PkgPresent(interp, name, version, exact);
Tcl_PkgPresentEx(interp, name, version, exact, NULL);
return TCL_ERROR;
break;
}
@@ -967,7 +974,7 @@ Tcl_PackageObjCmd(
if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
return Tcl_PkgProvide(interp, argv2, argv3);
return Tcl_PkgProvideEx(interp, argv2, argv3, NULL);
case PKG_REQUIRE:
require:
if (objc < 3) {
+2 -3
View File
@@ -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
+19 -30
View File
@@ -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));
+5 -5
View File
@@ -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;
}
+4 -1
View File
@@ -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) {
+2 -2
View File
@@ -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
+40 -9
View File
@@ -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
@@ -65,6 +92,7 @@ static unsigned short TclWinNToHS(unsigned short ns) {
#ifdef __WIN32__
# define TclUnixWaitForFile 0
# define TclUnixCopyFile 0
# define TclUnixOpenTemporaryFile 0
# define TclpReaddir 0
# define TclpIsAtty 0
#elif defined(__CYGWIN__)
@@ -346,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 */
@@ -355,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 */
@@ -366,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 */
@@ -424,7 +452,7 @@ static const TclIntStubs tclIntStubs = {
TclGetSrcInfoForPc, /* 233 */
TclVarHashCreateVar, /* 234 */
TclInitVarHashTable, /* 235 */
0, /* 236 */
TclBackgroundException, /* 236 */
TclResetCancellation, /* 237 */
TclNRInterpProc, /* 238 */
TclNRInterpProcCore, /* 239 */
@@ -465,7 +493,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
0, /* 17 */
0, /* 18 */
0, /* 19 */
TclUnixOpenTemporaryFile, /* 20 */
0, /* 20 */
0, /* 21 */
0, /* 22 */
0, /* 23 */
@@ -475,6 +503,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
0, /* 27 */
0, /* 28 */
TclWinCPUID, /* 29 */
TclUnixOpenTemporaryFile, /* 30 */
#endif /* UNIX */
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
TclWinConvertError, /* 0 */
@@ -507,6 +536,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
TclWinFlushDirtyChannels, /* 27 */
TclWinResetInterfaces, /* 28 */
TclWinCPUID, /* 29 */
TclUnixOpenTemporaryFile, /* 30 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
TclGetAndDetachPids, /* 0 */
@@ -529,7 +559,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
TclMacOSXCopyFileAttributes, /* 17 */
TclMacOSXMatchType, /* 18 */
TclMacOSXNotifierAddRunLoopMode, /* 19 */
TclUnixOpenTemporaryFile, /* 20 */
0, /* 20 */
0, /* 21 */
0, /* 22 */
0, /* 23 */
@@ -539,6 +569,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
0, /* 27 */
0, /* 28 */
TclWinCPUID, /* 29 */
TclUnixOpenTemporaryFile, /* 30 */
#endif /* MACOSX */
};
+12 -34
View File
@@ -11,15 +11,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
/*
* We need to ensure that we use the stub macros so that this file contains no
* references to any of the stub functions. This will make it possible to
* build an extension that references Tcl_InitStubs but doesn't end up
* including the rest of the stub functions.
*/
#define USE_TCL_STUBS
#include "tclInt.h"
MODULE_SCOPE const TclStubs *tclStubsPtr;
@@ -32,24 +23,8 @@ const TclPlatStubs *tclPlatStubsPtr = NULL;
const TclIntStubs *tclIntStubsPtr = NULL;
const TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
static const TclStubs *
HasStubSupport(
Tcl_Interp *interp)
{
Interp *iPtr = (Interp *) interp;
if (iPtr->stubTable && (iPtr->stubTable->magic == TCL_STUB_MAGIC)) {
return iPtr->stubTable;
}
iPtr->result =
(char *)"This interpreter does not support stubs-enabled extensions.";
iPtr->freeProc = TCL_STATIC;
return NULL;
}
/*
* Use our own isdigit to avoid linking to libc on windows
* Use our own isDigit to avoid linking to libc on windows
*/
static int isDigit(const int c)
@@ -74,15 +49,17 @@ static int isDigit(const int c)
*
*----------------------------------------------------------------------
*/
#undef Tcl_InitStubs
MODULE_SCOPE const char *
Tcl_InitStubs(
Tcl_Interp *interp,
const char *version,
int exact)
{
Interp *iPtr = (Interp *) interp;
const char *actualVersion = NULL;
ClientData pkgData = NULL;
const TclStubs *stubsPtr = iPtr->stubTable;
/*
* We can't optimize this check by caching tclStubsPtr because that
@@ -90,12 +67,13 @@ Tcl_InitStubs(
* times. [Bug 615304]
*/
tclStubsPtr = HasStubSupport(interp);
if (!tclStubsPtr) {
if (!stubsPtr || (stubsPtr->magic != TCL_STUB_MAGIC)) {
iPtr->result = "interpreter uses an incompatible stubs mechanism";
iPtr->freeProc = TCL_STATIC;
return NULL;
}
actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
if (actualVersion == NULL) {
return NULL;
}
@@ -113,19 +91,19 @@ Tcl_InitStubs(
while (*p && (*p == *q)) {
p++; q++;
}
if (*p) {
if (*p || isDigit(*q)) {
/* Construct error message */
Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
return NULL;
}
} else {
actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
if (actualVersion == NULL) {
return NULL;
}
}
}
tclStubsPtr = (TclStubs *) pkgData;
tclStubsPtr = (TclStubs *)pkgData;
if (tclStubsPtr->hooks) {
tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+20 -4
View File
@@ -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
+15 -4
View File
@@ -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]);
}
@@ -963,6 +963,17 @@ TestobjCmd(
}
SetVarToObj(varPtr, destIndex, varPtr[varIndex]);
Tcl_SetObjResult(interp, varPtr[destIndex]);
} else if (strcmp(subCmd, "bug3598580") == 0) {
Tcl_Obj *listObjPtr, *elemObjPtr;
if (objc != 2) {
goto wrongNumArgs;
}
elemObjPtr = Tcl_NewIntObj(123);
listObjPtr = Tcl_NewListObj(1, &elemObjPtr);
/* Replace the single list element through itself, nonsense but legal. */
Tcl_ListObjReplace(interp, listObjPtr, 0, 1, 1, &elemObjPtr);
Tcl_SetObjResult(interp, listObjPtr);
return TCL_OK;
} else if (strcmp(subCmd, "convert") == 0) {
const char *typeName;
@@ -1239,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;
@@ -1293,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;
+6 -6
View File
@@ -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;
}
+2 -2
View File
@@ -513,7 +513,6 @@ ThreadCreate(
TCL_THREAD_STACK_DEFAULT, joinable) != TCL_OK) {
Tcl_MutexUnlock(&threadMutex);
Tcl_AppendResult(interp, "can't create a new thread", NULL);
ckfree(ctrl.script);
return TCL_ERROR;
}
@@ -927,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;
+3 -3
View File
@@ -111,7 +111,7 @@ extern void *
TclBNAlloc(
size_t x)
{
return (void *) Tcl_Alloc((unsigned int) x);
return (void *) ckalloc((unsigned int) x);
}
/*
@@ -135,7 +135,7 @@ TclBNRealloc(
void *p,
size_t s)
{
return (void *) Tcl_Realloc((char *) p, (unsigned int) s);
return (void *) ckrealloc((char *) p, (unsigned int) s);
}
/*
@@ -161,7 +161,7 @@ extern void
TclBNFree(
void *p)
{
Tcl_Free((char *) p);
ckree((char *) p);
}
#endif
+11 -21
View File
@@ -11,15 +11,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
/*
* We need to ensure that we use the stub macros so that this file contains no
* references to any of the stub functions. This will make it possible to
* build an extension that references Tcl_InitStubs but doesn't end up
* including the rest of the stub functions.
*/
#define USE_TCL_STUBS
#include "tclInt.h"
MODULE_SCOPE const TclTomMathStubs *tclTomMathStubsPtr;
@@ -55,31 +46,30 @@ TclTomMathInitializeStubs(
int exact = 0;
const char *packageName = "tcl::tommath";
const char *errMsg = NULL;
ClientData pkgClientData = NULL;
const char *actualVersion =
Tcl_PkgRequireEx(interp, packageName, version, exact, &pkgClientData);
const TclTomMathStubs *stubsPtr = pkgClientData;
TclTomMathStubs *stubsPtr = NULL;
const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
packageName, version, exact, &stubsPtr);
if (actualVersion == NULL) {
return NULL;
}
if (pkgClientData == NULL) {
if (stubsPtr == NULL) {
errMsg = "missing stub table pointer";
} else if ((stubsPtr->tclBN_epoch)() != epoch) {
} else if(stubsPtr->tclBN_epoch() != epoch) {
errMsg = "epoch number mismatch";
} else if ((stubsPtr->tclBN_revision)() != revision) {
} else if(stubsPtr->tclBN_revision() != revision) {
errMsg = "requires a later revision";
} else {
tclTomMathStubsPtr = stubsPtr;
return actualVersion;
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error loading %s (requested version %s, actual version %s): %s",
packageName, version, actualVersion, errMsg));
tclStubsPtr->tcl_ResetResult(interp);
tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
" (requested version ", version, ", actual version ",
actualVersion, "): ", errMsg, NULL);
return NULL;
}
/*
* Local Variables:
* mode: c
+11 -4
View File
@@ -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
+3 -2
View File
@@ -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);
+12 -10
View File
@@ -167,7 +167,7 @@ const Tcl_ObjType tclEndOffsetType = {
* separating whitespace, or a string terminator. It is just another
* character in a list element.
*
* The interpretaton of a formatted substring as a list element follows rules
* The interpretation of a formatted substring as a list element follows rules
* similar to the parsing of the words of a command in a Tcl script. Backslash
* substitution plays a key role, and is defined exactly as it is in command
* parsing. The same routine, TclParseBackslash() is used in both command
@@ -179,7 +179,7 @@ const Tcl_ObjType tclEndOffsetType = {
* Backslash substitution replaces an "escape sequence" of one or more
* characters starting with
* \u005c \ BACKSLASH
* with a single character. The one character escape sequent case happens only
* with a single character. The one character escape sequence case happens only
* when BACKSLASH is the last character in the string. In all other cases, the
* escape sequence is at least two characters long.
*
@@ -2927,14 +2927,16 @@ TclDStringToObj(
{
Tcl_Obj *result;
if (dsPtr->length == 0) {
TclNewObj(result);
} else if (dsPtr->string == dsPtr->staticSpace) {
/*
* Static buffer, so must copy.
*/
TclNewStringObj(result, dsPtr->string, dsPtr->length);
if (dsPtr->string == dsPtr->staticSpace) {
if (dsPtr->length == 0) {
TclNewObj(result);
} else {
/*
* Static buffer, so must copy.
*/
TclNewStringObj(result, dsPtr->string, dsPtr->length);
}
} else {
/*
* Dynamic buffer, so transfer ownership and reset.
+123 -95
View File
@@ -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,
@@ -136,6 +143,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;
/* 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;
}
}
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);
}
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.
*
*----------------------------------------------------------------------
*/
@@ -4222,16 +4255,16 @@ TclInitArrayCmd(
Tcl_Interp *interp) /* Current interpreter. */
{
static const EnsembleImplMap arrayImplMap[] = {
{"anymore", ArrayAnyMoreCmd, NULL, NULL, NULL, 0},
{"donesearch", ArrayDoneSearchCmd, NULL, NULL, NULL, 0},
{"anymore", ArrayAnyMoreCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"donesearch", ArrayDoneSearchCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"exists", ArrayExistsCmd, TclCompileArrayExistsCmd, NULL, NULL, 0},
{"get", ArrayGetCmd, NULL, NULL, NULL, 0},
{"names", ArrayNamesCmd, NULL, NULL, NULL, 0},
{"nextelement", ArrayNextElementCmd, NULL, NULL, NULL, 0},
{"get", ArrayGetCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{"names", ArrayNamesCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"nextelement", ArrayNextElementCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"set", ArraySetCmd, TclCompileArraySetCmd, NULL, NULL, 0},
{"size", ArraySizeCmd, NULL, NULL, NULL, 0},
{"startsearch", ArrayStartSearchCmd, NULL, NULL, NULL, 0},
{"statistics", ArrayStatsCmd, NULL, NULL, NULL, 0},
{"size", ArraySizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"startsearch", ArrayStartSearchCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"statistics", ArrayStatsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"unset", ArrayUnsetCmd, TclCompileArrayUnsetCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -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;
}
+45 -48
View File
@@ -507,7 +507,7 @@ GenerateHeader(
* ExtractHeader --
*
* Take the values out of a gzip header and store them in a dictionary.
* SetValue is a helper function.
* SetValue is a helper macro.
*
* Results:
* None.
@@ -518,18 +518,8 @@ GenerateHeader(
*----------------------------------------------------------------------
*/
static inline void
SetValue(
Tcl_Obj *dictObj,
const char *key,
Tcl_Obj *value)
{
Tcl_Obj *keyObj = Tcl_NewStringObj(key, -1);
Tcl_IncrRefCount(keyObj);
Tcl_DictObjPut(NULL, dictObj, keyObj, value);
TclDecrRefCount(keyObj);
}
#define SetValue(dictObj, key, value) \
Tcl_DictObjPut(NULL, (dictObj), Tcl_NewStringObj((key), -1), (value))
static void
ExtractHeader(
@@ -2119,9 +2109,6 @@ ZlibCmd(
}
if (headerVarObj != NULL && Tcl_ObjSetVar2(interp, headerVarObj, NULL,
headerDictObj, TCL_LEAVE_ERR_MSG) == NULL) {
if (headerDictObj) {
TclDecrRefCount(headerDictObj);
}
return TCL_ERROR;
}
return TCL_OK;
@@ -2177,29 +2164,36 @@ ZlibStreamSubcmd(
FMT_INFLATE
};
int i, format, mode = 0, option, level;
enum objIndices {
OPT_COMPRESSION_DICTIONARY = 0,
OPT_GZIP_HEADER = 1,
OPT_COMPRESSION_LEVEL = 2,
OPT_END = -1
};
Tcl_Obj *obj[3] = { NULL, NULL, NULL };
#define compDictObj obj[OPT_COMPRESSION_DICTIONARY]
#define gzipHeaderObj obj[OPT_GZIP_HEADER]
#define levelObj obj[OPT_COMPRESSION_LEVEL]
typedef struct {
const char *name;
Tcl_Obj **valueVar;
enum objIndices offset;
} OptDescriptor;
Tcl_Obj *compDictObj = NULL;
Tcl_Obj *gzipHeaderObj = NULL;
Tcl_Obj *levelObj = NULL;
const OptDescriptor compressionOpts[] = {
{ "-dictionary", &compDictObj },
{ "-level", &levelObj },
{ NULL, NULL }
static const OptDescriptor compressionOpts[] = {
{ "-dictionary", OPT_COMPRESSION_DICTIONARY },
{ "-level", OPT_COMPRESSION_LEVEL },
{ NULL, OPT_END }
};
const OptDescriptor gzipOpts[] = {
{ "-header", &gzipHeaderObj },
{ "-level", &levelObj },
{ NULL, NULL }
static const OptDescriptor gzipOpts[] = {
{ "-header", OPT_GZIP_HEADER },
{ "-level", OPT_COMPRESSION_LEVEL },
{ NULL, OPT_END }
};
const OptDescriptor expansionOpts[] = {
{ "-dictionary", &compDictObj },
{ NULL, NULL }
static const OptDescriptor expansionOpts[] = {
{ "-dictionary", OPT_COMPRESSION_DICTIONARY },
{ NULL, OPT_END }
};
const OptDescriptor gunzipOpts[] = {
{ NULL, NULL }
static const OptDescriptor gunzipOpts[] = {
{ NULL, OPT_END }
};
const OptDescriptor *desc = NULL;
Tcl_ZlibStream zh;
@@ -2262,13 +2256,7 @@ ZlibStreamSubcmd(
sizeof(OptDescriptor), "option", 0, &option) != TCL_OK) {
return TCL_ERROR;
}
*desc[option].valueVar = objv[i+1];
/*
* Drop the cache on the option name; table address not constant.
*/
TclFreeIntRep(objv[i]);
obj[desc[option].offset] = objv[i+1];
}
/*
@@ -2300,6 +2288,9 @@ ZlibStreamSubcmd(
}
Tcl_SetObjResult(interp, Tcl_ZlibStreamGetCommandName(zh));
return TCL_OK;
#undef compDictObj
#undef gzipHeaderObj
#undef levelObj
}
/*
@@ -3120,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;
@@ -3874,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.
@@ -3900,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;
}
@@ -3966,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;
}
@@ -3979,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;
}
+21 -13
View File
@@ -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 {} {}]
}
}
}
}
+49 -38
View File
@@ -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.5
package provide http 2.8.7
namespace eval http {
# Allow resourcing to not clobber existing data
@@ -394,13 +394,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
@@ -437,7 +440,7 @@ proc http::geturl {url args} {
)
(?: : (\d+) )? # <port part of authority>
)?
( / [^\#]*)? # <path> (including query)
( [/\?] [^\#]*)? # <path> (including query)
(?: \# (.*) )? # <fragment>
$
}
@@ -481,6 +484,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)
^
@@ -537,11 +546,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
@@ -597,10 +605,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]} {
@@ -616,13 +629,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)
@@ -753,35 +782,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:
@@ -865,7 +876,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"
@@ -873,10 +884,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
}
@@ -981,7 +992,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
}
@@ -1379,7 +1390,7 @@ proc http::mapReply {string} {
}
set converted [string map $formMap $string]
if {[string match "*\[\u0100-\uffff\]*" $converted]} {
regexp {[\u0100-\uffff]} $converted badChar
regexp "\[\u0100-\uffff\]" $converted badChar
# Return this error message for maximum compatability... :^/
return -code error \
"can't read \"formMap($badChar)\": no such element in array"

Some files were not shown because too many files have changed in this diff Show More