Compare commits

...
377 Commits
Author SHA1 Message Date
mig cd0bf3e350 still no good 2013-01-07 18:34:07 +00:00
mig 7754effa64 merge trunk 2013-01-07 13:24:38 +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
mig 524556581a CRASH - possibly full of mental typos 2013-01-07 07:28:45 +00:00
mig c9152240b9 move TCL_EVAL_REDIRECT from iPtr->evalFlags (tclInt.h) to flags passed to the eval functions (tcl.h) 2013-01-07 04:21:38 +00:00
mig d6ec1e9bfc more abstraction 2013-01-07 03:51:48 +00:00
mig b49ab44beb reenable compiled tailcall 2013-01-07 02:54:12 +00:00
mig a5d25d127e ... tmp 2013-01-07 01:55:14 +00:00
mig d22d1ef546 partial work towards a new tailcall mechanism 2013-01-07 00:45:28 +00:00
mig 952dfe7d9a towards an nre stack (instead of linked list) 2013-01-06 21:52:47 +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
mig bc33fd2059 merge trunk 2013-01-05 16:58:09 +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 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
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 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 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
mig a8c55de8fc merge trunk: get fix for test error under -DPURIFY 2012-12-09 12:08:03 +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
mig cebb11e97e merge trunk: get fix for test error under -DPURIFY 2012-12-08 17:20:43 +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
mig 7442eb42a1 New branch for exploring mods to nre's guts 2012-12-06 15:33:33 +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 7e68d373c1 very minor style tweaks 2012-11-20 12:04:51 +00:00
dkf 00451a175e merge trunk 2012-11-19 22:23:08 +00:00
dkf 6e2667d4d2 merge trunk 2012-11-19 22:10:10 +00:00
dkf 2ab23f6186 [Bug 3588366]: Corrected implementation of bounds restriction for end-indexed
compiled [string range]. Thanks to Emiliano Gavilan for diagnosis and fix.
2012-11-19 22:08:35 +00:00
dgp b670d49ae2 merge trunk 2012-11-19 17:30:33 +00:00
dgp 858c24761a 3587651 Fix [info functions] and Tcl_ListMathFuncs(). 2012-11-16 16:19:54 +00:00
dgp 70e9e19b64 3587651 Fix Tcl_ListMathFuncs() by turning it into a call to [info functions] 2012-11-16 16:11:29 +00:00
dgp cbfb51846d 3587651 fix [info functions] (Re-implementation in Tcl) 2012-11-16 15:35:22 +00:00
dgp 91d791cd85 merge trunk 2012-11-16 12:52:39 +00:00
jan.nijtmans adb756a95a A few unneeded internal CONST/CONST86's 2012-11-16 11:41:45 +00:00
jan.nijtmans 491f1691e5 Doc fix in TCL_MEM_DEBUG.3 2012-11-16 10:22:00 +00:00
jan.nijtmans a24ce60075 Doc fix in TCL_MEM_DEBUG.3 2012-11-16 10:21:07 +00:00
jan.nijtmans 134609fd57 Fix msgcat.test (in case a higher msgcat version is encountered, which is not included with Tcl 8.4)
<p>Doc fix in TCL_MEM_DEBUG.3
2012-11-16 10:16:18 +00:00
jan.nijtmans f7a0d6fdbe Let all test-cases which require Thread, at least require Thread 2.7 2012-11-16 09:38:38 +00:00
jan.nijtmans b93728a301 Don't use deprecated function 2012-11-16 08:35:30 +00:00
dgp c8318a69ff Contributed patch from Andy Goth. 2012-11-15 20:25:01 +00:00
dgp 41ace1ce41 More complete purge of things only present for supporting long-dead Mac 9 systems. 2012-11-15 17:55:25 +00:00
jan.nijtmans 4c439c45ea Fix bug in genStubs.tcl: If the macosx section doesn't contain any macosx-specific entries, no section at all is created 2012-11-15 15:04:08 +00:00
jan.nijtmans 5b9c4d9393 Fix bug in genStubs.tcl: If the macosx section doesn't contain any macosx-specific entries, no section at all is created 2012-11-15 15:02:35 +00:00
jan.nijtmans 212fc8e012 Fix bug in genStubs.tcl: If the macosx section doesn't contain any macosx-specific entries, no section at all is created
<p>revert previous workaround in tclInt.decls
2012-11-15 15:00:14 +00:00
jan.nijtmans a47366b842 add missing macosx sections 2012-11-15 14:33:35 +00:00
jan.nijtmans 1892e61aa6 Simplification: don't declare struct types that are never used. 2012-11-15 11:48:05 +00:00
jan.nijtmans daf66f3418 merge-mark 2012-11-15 10:40:48 +00:00
jan.nijtmans e1adc46245 Fix 2 failing tests on Windows 7. Fix backported from Tcl 8.6 2012-11-15 10:33:35 +00:00
jan.nijtmans 192c0b4b69 merge-mark 2012-11-15 09:10:41 +00:00
jan.nijtmans 0119f508e2 Remove all the long dead mac entries in tcl*.decls files
<p>backport genStubs::forAllStubs function, to generate dummy entries for some MAC_TCL entries
<p>re-generate all tcl*Decls.h files.
2012-11-15 08:23:35 +00:00
dgp e2c63e97bc Remove all the long dead mac/* files (for Mac OS9 !?!). 2012-11-15 04:16:56 +00:00
dgp 275cdefdd7 merge trunk: 2012-11-15 01:54:58 +00:00
dkf 4a2c3d9ab9 unbreak trunk; fix some warnings 2012-11-15 01:44:12 +00:00
jan.nijtmans 59c308ebf0 IMPLEMENTATION OF TIP#416: New Options for 'load': -global and -lazy 2012-11-15 00:20:57 +00:00
dgp 920dfb2f56 3587242 Missing Tcl_MutexUnlock() call made [testasync create] block. 2012-11-14 22:05:21 +00:00
dgp f14b389544 merge trunk 2012-11-14 16:57:23 +00:00
dkf 0aeb86cee1 Fix botched patch 2012-11-14 16:30:27 +00:00
dkf 04b42c6d46 merge mark 2012-11-14 14:35:33 +00:00
dkf 762f642867 * unix/tclUnixPipe.c (DefaultTempDir): [Bug 2933003]: Allow overriding
of the back-stop default temporary file location at compile time by
	setting the TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing
	the directory name (defaults to "/tmp" as that is the most common
	default).
2012-11-14 14:33:08 +00:00
dkf e770d85db6 Backport from Tcl 8.6.
* unix/tclUnixPipe.c (DefaultTempDir): [Bug 2933003]: Allow overriding
	of the back-stop default temporary file location at compile time by
	setting the TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing
	the directory name (defaults to "/tmp" as that is the most common
	default).
2012-11-14 14:29:29 +00:00
dkf 2e074de52a * unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
out all the code to do temporary file creation so that it is possible
	to make it correct in one place. Allow overriding of the back-stop
	default temporary file location at compile time by setting the
	TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
	name (defaults to "/tmp" as that is the most common default).
2012-11-14 13:01:46 +00:00
jan.nijtmans 73cbb5ef6f merge trunk 2012-11-14 09:58:36 +00:00
jan.nijtmans 2b18d7d019 Workaround for mingw versions which don't provide _fpcontrol in float.h 2012-11-14 09:12:17 +00:00
jan.nijtmans 63c50fda84 Workaround for mingw versions which don't provide _fpcontrol in float.h 2012-11-14 09:11:21 +00:00
jan.nijtmans a61f0f3aa3 Workaround for mingw versions which don't provide _fpcontrol in float.h 2012-11-14 09:07:32 +00:00
dgp b8076815be merge trunk 2012-11-13 21:31:30 +00:00
dgp cb3e2cac34 360894 Threads inherit floating point config from their creator thread 2012-11-13 21:23:17 +00:00
dgp a8ea141350 360894 Threads inherit floating point config from their creator thread. 2012-11-13 21:22:21 +00:00
dgp 3c4956ece0 360894 Threads inherit floating point config from their creator thread 2012-11-13 21:16:13 +00:00
dgp cee0989147 merge 8.4 2012-11-13 21:03:28 +00:00
Joe Mistachkin 20058bf813 also search for the library directory (init.tcl, encodings, etc) relative to the build directory associated with the source checkout. 2012-11-13 20:03:42 +00:00
Joe Mistachkin c3bb46df16 also search for the library directory (init.tcl, encodings, etc) relative to the build directory associated with the source checkout. 2012-11-13 19:59:14 +00:00
dgp 1f0fc6d0b1 merge mark 2012-11-12 23:33:01 +00:00
dgp 071105233b merge release to 8.5 2012-11-12 23:22:56 +00:00
jan.nijtmans fcba3b601b merge trunk.
<p>doc fix
2012-11-12 08:01:53 +00:00
jan.nijtmans 5e8aae6bdc style fix 2012-11-12 07:53:34 +00:00
jan.nijtmans 2354c488dc merge trunk 2012-11-12 07:44:21 +00:00
mig c06ccc92c0 added forgotten Changelog entry 2012-11-10 19:24:23 +00:00
mig c23935f0c4 re-enable bcc-tailcall, after fixing an infinite loop in the TCL_COMPILE_DEBUG mode 2012-11-10 17:08:33 +00:00
jan.nijtmans a271a46238 merge trunk 2012-11-09 20:11:35 +00:00
dgp 1ff71889ea ChangeLog release mark 2012-11-09 15:12:01 +00:00
dgp bcd546207d merge mark 2012-11-09 13:53:39 +00:00
jan.nijtmans afe5dfc938 Flag USE_TCLOO_STUBS is not necessary any more for extensions: Stubs are the only way to access TclOO, so it is implied. 2012-11-09 12:11:04 +00:00
dgp 893f9c7cc6 dup test name 2012-11-08 16:22:35 +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 1c5b833a43 Updated the language of the documentation so that "object" refers to an OO
concept throughout, and a Tcl_Obj is called a "value" (which is what it is).
2012-11-08 15:21:29 +00:00
dgp 5f3314ac7b Missing bits of the msgcat 1.4 -> 1.5 bump. 2012-11-08 13:50:06 +00:00
dgp 4ffdb51e34 Pull msgcat fixes over the main dev branch 2012-11-08 13:33:28 +00:00
dgp 23cac7b42c Revert msgcat requirement bump in the "clock" module. Should be no need for it. 2012-11-08 13:31:57 +00:00
jan.nijtmans 24650f8e9d Remove another reference to tcl.wse.in 2012-11-08 13:06:55 +00:00
dkf d8ae9915dd merge updates to make HTML generation better 2012-11-08 10:16:28 +00:00
dkf 474d2cb11a Added tooltip generation to contents and keywords pages. 2012-11-08 10:14:35 +00:00
oehhar 57c33f7587 changed msgcat version from 1.4 to 1.5 in doc/msgcat.n, tests/clock.test, library/clock.tcl, win/makefile.bc and tools/tcl.wse.in 2012-11-08 09:15:55 +00:00
dkf 498d315304 Make HTML generator more resilient against problems when generating docs for
older versions of Tcl/Tk.
2012-11-08 08:22:13 +00:00
dgp a26191b7b2 tzdata update 2012-11-07 20:56:34 +00:00
Kevin B Kenny 051bf96db1 Import tzdata2012i 2012-11-07 20:53:14 +00:00
Kevin B Kenny 9aab4c1bac Import tzdata2012i 2012-11-07 20:49:51 +00:00
dgp 299d4abd03 Remove files and references for long outdated Wise Installer. 2012-11-07 20:41:15 +00:00
dgp 5b64a7d24c update changes 2012-11-07 19:11:56 +00:00
dgp efdc17a4d5 merge 8.5 2012-11-07 17:36:51 +00:00
dgp 626e22c982 merge mark 2012-11-07 17:30:20 +00:00
dgp 842e894ac5 3574493 Avoid hanging on exit due to use of synchronization calls in
routines called by DllMain().
2012-11-07 17:26:48 +00:00
dgp 9123f8f93e 3574493 Avoid hanging on exit due to use of synchronization calls in
routines called by DllMain().
2012-11-07 17:24:12 +00:00
jan.nijtmans 20ad704b92 merge-mark 2012-11-07 15:29:52 +00:00
jan.nijtmans ba7ee97d3a needed for complation with mingw-w64 (autoconf still to be run) 2012-11-07 15:28:22 +00:00
dkf f679fe87ab Added package descriptor file to allow for easier configuration of integration of contributed packages in HTML documentation. 2012-11-07 14:41:43 +00:00
jan.nijtmans 3ba55d4c91 merge trunk 2012-11-07 14:27:30 +00:00
dkf 53690d2607 Minor change: another formatting improvement 2012-11-07 13:18:20 +00:00
dkf ad3ee62cd3 Minor change: Formatting fix 2012-11-07 13:14:37 +00:00
jan.nijtmans 55d5fb55a2 just fix some characters that fossil cannot handle well 2012-11-07 10:36:43 +00:00
jan.nijtmans 335ddd20ca just fix some characters that fossil cannot handle well 2012-11-07 10:32:54 +00:00
jan.nijtmans ca3ab36dfd Finish the TIP #416 implementation as specified (#define's were still missing). Added warning to "load" documentation. Added test case for using -global without specifying filename. 2012-11-07 08:03:10 +00:00
dkf 96e7bb4e24 merge trunk 2012-11-06 21:16:47 +00:00
dgp 5c0961e758 merge 8.5 2012-11-06 16:28:05 +00:00
dgp 109f50dfe1 Complete bump to http 2.8.5 2012-11-06 16:27:16 +00:00
dgp 398787d859 changes update 2012-11-06 16:20:27 +00:00
dgp 85167c88b6 complete bump to http 2.7.10 2012-11-06 16:14:54 +00:00
dkf b2e0789f6b [Bug 3581754]: Ensure that http -command callbacks are done at most once. 2012-11-06 13:16:03 +00:00
dkf 9b474d56b9 [Bug 3581754]: Ensure that http -command callbacks are done at most once. 2012-11-06 10:40:09 +00:00
dkf ec58b631ce merge trunk: INST_TAILCALL has bug 2012-11-05 21:47:12 +00:00
dgp e55f7c6612 make dist 2012-11-05 21:03:34 +00:00
dgp 8a8dee7bde merge 8.5 2012-11-05 20:29:33 +00:00
dgp 2bd81c6785 merge changes 2012-11-05 20:27:59 +00:00
dgp e219c6140a date fixes 2012-11-05 20:27:28 +00:00
dgp f6be9e19c2 Update changes for 8.5.13. 2012-11-05 20:19:55 +00:00
dgp 688210c291 autoconf-2.59 2012-11-05 18:42:06 +00:00
dgp 83d0e64e99 Release branch for Tcl 8.5.13. 2012-11-05 18:38:37 +00:00
dgp a3bc9d0e44 Disable bytecompile of [tailcall] until it gets some repair. As is, it
hopelessly bogs down debug-enabled testing, and make many tests fail.
2012-11-05 16:57:28 +00:00
dkf 49dd27a4ea merge trunk 2012-11-05 15:17:26 +00:00
dkf b9c17fff37 Added bytecode compilation of many Tcl commands, merged from development branch. 2012-11-05 14:55:14 +00:00
jan.nijtmans c74d12c2e0 TIP #413 2012-11-05 14:42:50 +00:00
dkf ac3ebfbd49 Added compilation of [array exists], [array set] and [array unset]. Fixed a whole bunch of issues with opcode issuing that were causing problems with stack depth calculations. 2012-11-05 14:34:36 +00:00
jan.nijtmans 02dd785b16 fix Tcl_FSFileAttrStrings doc 2012-11-04 16:57:43 +00:00
dkf 9ef6a75daf Added compilation of [string last] and improved the compilation of [string range]. This in turn enables compilation of [namespace qualifiers] and [namespace tail] (also done). 2012-11-03 20:21:13 +00:00
dkf f17426d59e Added compilation of [info object isa object] (i.e., object verification). 2012-11-03 12:48:08 +00:00
dkf acd9d78458 Added more TclOO introspection bytecodes ([info object class], [info object namespace]). Also moved TclOO-in-8.6 to using the main Tcl internal ensemble builder. 2012-11-02 18:13:20 +00:00
dkf d82d84f004 Added compilation of [tailcall]. Not a particularly efficient compilation though; it does not detect tailcall-of-self as a special case. 2012-11-01 18:06:09 +00:00
dkf 5c68347747 Added compilation of [dict create] and [dict merge]. 2012-11-01 16:47:41 +00:00
jan.nijtmans eeb982f501 Dde version number to 1.4.0, ready for Tcl 8.6.0rc1 2012-10-31 13:09:23 +00:00
dkf ecec3a1a0b Added [dict exists] compilation; implementation is 95% shared with [dict get]. 2012-10-30 22:16:35 +00:00
dkf 040b7a730e Some corrections and performance tweaks 2012-10-30 20:59:34 +00:00
dkf ee5f41d141 Compilation of [string first] and [string range] (with constant indices). 2012-10-30 18:20:28 +00:00
dkf 71560be819 Added compilation of [regsub] (in the simplest, most restricted case). 2012-10-30 12:39:40 +00:00
dkf 05d8b59183 Added compilation of simplest practical case of [string map]. 2012-10-29 21:35:49 +00:00
dkf bedb57a468 Minor: correct a comment 2012-10-29 17:16:55 +00:00
dkf 0d71be4a7e Compiler for some of the simpler cases of [format]. 2012-10-29 17:15:00 +00:00
dkf d25cf46468 merge trunk 2012-10-29 12:03:51 +00:00
dkf e1019374e0 Merge corrected [yield] compilation. Many thanks to Miguel Sofer for help. 2012-10-29 12:03:03 +00:00
dkf 1c889c0352 Compilation of [info commands] in the case of a fully-qualified literal name. 2012-10-29 11:02:45 +00:00
mig f7bae6ac60 fix INST_YIELD so that it works 2012-10-28 18:58:20 +00:00
dkf 8122cb706d Added [self namespace] to bytecoded command set. 2012-10-28 16:01:31 +00:00
dkf 41128611bf Working towards a BCCed [yield]; this doesn't work right now. 2012-10-26 13:13:27 +00:00
dkf 13ba95be10 Compile [namespace which -command]; big performance saving in some contexts. 2012-10-26 07:32:47 +00:00
dkf 734725f73e Added compilation of [namespace code] (except for gnarly edge cases). 2012-10-25 09:56:35 +00:00
jan.nijtmans c705d5b937 syntax improvement: expect options before the filename
<p>start at documentation
2012-10-24 21:22:30 +00:00
jan.nijtmans 225c3d3e5f experimental implementation of FRQ-3579001 2012-10-24 13:08:34 +00:00
jan.nijtmans 706e42d83b make tclTest.c compilable against version 2 filesystems 2012-10-24 11:28:33 +00:00
jan.nijtmans 8dfd4b7f02 Add dummy 0 parameter (unused flags) to internal Tcl_FSLoadFileProc call, for upwards compatibility with version 2 filesystems 2012-10-24 11:21:31 +00:00
jan.nijtmans ee55e87c47 Add dummy 0 parameter (unused flags) to internal Tcl_FSLoadFileProc call, for upwards compatibility with version 2 filesystems 2012-10-24 11:14:51 +00:00
dkf d764a87552 merge trunk 2012-10-24 09:52:50 +00:00
dkf 129d93bc40 Added compilation of [dict unset]; the bytecode needed already existed anyway. 2012-10-24 09:50:09 +00:00
dkf 247a043a05 minor correction to index line 2012-10-24 08:19:11 +00:00
jan.nijtmans db601d75b9 unbreak Mac OSX build 2012-10-23 22:07:02 +00:00
jan.nijtmans 8a9731657e merge trunk 2012-10-23 21:52:56 +00:00
jan.nijtmans 966e9c3477 Add "flags" parameter from Tcl_LoadFile to to various internal functions, so these flags are available through the whole filesystem for (future) internal use 2012-10-23 21:50:49 +00:00
jan.nijtmans 7927604b94 Remove unused TclpLoadFile function. 2012-10-23 21:45:51 +00:00
dkf a584e5f052 yet another small introspector: [self] 2012-10-19 14:17:18 +00:00
dkf 54e225f382 merge trunk 2012-10-19 08:48:40 +00:00
mig e5c614fc2d * generic/tclBasic.c (TclNRCoroutineObjCmd): insure that numlevels
are properly set, fix bug discovered by dkf and reported at http://code.activestate.com/lists/tcl-core/12213/
2012-10-18 17:38:19 +00:00
dkf aaac3316a4 merge trunk 2012-10-17 13:52:24 +00:00
jan.nijtmans 0af0c0e973 Remove two characters, zero width non-joiner (U+200c) and zero width joiner (U+200d),
which were finally left out of TIP #413
2012-10-16 14:25:18 +00:00
jan.nijtmans 532e6f0c8e doc fix 2012-10-16 13:58:16 +00:00
dkf 6e458bffe0 merge trunk 2012-10-16 13:44:04 +00:00
dkf 6c99b4f545 Implementation of TIP #405. 2012-10-16 13:14:28 +00:00
dkf 7e90ca9d19 merge trunk 2012-10-16 13:06:35 +00:00
dkf 37f4435517 Implementation of TIP #400. 2012-10-16 13:04:13 +00:00
dkf 28f6f6deb5 merge trunk 2012-10-16 12:50:31 +00:00
jan.nijtmans 8eb29f16f2 Bug 3576509: Better fix, which helps for all Tcl_DictObjGet() calls in Tcl's source code. 2012-10-14 19:02:37 +00:00
jan.nijtmans 495bfd5d18 Bug 357650: Better fix, which helps for all Tcl_DictObjGet() calls in Tcl's source code. 2012-10-14 19:00:39 +00:00
jan.nijtmans c02571fab0 Bug 3576509: tcl::Bgerror crashes with invalid arguments 2012-10-13 20:29:09 +00:00
jan.nijtmans e4c33dab06 Bug 3576509: tcl::Bgerror crashes with invalid arguments 2012-10-13 20:26:00 +00:00
jan.nijtmans 43a3d8d594 and remove the two characters from string trim as well 2012-10-09 01:55:04 +00:00
jan.nijtmans 40ea3f744a merge trunk
<p>Dont include U+0082 and U+0083 in the Tcl space set
2012-10-09 01:48:31 +00:00
jan.nijtmans 2481948f74 [Bug 2459774] win/tcl/Makefile.in not compatible with msys 0.8. 2012-10-06 06:13:09 +00:00
dgp 23612cace5 3574819 Increase test robustness by creating files in fresh directory to
reduce trouble with any existing files in an existing directory.
2012-10-05 16:37:27 +00:00
dkf b38a57ebda merge trunk 2012-10-04 08:25:52 +00:00
dkf 9b4651ad57 clean up some of the code to remove warnings and uselessly-settable things 2012-10-04 08:24:05 +00:00
dgp 43da7a5b40 merge 8.4 2012-10-03 15:23:16 +00:00
dgp 56d71ce11b When checking for std channels being closed, compare the channel state,
not the channel itself so that stacked channels do not cause trouble.
2012-10-03 15:18:32 +00:00
dkf f7baa52775 documented new C API; corrected type signature of no-zlib fallback function 2012-10-03 09:38:50 +00:00
dkf b488ca3be7 merge trunk 2012-10-03 08:11:48 +00:00
jan.nijtmans 0c7b5c9b40 update documentation 2012-09-26 12:32:56 +00:00
jan.nijtmans 161982db4e tip 318 update 2012-09-23 16:48:49 +00:00
Joe Mistachkin 96b22f2bf9 Make compilation of the fp control changes possible with MinGW. 2012-09-13 20:03:01 +00:00
Joe Mistachkin 3bb8b9504c Free the WinThread structure before running the original thread procedure. 2012-09-13 18:37:55 +00:00
Joe Mistachkin 2aaae6b3fe Initial work on SF FRQ #3567063. 2012-09-13 18:30:41 +00:00
dkf cbe9080dcf tinkering with the documentation 2012-08-13 10:05:16 +00:00
dkf b63fcbf8cf merge trunk 2012-08-11 21:24:22 +00:00
dkf a8d394eeaf merge trunk 2012-08-04 07:47:22 +00:00
dkf 66adad9c26 merge trunk 2012-07-04 07:09:40 +00:00
dkf 025299dede merge trunk 2012-06-25 09:23:23 +00:00
dkf ee7e6c078d add configurability of readahead limit 2012-06-24 15:15:36 +00:00
dkf f0648d0658 merge trunk 2012-06-22 08:17:14 +00:00
dkf d751107a26 Documenting the stream command options better. 2012-06-22 07:52:24 +00:00
dkf d6600f4d5a Start to split apart the stream command implementation for easier maintenance. 2012-06-22 07:51:38 +00:00
dkf c9e3b7680f merge trunk 2012-06-16 17:20:06 +00:00
dkf e8273026f8 verify zlib package presence and version 2012-06-11 00:07:52 +00:00
dkf a3e13bdce2 merge trunk 2012-06-09 23:18:24 +00:00
dkf 1434262700 more cross-testing of dictionary-powered compression; describe package configuration 2012-06-09 23:15:51 +00:00
dkf f0047f95e1 tidy up, fix test 2012-06-09 17:52:05 +00:00
dkf c0050dd5cd compressing transforms now work with dictionaries, even if raw 2012-06-07 07:12:47 +00:00
dkf 5d1214f529 merge trunk 2012-06-06 14:49:53 +00:00
dkf 4d5127aca4 making the -dictionary option work with streams 2012-06-06 10:34:12 +00:00
dkf b49f1ffb1b more tests, more failures, more docs 2012-06-06 09:30:31 +00:00
dkf bba49ba498 more test tinkering 2012-06-05 16:50:52 +00:00
dkf 2f46625fe9 fix broken tests 2012-06-05 16:36:11 +00:00
dkf 0a40e59f2c better test that dictionaries work 2012-06-05 16:25:29 +00:00
dkf e148310a7b merge trunk 2012-06-05 16:05:36 +00:00
dkf 2b24dada59 merge trunk 2012-05-31 08:31:58 +00:00
dkf 494a614936 merge trunk 2012-05-24 10:05:50 +00:00
dkf c8e8e61fcc typofix 2012-05-18 00:01:58 +00:00
dkf 937f040a7f merge trunk 2012-05-17 17:26:34 +00:00
dkf 4a61476888 merge trunk 2012-05-13 11:04:44 +00:00
dkf 720fc8cc34 updated C API to be more focused on supporting just some operations 2012-05-10 09:22:48 +00:00
dkf 7b864a3d91 merge trunk 2012-05-07 09:29:30 +00:00
dkf aae531d780 start writing some documentation 2012-05-05 14:29:48 +00:00
dkf f2e45587d3 Add ability to get gzip header out of streaming zlib access 2012-05-04 21:18:59 +00:00
dkf 25cd849a61 merge trunk 2012-05-04 10:53:36 +00:00
dkf 884ea95c53 first actual test of doing something with a compression dictionary 2012-05-01 08:29:11 +00:00
dkf 4cc68c3c06 merge trunk 2012-05-01 04:51:49 +00:00
dkf 4443d92ca2 merge trunk 2012-04-29 07:23:07 +00:00
dkf 34b81fea59 Differentiate what options may be set by format type. 2012-04-29 07:18:30 +00:00
dkf f0e80d448f merge trunk 2012-04-26 13:52:58 +00:00
dkf 2fffc3d3e9 merge trunk 2012-04-21 09:05:26 +00:00
dkf bd225549d9 another bit of fconfigure guts 2012-04-20 10:22:03 +00:00
dkf bfa17c4303 merge trunk 2012-04-20 09:45:18 +00:00
dkf 1c974eb626 merge trunk 2012-04-17 17:10:39 +00:00
dkf b474131fd6 merge trunk 2012-04-17 07:46:19 +00:00
dkf dab3544492 Working towards the channel transform config options. 2012-04-17 07:42:58 +00:00
dkf 56756de072 Refactor some [zlib] subcommands into their own functions 2012-04-15 21:05:43 +00:00
dkf 03a345e867 merge trunk 2012-04-15 10:12:18 +00:00
dkf 3027444baf merge trunk 2012-04-14 06:45:27 +00:00
dkf ad27974fb0 towards dictionary setting on transforms 2012-04-11 07:16:45 +00:00
dkf 794c4bc874 merge trunk 2012-04-10 08:13:40 +00:00
dkf 129b4229f0 Argument parsing update 2012-04-10 07:29:38 +00:00
dkf 95eb3ddcaa Another few bits of zlib stream core hacking 2012-04-08 17:16:43 +00:00
dkf aa40191938 Another bit more 2012-04-07 17:41:10 +00:00
dkf 0a41daed74 merge trunk 2012-04-05 16:29:48 +00:00
dkf a4c60c3914 Another step on the road to implementation. 2012-03-31 15:16:45 +00:00
dkf 354910b5c5 D'oh! 2012-03-31 14:06:43 +00:00
dkf d9cfa9ca3b Start of implementation of TIP 400: zlib improvements 2012-03-31 13:48:11 +00:00
dkf e021bca54d merge trunk 2012-03-28 13:32:37 +00:00
dkf 17e289ab9d merge from trunk 2012-03-08 09:01:11 +00:00
dkf 4683dce51c Compilation of misc info sometimes used in high-performance code. 2012-03-04 16:52:01 +00:00
194 changed files with 8412 additions and 6191 deletions
+349 -22
View File
@@ -1,3 +1,330 @@
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: Stop leaking allocated space when objifying a
zero-length DString. [Bug 3598150] 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
implementation of bounds restriction for end-indexed compiled [string
range]. Thanks to Emiliano Gavilan for diagnosis and fix.
2012-11-15 Jan Nijtmans <nijtmans@users.sf.net>
IMPLEMENTATION OF TIP#416
New Options for 'load': -global and -lazy
* generic/tcl.h:
* generic/tclLoad.c
* unix/tclLoadDl.c
* unix/tclLoadDyld.c
* tests/load.test
* doc/Load.3
* doc/load.n
2012-11-14 Donal K. Fellows <dkf@users.sf.net>
* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
out all the code to do temporary file creation so that it is possible
to make it correct in one place. Allow overriding of the back-stop
default temporary file location at compile time by setting the
TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
name (defaults to "/tmp" as that is the most common default).
2012-11-13 Joe Mistachkin <joe@mistachkin.com>
* win/tclWinInit.c: also search for the library directory (init.tcl,
encodings, etc) relative to the build directory associated with the
source checkout.
2012-11-10 Miguel Sofer <msofer@users.sf.net>
* generic/tclBasic.c: re-enable bcc-tailcall, after fixing an
* generic/tclExecute.c: infinite loop in the TCL_COMPILE_DEBUG mode
2012-11-07 Kevin B. Kenny <kennykb@acm.org>
* library/tzdata/Africa/Casablanca:
* library/tzdata/America/Araguaina:
* library/tzdata/America/Bahia:
* library/tzdata/America/Havana:
* library/tzdata/Asia/Amman:
* library/tzdata/Asia/Gaza:
* library/tzdata/Asia/Hebron:
* library/tzdata/Asia/Jerusalem:
* library/tzdata/Pacific/Apia:
* library/tzdata/Pacific/Fakaofo:
* library/tzdata/Pacific/Fiji: Import tzdata2012i.
2012-11-06 Donal K. Fellows <dkf@users.sf.net>
* library/http/http.tcl (http::Finish): [Bug 3581754]: Ensure that
callbacks are done at most once to prevent problems with timeouts on a
keep-alive connection (combined with reentrant http package use)
causing excessive stack growth. Not a fix for the underlying problem,
but ensures that pain will be mostly kept away from users.
Bump http package to 2.8.5.
2012-11-05 Donal K. Fellows <dkf@users.sf.net>
Added bytecode compilation of many Tcl commands. Some of these are
total compilations and some are only partial (i.e., only compile in
some cases). The (sub-)commands affected are:
* array: exists, set, unset
* dict: create, exists, merge
* format: (simple cases only)
* info: commands, coroutine, level, object
* info object: class, isa object, namespace
* namespace: current, code, qualifiers, tail, which
* regsub: (only cases convertable to simple [string map])
* self: (only no-argument and [self object] cases)
* string: first, last, map, range
* tailcall:
* yield:
[This was work originally done on the 'dkf-compile-misc-info' branch.]
2012-11-05 Jan Nijtmans <nijtmans@users.sf.net>
IMPLEMENTATION OF TIP#413
Align the [string trim] and [string is space] commands, such that
[string trim] by default trims all characters for which [string is
space] returns 1, augmented with the NUL character.
* generic/tclUtf.c: Add NEL, BOM and two more characters to [string is
space]
* generic/tclCmdMZ.c: Modify [string trim] for Unicode modifications.
* generic/regc_locale.c: Regexp engine must match [string is space]
* doc/string.n
* tests/string.test
***POTENTIAL INCOMPATIBILITY***
Code that relied on characters not previously trimmed being not
removed will notice a difference; it is believed that this is rare,
but a workaround to get the behavior in Tcl 8.5 is to use " \t\n\r" as
an explicit trim set.
2012-10-31 Jan Nijtmans <nijtmans@users.sf.net>
* win/Makefile.in: Dde version number to 1.4.0, ready for Tcl 8.6.0rc1
* win/makefile.vc
* win/tclWinDde.c
* library/dde/pkgIndex.tcl
* tests/winDde.test
2012-10-24 Donal K. Fellows <dkf@users.sf.net>
* generic/tclCompCmds.c (TclCompileDictUnsetCmd): Added compilation of
the [dict unset] command (for scalar var in LVT only).
2012-10-23 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclInt.h: Add "flags" parameter from Tcl_LoadFile to
* generic/tclIOUtil.c: to various internal functions, so these
* generic/tclLoadNone.c: flags are available through the whole
* unix/tclLoad*.c: filesystem for (future) internal use.
* win/tclWinLoad.c:
2012-10-17 Miguel Sofer <msofer@users.sf.net>
* generic/tclBasic.c (TclNRCoroutineObjCmd): insure that numlevels
are properly set, fix bug discovered by dkf and reported at
http://code.activestate.com/lists/tcl-core/12213/
2012-10-16 Donal K. Fellows <dkf@users.sf.net>
IMPLEMENTATION OF TIP#405
New commands for applying a transformation to the elements of a list
to produce another list (the [lmap] command) and to the mappings of a
dictionary to produce another dictionary (the [dict map] command). In
both cases, a [continue] will cause the skipping of an element/pair,
and a [break] will terminate the construction early and successfully.
* generic/tclCmdAH.c (Tcl_LmapObjCmd, TclNRLmapCmd): Implementation of
the new [lmap] command, based on (and sharing much of) [foreach].
* generic/tclDictObj.c (DictMapNRCmd): Implementation of the new [dict
map] subcommand, based on (and sharing much of) [dict for].
* generic/tclCompCmds.c (TclCompileLmapCmd, TclCompileDictMapCmd):
Compilation engines for [lmap] and [dict map].
IMPLEMENTATION OF TIP#400
* generic/tclZlib.c: Allow the specification of a compression
dictionary (a binary blob used to seed the compression engine) in both
streams and channel transformations. Also some reorganization to allow
for getting gzip header dictionaries and controlling buffering levels
in channel transformations (allowing a trade-off between formal
correctness and speed).
(Tcl_ZlibStreamSetCompressionDictionary): New C API to allow setting
the compression dictionary without using a Tcl script.
2012-10-14 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclDictObj.c: [Bug 3576509]: ::tcl::Bgerror crashes with
* generic/tclEvent.c: invalid arguments. Better fix, which helps
for all Tcl_DictObjGet() calls in Tcl's source code.
2012-10-13 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclEvent.c: [Bug 3576509]: tcl::Bgerror crashes with invalid
arguments
2012-10-06 Jan Nijtmans <nijtmans@users.sf.net>
* win/Makefile.in: [Bug 2459774]: tcl/win/Makefile.in not compatible
with msys 0.8.
2012-10-03 Don Porter <dgp@users.sourceforge.net>
* generic/tclIO.c: When checking for std channels being closed,
@@ -6,27 +333,27 @@
2012-09-26 Reinhard Max <max@suse.de>
* generic/tclIOSock.c (TclCreateSocketAddress): Work around a bug
in getaddrinfo() on OSX that caused name resolution to fail for
[socket -server foo -myaddr localhost 0].
* generic/tclIOSock.c (TclCreateSocketAddress): Work around a bug in
getaddrinfo() on OSX that caused name resolution to fail for [socket
-server foo -myaddr localhost 0].
2012-09-20 Jan Nijtmans <nijtmans@users.sf.net>
* win/configure.in: New import libraries for zlib 1.2.7,
* win/configure: usable for all win32/win64 compilers
* compat/zlib/win32/zdll.lib
* compat/zlib/win64/zdll.lib
* win/configure.in: New import libraries for zlib 1.2.7, usable for
* win/configure: all win32/win64 compilers
* compat/zlib/win32/zdll.lib:
* compat/zlib/win64/zdll.lib:
* win/tclWinDde.c: [Frq 3527238]: Full unicode support
for dde. Dde version is now 1.4.0b2.
* win/tclWinDde.c: [FRQ 3527238]: Full unicode support for dde. Dde
version is now 1.4.0b2.
***POTENTIAL INCOMPATIBILITY***
2012-09-19 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tcl.h: make Tcl_Interp a fully opaque structure
if TCL_NO_DEPRECATED is set (TIP 330 and 336).
* win/nmakehlp.c: Let "nmakehlp -V" start searching digits
after the found match (suggested by Harald Oehlmann)
* generic/tcl.h: Make Tcl_Interp a fully opaque structure if
TCL_NO_DEPRECATED is set (TIP 330 and 336).
* win/nmakehlp.c: Let "nmakehlp -V" start searching digits after the
found match (suggested by Harald Oehlmann).
2012-09-07 Harald Oehlmann <oehhar@users.sf.net>
@@ -59,13 +386,13 @@
* win/tclWinPort.h: Remove wrapper macro for ntohs(): unnecessary,
because it doesn't require an initialized winsock_2 library. See:
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms740075%28v=vs.85%29.aspx>
* win/tclWinSock.c
* generic/tclStubInit.c
* win/tclWinSock.c:
* generic/tclStubInit.c:
2012-08-17 Jan Nijtmans <nijtmans@users.sf.net>
* win/nmakehlp.c: Add "-V<num>" option, in order to be able
to detect partial version numbers.
* win/nmakehlp.c: Add "-V<num>" option, in order to be able to detect
partial version numbers.
2012-08-15 Jan Nijtmans <nijtmans@users.sf.net>
@@ -79,11 +406,11 @@
2012-08-13 Jan Nijtmans <nijtmans@users.sf.net>
* compat/zlib/win64/zlib1.dll: Add 64-bit build of zlib1.dll, and use it
* compat/zlib/win64/zdll.lib: for the dynamic mingw-w64 build.
* win/Makefile.in
* win/configure.in
* win/configure
* compat/zlib/win64/zlib1.dll: Add 64-bit build of zlib1.dll, and use
* compat/zlib/win64/zdll.lib: it for the dynamic mingw-w64 build.
* win/Makefile.in:
* win/configure.in:
* win/configure:
2012-08-09 Reinhard Max <max@suse.de>
+2 -2
View File
@@ -746,7 +746,7 @@
* doc/trace.n: minor doc cleanup
2000-09-06 André Pönitz <poenitz@htwm.de>
2000-09-06 André Pönitz <poenitz@htwm.de>
* doc/*.n: added or changed "SEE ALSO:" section
@@ -1086,7 +1086,7 @@
* unix/tcl.m4 (SC_ENABLE_GCC): Don't set CC=gcc before running
AC_PROG_CC if CC is already set.
2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
* doc/lappend.n:
* doc/lindex.n:
+1 -1
View File
@@ -939,7 +939,7 @@
version of Tcl with Cygwin gcc. Users should compile with Mingw gcc
instead.
2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* generic/tclIO.c (ReadChars): Fixed [Bug 478856] reported by Stuart
Cassoff <stwo@users.sourceforge.net>. The bug caused loss of
+1 -1
View File
@@ -3284,7 +3284,7 @@
2003-01-10 Vince Darley <vincentdarley@users.sourceforge.net>
* generic/tclIOUtil.c:
* generic/tclIOUtil.c:
* win/tclWinInt.h:
* win/tclWinInit.c: fix to new WinTcl crash on exit with vfs,
introduced on 2002-12-06. Encodings must be cleaned up after the
+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.
+111 -64
View File
@@ -126,7 +126,7 @@ Tcl_Eval.
that came after version 3.3 was released.
40. 5/17/91 Changed tests to conform to Mary Ann May-Pumphrey's approach.
41. 5/23/91 Massive revision to Tcl parser to simplify the implementation
of string and floating-point support in expressions. Newlines inside
[] are now treated as command separators rather than word separators
@@ -260,7 +260,7 @@ argument (before file name), for consistency with other Tcl commands.
*** POTENTIAL INCOMPATIBILITY ***
72. 8/20/91 Changed format of information in $errorInfo variable:
comments such as
comments such as
("while" body line 1)
are now on separate lines from commands being executed.
*** POTENTIAL INCOMPATIBILITY ***
@@ -1192,7 +1192,7 @@ under some dynamic loading systems (e.g. SunOS 4.1 and Windows).
6/8/95 (feature change) Modified interface to Tcl_Main to pass in the
address of the application-specific initialization procedure.
Tcl_AppInit is no longer hardwired into Tcl_Main. This is needed
in order to make Tcl a shared library.
in order to make Tcl a shared library.
6/8/95 (feature change) Modified Makefile so that the installed versions
of tclsh and libtcl.a have version number in them (e.g. tclsh7.4 and
@@ -1616,7 +1616,7 @@ file name. Under Windows '95, this is incorrectly interpreted as a UNC
path. They delays came from the network timeouts needed to determine that
the file name was invalid. Tcl_TranslateFileName now suppresses duplicate
slashes that aren't at the beginning of the file name. (SS)
1/25/96 (bug fix) Changed exec and open to create children so they are
attached to the application's console if it exists. (SS)
@@ -2254,21 +2254,21 @@ version of Tcl. It's quite a bit faster than MetroWerk's version. (RJ)
8/26/96 (documentation update) Removed old change bars (for all changes
in Tcl 7.5 and earlier releases) from manual entries. (JO)
8/27/96 (enhancement) The exec and open commands behave better and work in
more situations under Windows NT and Windows 95. Documentation describes
8/27/96 (enhancement) The exec and open commands behave better and work in
more situations under Windows NT and Windows 95. Documentation describes
what is still lacking. (CS)
8/27/96 (enhancement) The Windows makefiles will now compile even if the
compiler is not in the path and/or the compiler's environment variables
have not been set up. (CS)
have not been set up. (CS)
8/27/96 (configuration improvement) The Windows resource files are
8/27/96 (configuration improvement) The Windows resource files are
automatically updated when the version/patch level changes. The header file
now has a comment that reminds the user which other files must be manually
updated when the version/patch level changes. (CS)
8/28/96 (new feature) Added file manipulation features (copy, rename, delete,
mkdir) that are supported on all platforms. They are implemented as
mkdir) that are supported on all platforms. They are implemented as
subcommands to the "file" command. See the documentation for the "file"
command for more information. (JH)
@@ -2371,7 +2371,7 @@ the Tcl script in the fileevent wasn't closing the socket immediately. (JL)
package goes in a separate subdirectory of a directory in
$tcl_pkgPath). These directories are included in auto_path by
default.
- Changed the package auto-loader to look for pkgIndex.tcl files
- Changed the package auto-loader to look for pkgIndex.tcl files
not only in the auto_path directories but also in their immediate
children. This should make it easier to install and uninstall
packages (don't have to change auto_path or merge pkgIndex.tcl
@@ -2621,7 +2621,7 @@ lookups of keyword arguments. (JO)
1/12/97 (new feature) Serial IO channel drivers for Windows and Unix,
available by using Tcl open command to open pseudo-files like "com1:" or
"/dev/ttya". New option to Tcl fconfigure command for serial files:
"/dev/ttya". New option to Tcl fconfigure command for serial files:
"-mode baud,parity,data,stop" to specify baud rate, parity, data bits, and
stop bits. Serial IO is not yet available on Mac.
@@ -2701,7 +2701,7 @@ to Feb 31.) The code now will return the last valid day of the
month in these situations. Thanks to Hume Smith for sending in
this bug fix. (RJ)
2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
Tcl_StringObjAppendObj procedures, replaced them with Tcl_AppendToObj
and Tcl_AppendStringsToObj procedures. Added new procedure
Tcl_SetObjLength. (JO)
@@ -3068,7 +3068,7 @@ compilation errors from "invoked from within" to "while compiling". (BL)
modified the interpreter result even if there was no error.
- The argument parsing procedure used by several compile procedures
always treated "]" as end of a command: e.g., "set a ]" would fail.
- Changed errorInfo traceback message for compilation errors from
- Changed errorInfo traceback message for compilation errors from
"invoked from within" to "while compiling".
- Problem initializing Tcl object managers during interpreter creation.
- Added check and error message if formal parameter to a procedure is
@@ -3143,7 +3143,7 @@ is leaked to safe interps. Error message fixes for interp sub commands.
Likewise changes in safealias.tcl; tcl_safeCreateInterp can now be called
without argument to generate the slave name (like in interp create). (DL)
7/10/97 (bug fixes) Bytecode compiler now generates more detailed
7/10/97 (bug fixes) Bytecode compiler now generates more detailed
command location information: subcommands as well as commands now have
location information. This means command trace procedures now get the
correct source string for each command in their command parameter. (BL)
@@ -3181,7 +3181,7 @@ malloc and free. (SS)
sourcing/loading (see safe.n) to hide pathnames, use virtual
paths tokens instead, improved security in several respects and made it
more tunable. Multi level interp loading can work too now. Package auto
loading now works in safe interps as long as the package directory is in
loading now works in safe interps as long as the package directory is in
the auto_path (no deep crawling allowed in safe interps). (DL)
*** POTENTIAL INCOMPATIBILITY with previous alpha and beta releases ***
@@ -3209,7 +3209,7 @@ exists" command returns 0 for them. (BL)
7/29/97 (feature change) Changed the http package to use the ::http
namespace. http_get renamed to http::geturl, http_config renamed to
http::config, http_formatQuery renamed to http::formatQuery.
It now provides the 2.0 version of the package.
It now provides the 2.0 version of the package.
The 1.0 version is still available with the old names.
*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b2 but not with Tcl 7.6 ***
@@ -3273,7 +3273,7 @@ except that the default precision is 12 instead of 6. (JO)
----------------- Released 8.0, 8/18/97 -----------------------
8/19/97 (bug fix) Minimal fix for glob -nocomplain bugs:
"glob -nocomplain unreadableDir/*" was generating an anonymous
"glob -nocomplain unreadableDir/*" was generating an anonymous
error. More in depth fixes will come with 8.1. (DL).
8/20/97 (bug fix) Removed check for FLT_MIN in binary command so
@@ -3318,7 +3318,7 @@ does not prevent stack overflow by multi-interps recursion or aliasing} (DL)
9/11/97 (bug fix) An uninitialized variable in Tcl_WaitPid caused
pipes to fail to report eof properly under Windows. (SS)
9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
executable. (CCS)
9/14/97 (bug fix) Was using the wrong structure in sizeof operation in
@@ -3342,7 +3342,7 @@ Roseman for the pointer on the fix.) (RJ)
cause the compare function to run off the end of an array if the
number only contained 0's. (Thanks to Greg Couch for the report.) (RJ)
9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
properly. (DL, JI)
9/18/97 (bug fix) Fixed long-standing bug where an "array get" command
@@ -3378,9 +3378,9 @@ Now you can "join $list \0" for instance. (DL)
non-existent directory, exec would fail when trying to create its temporary
files. (CCS)
10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
sockets were installed but the hostname could not be determined anyhow.
Tcl_GetHostName() was returning NULL when it should have been returning
Tcl_GetHostName() was returning NULL when it should have been returning
an empty string. (CCS)
10/10/97 (bug fix) "file attribute /" returned error on windows. (CCS)
@@ -3468,7 +3468,7 @@ around to be really closed in this case. (JL)
12/8/97 (bug fix) Need to protect the channel in a fileevent so that it
is not deleted before the fileevent handler returns. (CS, JL)
12/18/97 (bug fix) In the opt argument parsing package: if the description
12/18/97 (bug fix) In the opt argument parsing package: if the description
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)
@@ -3511,7 +3511,7 @@ that could lead to a crash. (SS)
non-local variable references. (SS)
6/25/98 (new features) Added name resolution hooks to support [incr Tcl].
There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
With this changes it should be possible to dynamically load [incr Tcl]
as an extension. (MM)
@@ -3539,7 +3539,7 @@ TclAccessInsertProc, TclStatInsertProc, & TclOpenFileChannelInsertProc
insert pointers to such routines; TclAccessDeleteProc, TclStatDeleteProc,
& TclOpenFileChannelDeleteProc delete pointers to such routines. See
the file generic/tclIOUtils.c for more details. (SKS)
7/1/98 (enhancement) Added a new internal C variable
tclPreInitScript. This is a pointer to a string that may hold an
initialization script; If this pointer is non-NULL it is evaluated in
@@ -3623,7 +3623,7 @@ internal representation holds a pointer to a Proc structure. Extended
TclCreateProc to take both strings and "procbody". (EMS)
10/13/98 (bug fix) The "info complete" command can now handle strings
with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
for providing this fix. (RJ)
10/13/98 (bug fix) The "lsort -dictionary" command did not properly
@@ -3691,7 +3691,7 @@ by default. Fixed socket code so it turns off this bit right after
creation so sockets aren't kept open by exec'ed processes. [Bug: 892]
Thanks to Kevin Kenny for this fix. (SS)
1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
empty string on static apps. It now always returns ".sl". (RJ)
1/28/99 (configure change) Now support -pipe option on gcc. (RJ)
@@ -3736,7 +3736,7 @@ panic. (stanton)
2/2/99 (feature change/bug fix) Changed the behavior of "file
extension" so that it splits at the last period. Now the extension of
a file like "foo..o" is ".o" instead of "..o" as in previous versions.
a file like "foo..o" is ".o" instead of "..o" as in previous versions.
*** POTENTIAL INCOMPATIBILITY ***
----------------- Released 8.0.5, 3/9/99 -------------------------
@@ -3757,15 +3757,15 @@ a file like "foo..o" is ".o" instead of "..o" as in previous versions.
of a UTF-8 string remains \0. Thus Tcl strings once again do not
contain null bytes, except for termination bytes.
- For Java compatibility, "\uXXXX" is used in Tcl to enter a Unicode
character. "\u0000" through "\uffff" are acceptable Unicode
characters.
character. "\u0000" through "\uffff" are acceptable Unicode
characters.
- "\xXX" is used to enter a small Unicode character (between 0 and 255)
in Tcl.
- Tcl automatically translates between UTF-8 and the normal encoding for
the platform during interactions with the system.
- The fconfigure command now supports a -encoding option for specifying
the encoding of an open file or socket. Tcl will automatically
translate between the specified encoding and UTF-8 during I/O.
translate between the specified encoding and UTF-8 during I/O.
See the directory library/encoding to find out what encodings are
supported (eventually there will be an "encoding" command that
makes this information more accessible).
@@ -3839,7 +3839,7 @@ imported procedures as well as procedures defined in a namespace. (BL)
in place of Tcl_GetStringFromObj() if the string representation's length
isn't needed. (BL)
12/18/97 (bug fix) In the opt argument parsing package: if the description
12/18/97 (bug fix) In the opt argument parsing package: if the description
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)
@@ -3849,11 +3849,11 @@ procs now in auto.tcl and package.tcl can be autoloaded if needed. (DL)
1/7/98 (enhancement) tcltest made at install time will search for it's
init.tcl where it is, even when using virtual path compilation. (DL)
1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
string compare "char with high bit set" "char w/o high bit set" returns
the expected value on all platforms. (DL)
1/8/98 (unix portability/configure) building from .../unix/targetName/
1/8/98 (unix portability/configure) building from .../unix/targetName/
subdirectories and simply using "../configure" should now work fine. (DL)
1/14/98 (enhancement) Added new regular expression package that
@@ -3885,7 +3885,7 @@ to generate direct loading package indexes (such those you need
if you use namespaces and plan on using namespace import just after
package require). pkg_mkIndex still has limitations regarding
package dependencies but errors are now ignored and with -direct, correct
package indexes can be generated even if there are dependencies as long
package indexes can be generated even if there are dependencies as long
as the "package provide" are done early enough in the files. (DL)
1/28/98 (enhancement) Performance tuning of regexp and regsub. (CCS)
@@ -3909,7 +3909,7 @@ continue to use the argv array after calling Tcl_OpenCommandChannel(). (CCS)
2/1/98 (bug fix) More bugs with %Z in format string argument to strftime():
1. Borland always returned empty string.
2. MSVC always returned the timezone string for the current time, not the
timezone string for the specified time.
timezone string for the specified time.
3. With MSVC, "clock format 0 -format %Z -gmt 1" would return "GMT" the first
time it was called, but would return the current timezone string on all
subsequent calls. (CCS)
@@ -3931,7 +3931,7 @@ root directory was returning error. (CCS)
determine the attributes for a file. Previously it would return different
error messages on Unix vs. Windows vs. Mac. (CCS)
2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
would reach outside the range of allocated memory. Improved the array
lookup algorithm in set compilation. (DL)
@@ -3939,13 +3939,13 @@ lookup algorithm in set compilation. (DL)
deprecated and ignored. The part1 is always parsed when the part2 argument
is NULL. This is to avoid a pattern of errors for extension writers converting
from string based Tcl_SetVar() to new Tcl_SetObjVar2() and who could easily
forget to provide the flag and thus get code working for normal variables
forget to provide the flag and thus get code working for normal variables
but not for array elements. The performance hit is minimal. A side effect
of that change is that is is no longer possible to create scalar variables
that can't be accessed by tcl scripts because of their invalid name
(ending with parenthesis). Likewise it is also parsed and checked to
ensure that you don't create array elements of array whose name is a valid
array element because they would not be accessible from scripts anyway.
that can't be accessed by tcl scripts because of their invalid name
(ending with parenthesis). Likewise it is also parsed and checked to
ensure that you don't create array elements of array whose name is a valid
array element because they would not be accessible from scripts anyway.
Note: There is still duplicate array elements parsing code. (DL)
*** POTENTIAL INCOMPATIBILITY ***
@@ -3991,7 +3991,7 @@ registry call. (CCS)
2/11/98 (enhancement) Eliminate the TCL_USE_TIMEZONE_VAR definition from
configure.in, because it was the same information as the already existing
HAVE_TM_ZONE definition. The lack of HAVE_TM_ZONE is used to work around a
Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
produces the local timezone string instead of "GMT". (CCS)
2/11/98 (bug fix) Memleaks and dereferencing of uninitialized memory in
@@ -4349,7 +4349,7 @@ strings that are already null terminated. [Bug: 1793] (stanton)
5/3/99 (new feature) Applied Jeff Hobbs's string patch which includes
the following changes:
- added new subcommands: equal, repeat, map, is, replace
- added new subcommands: equal, repeat, map, is, replace
- added -length option to "string compare|equal"
- added -nocase option to "string compare|equal|match"
- string and list indices can be an integer or end?-integer?.
@@ -4378,7 +4378,7 @@ improvements for many Tcl scripts. [Bug: 1063] (stanton)
encoding subfield from the LANG/LC_ALL environment variables in cases
where the locale is not found in the built-in locale table. It also
attempts to initialize the locale subsystem so X11 is happy. [Bug: 1989]
(stanton)
(stanton)
5/14/99 (bug fix) Applied the patch to fix 100-year and 400-year
boundaries in leap year code, from Isaac Hollander. [Bug: 2066] (redman)
@@ -4466,7 +4466,7 @@ harness package. Modified test files to use new tcltest package.
6/26/99 (new feature) Applied patch from Peter Hardie to add poke
command to dde and changed the dde package version number to
1.1. (redman)
1.1. (redman)
6/28/99 (bug fix) Applied patch from Peter Hardie to fix problem in
Tcl_GetIndexFromObj() when the key being passed is the empty string.
@@ -4529,7 +4529,7 @@ notation for opening serial ports on Windows. (redman)
instead of the platform-specific "size_t", primarily after SunOS 4
users could no longer compile. (redman)
7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
[Bug: 2427] (redman)
7/22/99 (bug fix) The install-sh script must be given execute
@@ -4564,7 +4564,7 @@ pack-old.n [Bug: 2469]. Patches from Don Porter. (redman)
7/29/99 (bug fix) Allow tcl to open CON and NUL, even for redirection
of std channels. [Bug: 2393 2392 2209 2458] (redman)
7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
[Bug: 2386] (hobbs)
7/30/99 (bug fix) Fixed bug in info complete. [Bug: 2383 2466] (hobbs)
@@ -4574,7 +4574,7 @@ provided by James Dennett. [Bug: 2450] (redman)
7/30/99 (bug fix) Fixed launching of 16bit applications on Win9x from
wish. The command line was being primed with tclpip82.dll, but it was
ignored later.
ignored later.
7/30/99 (bug fix) Added functions to stub table, patch provided by Jan
Nijtmans. [Bug: 2445] (hobbs)
@@ -4587,7 +4587,7 @@ thread's stack space. (redman)
--------------- Released 8.2b2, August 5, 1999 ----------------------
8/4/99 (bug fix) Applied patches supplied by Henry Spencer to greatly
enhance performance of certain classes of regular expressions.
enhance performance of certain classes of regular expressions.
[Bug: 2440 2447] (stanton)
8/5/99 (doc change) Made it clear that tcl_pkgPath was not set for
@@ -4601,7 +4601,7 @@ terminated in tclLiteral.c. [Bug: 2496] (hobbs)
8/9/99 (bug fix) Fixed test suite to handle larger integers
(64bit). Patch from Don Porter. (hobbs)
8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
[Bug: 1952]. Clarified array pattern docs [Bug: 1330]. Fixed clock docs
[Bug: 693]. Fixed formatting errors [Bug: 2188 2189]. Fixed doc error
in tclvars.n [Bug: 2042]. (hobbs)
@@ -4661,7 +4661,7 @@ and in testthread code. No more known (reported) mem leaks for Tcl
built using gcc on Solaris 2.5.1. Also none reported for Tcl on NT
(using Purify 6.0). (hobbs)
10/30/99 (bug fix) fixed improper bytecode handling of
10/30/99 (bug fix) fixed improper bytecode handling of
'eval {set array($unknownvar) 5}' (also for incr) (hobbs)
10/30/99 (bug fix) fixed event/io threading problems by making
@@ -5115,7 +5115,7 @@ bits for Tcl_UniChar though) (hobbs)
2001-05-30 (new feature)[TIP 15] Tcl_GetMathFuncInfo, Tcl_ListMathFuncs,
Tcl_InfoObjCmd, InfoFunctionsCmd APIs (fellows)
2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
definitions brought into agreement (porter)
2001-06-12 (bug fix)[219232] regexp returned non-matching sub-pairs to have
@@ -5284,7 +5284,7 @@ compiles to 0 bytecodes (sofer)
2001-09-13 (new feature) Old ChangeLog entries => ChangeLog.1999 (hobbs)
2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
enable all compile and execution tracing (sofer)
*** POTENTIAL INCOMPATIBILITY ***
@@ -5566,7 +5566,7 @@ options to configure (max)
2002-07-30 (bug fix)[584603] WriteChars infinite loop non-UTF-8 string (kupries)
2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
are now fully CONST-ified. Use the symbols USE_NON_CONST or
USE_COMPAT_CONST to select interfaces with fewer changes.
*** POTENTIAL INCOMPATIBILITY ***
@@ -5576,7 +5576,7 @@ options to configure (max)
=> tcltest 2.2
2002-08-07 (bug fix)[587488] mem leak with USE_THREAD_ALLOC (sofer,sass)
2002-08-07 (feature enhancement)[584794,584650,472576] boolean values
are no longer always re-parsed from string. (sofer)
@@ -5710,7 +5710,7 @@ packages in multiple interps.
2003-02-01 (bug fix)[675356] [clock clicks {}]; [clock clicks -] - syntax errs
2003-02-01 (bug fix)[656660] MT-safety for [clock format]
2003-02-01 (bug fix)[656660] MT-safety for [clock format]
2003-02-03 (bug fix)[651271] command rename traces get fully-qualified names
*** POTENTIAL INCOMPATIBILITY ***
@@ -5929,7 +5929,7 @@ various odd regexp "can't happen" bugs.
2003-12-09 (platform support)[852369] update errno usage for recent glibc
2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
2003-12-17 (bug fix)[839519] fixed two memory leaks (vasiljevic)
@@ -5944,7 +5944,7 @@ various odd regexp "can't happen" bugs.
2004-02-12 (feature enhancement) update HP-11 build libs setup
2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
2004-02-17 (bug fix)[772288] Unix std channels forced to exist at startup.
@@ -6037,7 +6037,7 @@ in this changeset (new minor version) rather than bug fixes:
* [TIP #139] documented portions of Tcl's namespace C APIs
* [TIP #148] correct [list]-quoting of the '#' character
*** POTENTIAL INCOMPATIBILITY ***
*** POTENTIAL INCOMPATIBILITY ***
For scripts that assume a particular (buggy) string rep for lists.
* [TIP #156] add "root locale" to msgcat
@@ -6532,7 +6532,7 @@ Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
2005-07-22 (enhancement)[1237755] 8.4 features in script library (fradin,porter)
2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
2005-07-26 (bug fix)[1047286] cmd delete traces during namespace delete (porter)
2005-07-26 (new unix feature)[1231015] ${prefix}/share on ::tcl_pkgPath (dejong)
@@ -6627,7 +6627,7 @@ registered by [package ifneeded] provides the version it claims (lavana,porter)
2005-11-09 (bug fix)[1350293,1350291] [after $negative $script] fixed (kenny)
2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
issues with [namespace path] and command delete traces (sofer,fellows)
2005-11-18 (bug fix)[1358369] URL parsing standards compliance (wu,fellows)
@@ -6756,7 +6756,7 @@ naked-fork safe on Tiger (steffen)
2006-06-20 (internal change) Dropped the internal routines used to hook into
filesystem operations back in the pre-Tcl_Filesystem days. (porter)
***POTENTIAL INCOMPATIBILITY***
For extensions and programs that have never migrated to the supported Tcl 8.4
For extensions and programs that have never migrated to the supported Tcl 8.4
interface for virtual filesystems
2006-07-05 (enhancement) Expression parser rewrite avoids stack overflow,
@@ -7603,7 +7603,7 @@ avoid otherwise very tricky multi-thread finalization bugs. (staplin,ferrieux)
2009-10-04 (bug fix)[2569449] Core Foundation memory bug in Tiger (steffen)
2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
introduced by first versions of the NRE conversion (nadkarni,porter)
2009-10-06 (bug fix)[1941434] broken tclTomMath.h includes (porter)
@@ -8108,7 +8108,7 @@ and Tcl_FSMountsChanged(). (porter)
2012-08-25 (bug fix)[3561330] Ukranian translation of "March" (teterin)
2012-09-12 (TIP 404) New msgcat commands [mcflset], [mcflmset] (oehlmann)
2012-09-07 (TIP 404) New msgcat commands [mcflset], [mcflmset] (oehlmann)
=> msgcat 1.5.0
Many revisions to better support a Cygwin environment (nijtmans)
@@ -8116,3 +8116,50 @@ Many revisions to better support a Cygwin environment (nijtmans)
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
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
-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
+4 -4
View File
@@ -107,7 +107,7 @@ with the value of \fIcode\fR. The \fB(Tcl_Obj *)\fR returned
by \fBTcl_GetReturnOptions\fR points to an unshared
\fBTcl_Obj\fR with reference count of zero. The dictionary
may be written to, either adding, removing, or overwriting
any entries in it, without the need to check for a shared object.
any entries in it, without the need to check for a shared value.
As with any \fBTcl_Obj\fR with reference count of zero, it is up to
the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
@@ -232,7 +232,7 @@ the need for a null byte. If the \fBTcl_AddObjErrorInfo\fR
interface is used at all, it should be with a negative \fIlength\fR value.
.PP
The procedure \fBTcl_SetObjErrorCode\fR is used to set the
\fB\-errorcode\fR return option to the list object \fIerrorObjPtr\fR
\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR
built up by the caller.
\fBTcl_SetObjErrorCode\fR is typically invoked just
before returning an error. If an error is
@@ -242,7 +242,7 @@ the \fB\-errorcode\fR return option to \fBNONE\fR.
.PP
The procedure \fBTcl_SetErrorCode\fR is also used to set the
\fB\-errorcode\fR return option. However, it takes one or more strings to
record instead of an object. Otherwise, it is similar to
record instead of a value. Otherwise, it is similar to
\fBTcl_SetObjErrorCode\fR in behavior.
.PP
\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
@@ -309,4 +309,4 @@ most recent error seen in an interpreter.
Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
Tcl_SetErrno(3), tclvars(n)
.SH KEYWORDS
error, object, object result, stack, trace, variable
error, value, value result, stack, trace, variable
+2 -2
View File
@@ -30,7 +30,7 @@ Points to the Tcl_Obj in which to store, or from which to
retrieve a boolean value.
.AP Tcl_Interp *interp in/out
If a boolean value cannot be retrieved,
an error message is left in the interpreter's result object
an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP int *boolPtr out
Points to place where \fBTcl_GetBooleanFromObj\fR
@@ -92,4 +92,4 @@ a \fBTCL_ERROR\fR return.
Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean
.SH KEYWORDS
boolean, object
boolean, value
+23 -23
View File
@@ -8,7 +8,7 @@
.TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -27,65 +27,65 @@ unsigned char *
.SH ARGUMENTS
.AS "const unsigned char" *lengthPtr in/out
.AP "const unsigned char" *bytes in
The array of bytes used to initialize or set a byte-array object. May be NULL
The array of bytes used to initialize or set a byte-array value. May be NULL
even if \fIlength\fR is non-zero.
.AP int length in
The length of the array of bytes. It must be >= 0.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
For \fBTcl_SetByteArrayObj\fR, this points to the value to be converted to
byte-array type. For \fBTcl_GetByteArrayFromObj\fR and
\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
\fBTcl_SetByteArrayLength\fR, this points to the value from which to get
the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
object, it will be converted to one.
value, it will be converted to one.
.AP int *lengthPtr out
If non-NULL, filled with the length of the array of bytes in the object.
If non-NULL, filled with the length of the array of bytes in the value.
.BE
.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl byte-array objects
from C code. Byte-array objects are typically used to hold the
These procedures are used to create, modify, and read Tcl byte-array values
from C code. Byte-array values are typically used to hold the
results of binary IO operations or data structures created with the
\fBbinary\fR command. In Tcl, an array of bytes is not equivalent to a
string. Conceptually, a string is an array of Unicode characters, while a
byte-array is an array of 8-bit quantities with no implicit meaning.
Accessor functions are provided to get the string representation of a
byte-array or to convert an arbitrary object to a byte-array. Obtaining the
string representation of a byte-array object (by calling
byte-array or to convert an arbitrary value to a byte-array. Obtaining the
string representation of a byte-array value (by calling
\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
one-to-one mapping between the bytes in the internal representation and the
UTF-8 characters in the string representation.
.PP
\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
create a new object of byte-array type or modify an existing object to have a
byte-array type. Both of these procedures set the object's type to be
byte-array and set the object's internal representation to a copy of the
create a new value of byte-array type or modify an existing value to have a
byte-array type. Both of these procedures set the value's type to be
byte-array and set the value's internal representation to a copy of the
array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
pointer to a newly allocated object with a reference count of zero.
pointer to a newly allocated value with a reference count of zero.
\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
the object is not already a byte-array object, frees any old internal
the value is not already a byte-array value, frees any old internal
representation. If \fIbytes\fR is NULL then the new byte array contains
arbitrary values.
.PP
\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
returns a pointer to the object's new internal representation as an array of
\fBTcl_GetByteArrayFromObj\fR converts a Tcl value to byte-array type and
returns a pointer to the value's new internal representation as an array of
bytes. The length of this array is stored in \fIlengthPtr\fR if
\fIlengthPtr\fR is non-NULL. The storage for the array of bytes is owned by
the object and should not be freed. The contents of the array may be
modified by the caller only if the object is not shared and the caller
the value and should not be freed. The contents of the array may be
modified by the caller only if the value is not shared and the caller
invalidates the string representation.
.PP
\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
and changes the length of the object's internal representation as an
\fBTcl_SetByteArrayLength\fR converts the Tcl value to byte-array type
and changes the length of the value's internal representation as an
array of bytes. If \fIlength\fR is greater than the space currently
allocated for the array, the array is reallocated to the new length; the
newly allocated bytes at the end of the array have arbitrary values. If
\fIlength\fR is less than the space currently allocated for the array,
the length of array is reduced to the new length. The return value is a
pointer to the object's new array of bytes.
pointer to the value's new array of bytes.
.SH "SEE ALSO"
Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
.SH KEYWORDS
object, byte array, utf, unicode, internationalization
value, binary data, byte array, utf, unicode, internationalization
+3 -3
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
@@ -846,7 +846,7 @@ the generic options error message string.
.PP
It always returns \fBTCL_ERROR\fR
.PP
An error message is generated in \fIinterp\fR's result object to
An error message is generated in \fIinterp\fR's result value to
indicate that a command was invoked with a bad option.
The message has the form
.CS
+6 -6
View File
@@ -41,18 +41,18 @@ will call \fIproc\fR to process the command.
It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
command is defined;
that is, a command procedure is defined that takes an array of
argument strings instead of objects.
The object-based command procedures registered by \fBTcl_CreateObjCommand\fR
argument strings instead of values.
The value-based command procedures registered by \fBTcl_CreateObjCommand\fR
can execute significantly faster than the string-based command procedures
defined by \fBTcl_CreateCommand\fR.
This is because they take Tcl objects as arguments
and those objects can retain an internal representation that
This is because they take Tcl values as arguments
and those values can retain an internal representation that
can be manipulated more efficiently.
Also, Tcl's interpreter now uses objects internally.
Also, Tcl's interpreter now uses values internally.
In order to invoke a string-based command procedure
registered by \fBTcl_CreateCommand\fR,
it must generate and fetch a string representation
from each argument object before the call.
from each argument value before the call.
New commands should be defined using \fBTcl_CreateObjCommand\fR.
We support \fBTcl_CreateCommand\fR for backwards compatibility.
.PP
+9 -2
View File
@@ -10,6 +10,13 @@
.BS
.SH NAME
Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
.SH "NOTICE OF EVENTUAL DEPRECATION"
.PP
The \fBTcl_CreateMathFunc\fR and \fBTcl_GetMathFuncInfo\fR functions
are rendered somewhat obsolete by the ability to create functions for
expressions by placing commands in the \fBtcl::mathfunc\fR namespace,
as described in the \fBmathfunc\fR manual page; the API described on
this page is not expected to be maintained indefinitely.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -146,9 +153,9 @@ will not be modified. The variable pointed to by \fInumArgsPointer\fR
will contain -1, and no argument types will be stored in the variable
pointed to by \fIargTypesPointer\fR.
.PP
\fBTcl_ListMathFuncs\fR returns a Tcl object containing a list of all
\fBTcl_ListMathFuncs\fR returns a Tcl value containing a list of all
the math functions defined in the interpreter whose name matches
\fIpattern\fR. The returned object has a reference count of zero.
\fIpattern\fR. The returned value has a reference count of zero.
.SH "SEE ALSO"
expr(n), info(n), Tcl_CreateObjCommand(3), Tcl_Free(3), Tcl_NewListObj(3)
.SH KEYWORDS
+10 -10
View File
@@ -64,7 +64,7 @@ The command must not have been deleted.
Pointer to structure containing various information about a
Tcl command.
.AP Tcl_Obj *objPtr in
Object containing the name of a Tcl command.
Value containing the name of a Tcl command.
.BE
.SH DESCRIPTION
.PP
@@ -102,10 +102,10 @@ will be copies of the \fIclientData\fR and \fIinterp\fR arguments given to
\fBTcl_CreateObjCommand\fR. Typically, \fIclientData\fR points to an
application-specific data structure that describes what to do when the
command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
arguments to the command, \fIobjc\fR giving the number of argument objects
arguments to the command, \fIobjc\fR giving the number of argument values
(including the command name) and \fIobjv\fR giving the values of the
arguments. The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
the argument objects. Unlike \fIargv\fR[\fIargv\fR] used in a
the argument values. Unlike \fIargv\fR[\fIargv\fR] used in a
string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
.PP
Additionally, when \fIproc\fR is invoked, it must not modify the contents
@@ -115,9 +115,9 @@ cause memory to be lost and the runtime stack to be corrupted. The
\fBconst\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
compilers to report any such attempted assignment as an error. However,
it is acceptable to modify the internal representation of any individual
object argument. For instance, the user may call
value argument. For instance, the user may call
\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
representation of that object; that call may change the type of the object
representation of that value; that call may change the type of the value
that \fIobjv\fR[\fB2\fR] points at, but will not change where
\fIobjv\fR[\fB2\fR] points.
.PP
@@ -133,7 +133,7 @@ of the command,
and in the case of \fBTCL_ERROR\fR this gives an error message.
Before invoking a command procedure,
\fBTcl_EvalObjEx\fR sets interpreter's result to
point to an object representing an empty string, so simple
point to a value representing an empty string, so simple
commands can return an empty result by doing nothing at all.
.PP
The contents of the \fIobjv\fR array belong to Tcl and are not
@@ -225,7 +225,7 @@ if \fIisNativeObjectProc\fR has the value 1.
The fields \fIobjProc\fR and \fIobjClientData\fR
have the same meaning as the \fIproc\fR and \fIclientData\fR
arguments to \fBTcl_CreateObjCommand\fR;
they hold information about the object-based command procedure
they hold information about the value-based command procedure
that the Tcl interpreter calls to implement the command.
The fields \fIproc\fR and \fIclientData\fR
hold information about the string-based command procedure
@@ -235,7 +235,7 @@ this is the procedure passed to it;
otherwise, this is a compatibility procedure
registered by \fBTcl_CreateObjCommand\fR
that simply calls the command's
object-based procedure after converting its string arguments to Tcl objects.
value-based procedure after converting its string arguments to Tcl values.
The field \fIdeleteData\fR is the ClientData value
to pass to \fIdeleteProc\fR; it is normally the same as
\fIclientData\fR but may be set independently using the
@@ -290,7 +290,7 @@ they need to keep it for a long time.
\fBTcl_GetCommandFullName\fR produces the fully qualified name
of a command from a command token.
The name, including all namespace prefixes,
is appended to the object specified by \fIobjPtr\fR.
is appended to the value specified by \fIobjPtr\fR.
.PP
\fBTcl_GetCommandFromObj\fR returns a token for the command
specified by the name in a \fBTcl_Obj\fR.
@@ -299,4 +299,4 @@ Returns NULL if the command is not found.
.SH "SEE ALSO"
Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
.SH KEYWORDS
bind, command, create, delete, namespace, object
bind, command, create, delete, namespace, value
+11 -11
View File
@@ -78,10 +78,10 @@ Count of additional arguments to pass to the alias command.
Vector of strings, the additional arguments to pass to the alias command.
This storage is owned by the caller.
.AP int objc in
Count of additional object arguments to pass to the alias object command.
Count of additional value arguments to pass to the aliased command.
.AP Tcl_Obj **objv in
Vector of Tcl_Obj structures, the additional object arguments to pass to
the alias object command.
Vector of Tcl_Obj structures, the additional value arguments to pass to
the aliased command.
This storage is owned by the caller.
.AP Tcl_Interp **targetInterpPtr in
Pointer to location to store the address of the interpreter where a target
@@ -97,11 +97,11 @@ Pointer to location to store a vector of strings, the additional arguments
to pass to an alias. The location is in storage owned by the caller, the
vector of strings is owned by the called function.
.AP int *objcPtr out
Pointer to location to store count of additional object arguments to be
Pointer to location to store count of additional value arguments to be
passed to the alias. The location is in storage owned by the caller.
.AP Tcl_Obj ***objvPtr out
Pointer to location to store a vector of Tcl_Obj structures, the additional
arguments to pass to an object alias command. The location is in storage
arguments to pass to an alias command. The location is in storage
owned by the caller, the vector of Tcl_Obj structures is owned by the
called function.
.AP "const char" *cmdName in
@@ -165,13 +165,13 @@ of the relative path succeeds, \fBTCL_OK\fR is returned, else
\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
\fIaskingInterp\fR contains the error message.
.PP
\fBTcl_CreateAlias\fR creates an object command named \fIslaveCmd\fR in
\fBTcl_CreateAlias\fR creates a command named \fIslaveCmd\fR in
\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
to be invoked in \fItargetInterp\fR. The arguments specified by the strings
contained in \fIargv\fR are always prepended to any arguments supplied in the
invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
it fails; in that case, an error message is left in the object result
it fails; in that case, an error message is left in the value result
of \fIslaveInterp\fR.
Note that there are no restrictions on the ancestry relationship (as
created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
@@ -179,7 +179,7 @@ created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
restrictions on how they are related.
.PP
\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
that it takes a vector of objects to pass as additional arguments instead
that it takes a vector of values to pass as additional arguments instead
of a vector of strings.
.PP
\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
@@ -202,7 +202,7 @@ command, or the operation will return \fBTCL_ERROR\fR and leave an error
message in the \fIresult\fR field in \fIinterp\fR.
If an exposed command named \fIcmdName\fR already exists,
the operation returns \fBTCL_ERROR\fR and leaves an error message in the
object result of \fIinterp\fR.
value result of \fIinterp\fR.
If the operation succeeds, it returns \fBTCL_OK\fR.
After executing this command, attempts to use \fIcmdName\fR in a call to
\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
@@ -212,10 +212,10 @@ exposed commands to the set of hidden commands, under the name
\fIhiddenCmdName\fR.
\fICmdName\fR must be the name of an existing exposed
command, or the operation will return \fBTCL_ERROR\fR and leave an error
message in the object result of \fIinterp\fR.
message in the value result of \fIinterp\fR.
Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
leave an error message in the object result of \fIinterp\fR.
leave an error message in the value result of \fIinterp\fR.
The \fICmdName\fR will be looked up in the global namespace, and not
relative to the current namespace, even if the current namespace is not the
global one.
+16 -16
View File
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl objects as dictionaries
Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl values as dictionaries
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -47,23 +47,23 @@ int
.SH ARGUMENTS
.AS Tcl_DictSearch "**valuePtrPtr" in/out
.AP Tcl_Interp *interp in
If an error occurs while converting an object to be a dictionary object,
an error message is left in the interpreter's result object
If an error occurs while converting a value to be a dictionary value,
an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP Tcl_Obj *dictPtr in/out
Points to the dictionary object to be manipulated.
If \fIdictPtr\fR does not already point to a dictionary object,
Points to the dictionary value to be manipulated.
If \fIdictPtr\fR does not already point to a dictionary value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *keyPtr in
Points to the key for the key/value pair being manipulated within the
dictionary object.
dictionary value.
.AP Tcl_Obj **keyPtrPtr out
Points to a variable that will have the key from a key/value pair
placed within it. May be NULL to indicate that the caller is not
interested in the key.
.AP Tcl_Obj *valuePtr in
Points to the value for the key/value pair being manipulated within the
dictionary object (or sub-object, in the case of
dictionary value (or sub-value, in the case of
\fBTcl_DictObjPutKeyList\fR.)
.AP Tcl_Obj **valuePtrPtr out
Points to a variable that will have the value from a key/value pair
@@ -88,15 +88,15 @@ completed, and a zero otherwise.
Indicates the number of keys that will be supplied in the \fIkeyv\fR
array.
.AP "Tcl_Obj *const" *keyv in
Array of \fIkeyc\fR pointers to objects that
Array of \fIkeyc\fR pointers to values that
\fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will
use to locate the key/value pair to manipulate within the
sub-dictionaries of the main dictionary object passed to them.
sub-dictionaries of the main dictionary value passed to them.
.BE
.SH DESCRIPTION
.PP
Tcl dictionary objects have an internal representation that supports
Tcl dictionary values have an internal representation that supports
efficient mapping from keys to values and which guarantees that the
particular ordering of keys within the dictionary remains the same
modulo any keys being deleted (which removes them from the order) or
@@ -106,11 +106,11 @@ keys of the dictionary, and each will be followed (in the odd-valued
index) by the value associated with that key.
.PP
The procedures described in this man page are used to
create, modify, index, and iterate over dictionary objects from C code.
create, modify, index, and iterate over dictionary values from C code.
.PP
\fBTcl_NewDictObj\fR creates a new, empty dictionary object. The
string representation of the object will be invalid, and the reference
count of the object will be zero.
\fBTcl_NewDictObj\fR creates a new, empty dictionary value. The
string representation of the value will be invalid, and the reference
count of the value will be zero.
.PP
\fBTcl_DictObjGet\fR looks up the given key within the given
dictionary and writes a pointer to the value associated with that key
@@ -217,7 +217,7 @@ if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
for (; !done ; \fBTcl_DictObjNext\fR(&search, &key, &value, &done)) {
/*
* Note that strcmp() is not a good way of comparing
* objects and is just used here for demonstration
* values and is just used here for demonstration
* purposes.
*/
if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
@@ -231,4 +231,4 @@ return TCL_OK;
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
.SH KEYWORDS
dict, dict object, dictionary, dictionary object, hash table, iteration, object
dict, dict value, dictionary, dictionary value, hash table, iteration, value
+13 -13
View File
@@ -8,7 +8,7 @@
.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl values as floating-point values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -23,11 +23,11 @@ int
.SH ARGUMENTS
.AS Tcl_Interp doubleValue in/out
.AP double doubleValue in
A double-precision floating-point value used to initialize or set a Tcl object.
A double-precision floating-point value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetDoubleObj\fR, this points to the object in which to store a
For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
double value.
For \fBTcl_GetDoubleFromObj\fR, this refers to the object
For \fBTcl_GetDoubleFromObj\fR, this refers to the value
from which to retrieve a double value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when double value retrieval fails.
@@ -37,21 +37,21 @@ Points to place to store the double value obtained from \fIobjPtr\fR.
.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl objects that
These procedures are used to create, modify, and read Tcl values that
hold double-precision floating-point values.
.PP
\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
\fBTcl_NewDoubleObj\fR creates and returns a new Tcl value initialized to
the double value \fIdoubleValue\fR. The returned Tcl value is unshared.
.PP
\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl object pointed to
\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl value pointed to
by \fIobjPtr\fR to the double value \fIdoubleValue\fR. The \fIobjPtr\fR
argument must point to an unshared Tcl object. Any attempt to set the value
of a shared Tcl object violates Tcl's copy-on-write policy. Any existing
string representation or internal representation in the unshared Tcl object
argument must point to an unshared Tcl value. Any attempt to set the value
of a shared Tcl value violates Tcl's copy-on-write policy. Any existing
string representation or internal representation in the unshared Tcl value
will be freed as a consequence of setting the new value.
.PP
\fBTcl_GetDoubleFromObj\fR attempts to retrieve a double value from the
Tcl object \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
Tcl value \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
returned, and the double value is written to the storage pointed to by
\fIdoublePtr\fR. If the attempt fails, then \fBTCL_ERROR\fR is returned,
and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
@@ -61,4 +61,4 @@ calls to \fBTcl_GetDoubleFromObj\fR more efficient.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
.SH KEYWORDS
double, double object, double type, internal representation, object, object type, string representation
double, double value, double type, internal representation, value, value type, string representation
+10 -10
View File
@@ -47,17 +47,17 @@ int
Interpreter in which to execute the script. The interpreter's result is
modified to hold the result or error message from the script.
.AP Tcl_Obj *objPtr in
A Tcl object containing the script to execute.
A Tcl value containing the script to execute.
.AP int flags in
ORed combination of flag bits that specify additional options.
\fBTCL_EVAL_GLOBAL\fR and \fBTCL_EVAL_DIRECT\fR are currently supported.
.AP "const char" *fileName in
Name of a file containing a Tcl script.
.AP int objc in
The number of objects in the array pointed to by \fIobjPtr\fR;
The number of values in the array pointed to by \fIobjPtr\fR;
this is also the number of words in the command.
.AP Tcl_Obj **objv in
Points to an array of pointers to objects; each object holds the
Points to an array of pointers to values; each value holds the
value of a single word in the command to execute.
.AP int numBytes in
The number of bytes in \fIscript\fR, not including any
@@ -83,7 +83,7 @@ If this is the first time \fIobjPtr\fR has been executed,
its commands are compiled into bytecode instructions
which are then executed. The
bytecodes are saved in \fIobjPtr\fR so that the compilation step
can be skipped if the object is evaluated again in the future.
can be skipped if the value is evaluated again in the future.
.PP
The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
described here) is a Tcl completion code with
@@ -111,15 +111,15 @@ which will be safely substituted by the Tcl interpreter into
.PP
\fBTcl_EvalObjv\fR executes a single pre-parsed command instead of a
script. The \fIobjc\fR and \fIobjv\fR arguments contain the values
of the words for the Tcl command, one word in each object in
of the words for the Tcl command, one word in each value in
\fIobjv\fR. \fBTcl_EvalObjv\fR evaluates the command and returns
a completion code and result just like \fBTcl_EvalObjEx\fR.
The caller of \fBTcl_EvalObjv\fR has to manage the reference count of the
elements of \fIobjv\fR, insuring that the objects are valid until
elements of \fIobjv\fR, insuring that the values are valid until
\fBTcl_EvalObjv\fR returns.
.PP
\fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that the script to
be executed is supplied as a string instead of an object and no compilation
be executed is supplied as a string instead of a value and no compilation
occurs. The string should be a proper UTF-8 string as converted by
\fBTcl_ExternalToUtfDString\fR or \fBTcl_ExternalToUtf\fR when it is known
to possibly contain upper ASCII characters whose possible combinations
@@ -129,7 +129,7 @@ bytecodes. In situations where it is known that the script will never be
executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
\fBTcl_Eval\fR returns a completion code and result just like
\fBTcl_EvalObjEx\fR. Note: for backward compatibility with versions before
Tcl 8.0, \fBTcl_Eval\fR copies the object result in \fIinterp\fR to
Tcl 8.0, \fBTcl_Eval\fR copies the value result in \fIinterp\fR to
\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
does not do the copy.
@@ -170,7 +170,7 @@ other procedures. If this flag bit is set, the script is not
compiled to bytecodes; instead it is executed directly
as is done by \fBTcl_EvalEx\fR. The
\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
contents of an object are going to change immediately, so the
contents of a value are going to change immediately, so the
bytecodes will not be reused in a future execution. In this case,
it is faster to execute the script directly.
.TP 23
@@ -208,4 +208,4 @@ This means that top-level applications should never see a return code
from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
.SH KEYWORDS
execute, file, global, object, result, script
execute, file, global, result, script, value
+4 -4
View File
@@ -49,11 +49,11 @@ given by the \fIexpr\fR argument
and return the result in one of four different forms.
The expression can have any of the forms accepted by the \fBexpr\fR command.
Note that these procedures have been largely replaced by the
object-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
value-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
Those object-based procedures evaluate an expression held in a Tcl object
Those value-based procedures evaluate an expression held in a Tcl value
instead of a string.
The object argument can retain an internal representation
The value argument can retain an internal representation
that is more efficient to execute.
.PP
The \fIinterp\fR argument refers to an interpreter used to
@@ -103,4 +103,4 @@ string stored in the interpreter's result.
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
.SH KEYWORDS
boolean, double, evaluate, expression, integer, object, string
boolean, double, evaluate, expression, integer, value, string
+6 -6
View File
@@ -29,7 +29,7 @@ int
.AP Tcl_Interp *interp in
Interpreter in whose context to evaluate \fIobjPtr\fR.
.AP Tcl_Obj *objPtr in
Pointer to an object containing the expression to evaluate.
Pointer to a value containing the expression to evaluate.
.AP long *longPtr out
Pointer to location in which to store the integer value of the
expression.
@@ -40,7 +40,7 @@ expression.
Pointer to location in which to store the 0/1 boolean value of the
expression.
.AP Tcl_Obj **resultPtrPtr out
Pointer to location in which to store a pointer to the object
Pointer to location in which to store a pointer to the value
that is the result of the expression.
.BE
@@ -93,14 +93,14 @@ or
or else an error occurs.
.PP
If \fBTcl_ExprObj\fR successfully evaluates the expression,
it stores a pointer to the Tcl object
it stores a pointer to the Tcl value
containing the expression's value at \fI*resultPtrPtr\fR.
In this case, the caller is responsible for calling
\fBTcl_DecrRefCount\fR to decrement the object's reference count
when it is finished with the object.
\fBTcl_DecrRefCount\fR to decrement the value's reference count
when it is finished with the value.
.SH "SEE ALSO"
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
.SH KEYWORDS
boolean, double, evaluate, expression, integer, object, string
boolean, double, evaluate, expression, integer, value, string
+65 -64
View File
@@ -86,7 +86,7 @@ int
int
\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
.sp
const char **
const char *const *
\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
.sp
int
@@ -192,8 +192,8 @@ int
Points to a structure containing the addresses of procedures that
can be called to perform the various filesystem operations.
.AP Tcl_Obj *pathPtr in
The path represented by this object is used for the operation in
question. If the object does not already have an internal \fBpath\fR
The path represented by this value is used for the operation in
question. If the value does not already have an internal \fBpath\fR
representation, it will be converted to have one.
.AP Tcl_Obj *srcPathPtr in
As for \fIpathPtr\fR, but used for the source file for a copy or
@@ -213,12 +213,12 @@ this structure will be returned. This parameter may be NULL.
Interpreter to use either for results, evaluation, or reporting error
messages.
.AP ClientData clientData in
The native description of the path object to create.
The native description of the path value to create.
.AP Tcl_Obj *firstPtr in
The first of two path objects to compare. The object may be converted
The first of two path values to compare. The value may be converted
to \fBpath\fR type.
.AP Tcl_Obj *secondPtr in
The second of two path objects to compare. The object may be converted
The second of two path values to compare. The value may be converted
to \fBpath\fR type.
.AP Tcl_Obj *listObj in
The list of path elements to operate on with a \fBjoin\fR operation.
@@ -226,12 +226,12 @@ The list of path elements to operate on with a \fBjoin\fR operation.
If non-negative, the number of elements in the \fIlistObj\fR which should
be joined together. If negative, then all elements are joined.
.AP Tcl_Obj **errorPtr out
In the case of an error, filled with an object containing the name of
In the case of an error, filled with a value containing the name of
the file which caused an error in the various copy/rename operations.
.AP Tcl_Obj **objPtrRef out
Filled with an object containing the result of the operation.
Filled with a value containing the result of the operation.
.AP Tcl_Obj *resultPtr out
Pre-allocated object in which to store (using
Pre-allocated value in which to store (using
\fBTcl_ListObjAppendElement\fR) the list of
files or directories which are successfully matched.
.AP int mode in
@@ -331,17 +331,17 @@ buffer is actually
declared to be, allowing the same code to be used both on systems with
and systems without support for files larger than 2GB in size.
.PP
The \fBTcl_FS\fR API is objectified and may cache internal
The \fBTcl_FS\fR API is \fBTcl_Obj\fR-ified and may cache internal
representations and other path-related strings (e.g.\ the current working
directory). One side-effect of this is that one must not pass in objects
directory). One side-effect of this is that one must not pass in values
with a reference count of zero to any of these functions. If such calls were
handled, they might result
in memory leaks (under some circumstances, the filesystem code may wish
to retain a reference to the passed in object, and so one must not assume
that after any of these calls return, the object still has a reference count of
to retain a reference to the passed in value, and so one must not assume
that after any of these calls return, the value still has a reference count of
zero - it may have been incremented) or in a direct segmentation fault
(or other memory access error)
due to the object being freed part way through the complex object
due to the value being freed part way through the complex value
manipulation required to ensure that the path is fully normalized and
absolute for filesystem determination. The practical lesson to learn
from this is that
@@ -354,9 +354,9 @@ Tcl_DecrRefCount(path);
.PP
is wrong, and may cause memory errors. The \fIpath\fR must have its
reference count incremented before passing it in, or
decrementing it. For this reason, objects with a reference count of zero are
decrementing it. For this reason, values with a reference count of zero are
considered not to be valid filesystem paths and calling any Tcl_FS API
function with such an object will result in no action being taken.
function with such a value will result in no action being taken.
.SS "FS API FUNCTIONS"
\fBTcl_FSCopyFile\fR attempts to copy the file given by \fIsrcPathPtr\fR to the
path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
@@ -484,7 +484,7 @@ If the \fItoPtr\fR is NULL, a
action is performed. The result
is a Tcl_Obj specifying the contents of the symbolic link given by
\fIlinkNamePtr\fR, or NULL if the link could not be read. The result is owned
by the caller, which should call Tcl_DecrRefCount when the result is no
by the caller, which should call \fBTcl_DecrRefCount\fR when the result is no
longer needed. If the \fItoPtr\fR is not NULL, Tcl should create a link
of one of the types passed in in the \fIlinkAction\fR flag. This flag is
an ORed combination of \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
@@ -523,7 +523,7 @@ values of the file given.
attributes\fR subcommand. The appropriate function for the filesystem to
which \fIpathPtr\fR belongs will be called.
.PP
If the result is \fBTCL_OK\fR, then an object was placed in
If the result is \fBTCL_OK\fR, then a value was placed in
\fIobjPtrRef\fR, which
will only be temporarily valid (unless \fBTcl_IncrRefCount\fR is called).
.PP
@@ -541,7 +541,7 @@ will take that list and first increment its reference count before using it.
On completion of that use, Tcl will decrement its reference count. Hence if
the list should be disposed of by Tcl when done, it should have a
reference count of zero, and if the list should not be disposed of, the
filesystem should ensure it retains a reference count to the object.
filesystem should ensure it retains a reference count to the value.
.PP
\fBTcl_FSAccess\fR checks whether the process would be allowed to read,
write or test for existence of the file (or other filesystem object)
@@ -622,29 +622,29 @@ The separator is returned as a Tcl_Obj containing a string of length
.PP
\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which must be a valid
list (which is allowed to have a reference count of zero), and returns the path
object given by considering the first \fIelements\fR elements as valid path
value given by considering the first \fIelements\fR elements as valid path
segments (each path segment may be a complete path, a partial path or
just a single possible directory or file name). If any path segment is
actually an absolute path, then all prior path segments are discarded.
If \fIelements\fR is less than 0, we use the entire list.
.PP
It is possible that the returned object is actually an element
It is possible that the returned value is actually an element
of the given list, so the caller should be careful to increment the
reference count of the result before freeing the list.
.PP
The returned object, typically with a reference count of zero (but it
The returned value, typically with a reference count of zero (but it
could be shared
under some conditions), contains the joined path. The caller must
add a reference count to the object before using it. In particular, the
returned object could be an element of the given list, so freeing the
list might free the object prematurely if no reference count has been taken.
If the number of elements is zero, then the returned object will be
add a reference count to the value before using it. In particular, the
returned value could be an element of the given list, so freeing the
list might free the value prematurely if no reference count has been taken.
If the number of elements is zero, then the returned value will be
an empty-string Tcl_Obj.
.PP
\fBTcl_FSSplitPath\fR takes the given Tcl_Obj, which should be a valid path,
and returns a Tcl list object containing each segment of that path as
and returns a Tcl list value containing each segment of that path as
an element.
It returns a list object with a reference count of zero. If the
It returns a list value with a reference count of zero. If the
passed in \fIlenPtr\fR is non-NULL, the variable it points to will be
updated to contain the number of elements in the returned list.
.PP
@@ -657,7 +657,7 @@ either path is NULL, 0 is always returned.
from the given Tcl_Obj a unique normalized path representation, whose
string value can be used as a unique identifier for the file.
.PP
It returns the normalized path object, owned by Tcl, or NULL if the path
It returns the normalized path value, owned by Tcl, or NULL if the path
was invalid or could otherwise not be successfully converted.
Extraction of absolute, normalized paths is very efficient (because the
filesystem operates on these representations internally), although the
@@ -665,35 +665,36 @@ result when the filesystem contains numerous symbolic links may not be
the most user-friendly version of a path. The return value is owned by
Tcl and has a lifetime equivalent to that of the \fIpathPtr\fR passed in
(unless that is a relative path, in which case the normalized path
object may be freed any time the cwd changes) - the caller can of
course increment the refCount if it wishes to maintain a copy for longer.
value may be freed any time the cwd changes) - the caller can of
course increment the reference count if it wishes to maintain a copy for longer.
.PP
\fBTcl_FSJoinToPath\fR takes the given object, which should usually be a
\fBTcl_FSJoinToPath\fR takes the given value, which should usually be a
valid path or NULL, and joins onto it the array of paths segments
given.
.PP
Returns object, typically with refCount of zero (but it could be shared
Returns a value, typically with reference count of zero (but it could be shared
under some conditions), containing the joined path. The caller must
add a refCount to the object before using it. If any of the objects
passed into this function (pathPtr or path elements) have a refCount
add a reference count to the value before using it. If any of the values
passed into this function (\fIpathPtr\fR or \fIpath\fR elements) have
a reference count
of zero, they will be freed when this function returns.
.PP
\fBTcl_FSConvertToPathType\fR tries to convert the given Tcl_Obj to a valid
Tcl path type, taking account of the fact that the cwd may have changed
even if this object is already supposedly of the correct type.
even if this value is already supposedly of the correct type.
The filename may begin with
.QW ~
(to indicate current user's home directory) or
.QW ~<user>
(to indicate any user's home directory).
.PP
If the conversion succeeds (i.e.\ the object is a valid path in one of
If the conversion succeeds (i.e.\ the value is a valid path in one of
the current filesystems), then \fBTCL_OK\fR is returned. Otherwise
\fBTCL_ERROR\fR is returned, and an error message may
be left in the interpreter.
.PP
\fBTcl_FSGetInternalRep\fR extracts the internal representation of a given
path object, in the given filesystem. If the path object belongs to a
path value, in the given filesystem. If the path value belongs to a
different filesystem, we return NULL. If the internal representation is
currently NULL, we attempt to generate it, by calling the filesystem's
\fBTcl_FSCreateInternalRepProc\fR.
@@ -705,7 +706,7 @@ not require additional conversions.
\fBTcl_FSGetTranslatedPath\fR attempts to extract the translated path
from the given Tcl_Obj.
.PP
If the translation succeeds (i.e.\ the object is a valid path), then it is
If the translation succeeds (i.e.\ the value is a valid path), then it is
returned. Otherwise NULL will be returned, and an error message may be
left in the interpreter. A
.QW translated
@@ -714,8 +715,8 @@ path is one which contains no
or
.QW ~user
sequences (these have been expanded to their current
representation in the filesystem). The object returned is owned by the
caller, which must store it or call Tcl_DecrRefCount to ensure memory is
representation in the filesystem). The value returned is owned by the
caller, which must store it or call \fBTcl_DecrRefCount\fR to ensure memory is
freed. This function is of little practical use, and
\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
better functions to use for most purposes.
@@ -731,11 +732,11 @@ better functions to use for most purposes.
usual obj->path->nativerep conversions. If some code retrieves a path
in native form (from, e.g.\ \fBreadlink\fR or a native dialog), and that path
is to be used at the Tcl level, then calling this function is an
efficient way of creating the appropriate path object type.
efficient way of creating the appropriate path value type.
.PP
The resulting object is a pure
The resulting value is a pure
.QW path
object, which will only receive
value, which will only receive
a UTF-8 string representation if that is required by some Tcl code.
.PP
\fBTcl_FSGetNativePath\fR is for use by the Win/Unix native
@@ -773,7 +774,7 @@ given path within that filesystem (which is filesystem dependent). The
second element may be empty if the filesystem does not provide a
further categorization of files.
.PP
A valid list object is returned, unless the path object is not
A valid list value is returned, unless the path value is not
recognized, when NULL will be returned.
.PP
\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
@@ -1001,14 +1002,14 @@ The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
.SS PATHINFILESYSTEMPROC
.PP
The \fIpathInFilesystemProc\fR field contains the address of a function
which is called to determine whether a given path object belongs to this
which is called to determine whether a given path value belongs to this
filesystem or not. Tcl will only call the rest of the filesystem
functions with a path for which this function has returned \fBTCL_OK\fR.
If the path does not belong, -1 should be returned (the behavior of Tcl
for any other return value is not defined). If \fBTCL_OK\fR is returned,
then the optional \fIclientDataPtr\fR output parameter can be used to
return an internal (filesystem specific) representation of the path,
which will be cached inside the path object, and may be retrieved
which will be cached inside the path value, and may be retrieved
efficiently by the other filesystem functions. Tcl will simultaneously
cache the fact that this path belongs to this filesystem. Such caches
are invalidated when filesystem structures are added or removed from
@@ -1022,7 +1023,7 @@ typedef int \fBTcl_FSPathInFilesystemProc\fR(
.SS DUPINTERNALREPPROC
.PP
This function makes a copy of a path's internal representation, and is
called when Tcl needs to duplicate a path object. If NULL, Tcl will
called when Tcl needs to duplicate a path value. If NULL, Tcl will
simply not copy the internal representation, which may then need to be
regenerated later.
.PP
@@ -1042,8 +1043,8 @@ typedef void \fBTcl_FSFreeInternalRepProc\fR(
.SS INTERNALTONORMALIZEDPROC
.PP
Function to convert internal representation to a normalized path. Only
required if the filesystem creates pure path objects with no string/path
representation. The return value is a Tcl object whose string
required if the filesystem creates pure path values with no string/path
representation. The return value is a Tcl value whose string
representation is the normalized path.
.PP
.CS
@@ -1052,9 +1053,9 @@ typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
.CE
.SS CREATEINTERNALREPPROC
.PP
Function to take a path object, and calculate an internal
Function to take a path value, and calculate an internal
representation for it, and store that native representation in the
object. May be NULL if paths have no internal representation, or if
value. May be NULL if paths have no internal representation, or if
the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
immediately creates an internal representation for paths it accepts.
.PP
@@ -1066,7 +1067,7 @@ typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
.PP
Function to normalize a path. Should be implemented for all
filesystems which can have multiple string representations for the same
path object. In Tcl, every
path value. In Tcl, every
.QW path
must have a single unique
.QW normalized
@@ -1078,7 +1079,7 @@ reference to a home directory such as
.QW ~ ,
a path containing symbolic
links, etc). If the very last component in the path is a symbolic
link, it should not be converted into the object it points to (but
link, it should not be converted into the value it points to (but
its case or other aspects should be made unique). All other path
components should be converted from symbolic links. This one
exception is required to agree with Tcl's semantics with \fBfile
@@ -1122,7 +1123,7 @@ which is returned. A typical return value might be
or
.QW ftp .
The Tcl_Obj result is owned by the filesystem and so Tcl will
increment the refCount of that object if it wishes to retain a reference
increment the reference count of that value if it wishes to retain a reference
to it.
.PP
.CS
@@ -1137,7 +1138,7 @@ different separator than the standard string
.QW / .
Amongst other
uses, it is returned by the \fBfile separator\fR command. The
return value should be an object with refCount of zero.
return value should be a value with reference count of zero.
.PP
.CS
typedef Tcl_Obj *\fBTcl_FSFilesystemSeparatorProc\fR(
@@ -1256,7 +1257,7 @@ The return value is a standard Tcl result indicating whether an error
occurred in the matching process. Error messages are placed in
\fIinterp\fR, unless \fIinterp\fR in NULL in which case no error
message need be generated; on a \fBTCL_OK\fR result, results should be
added to the \fIresultPtr\fR object given (which can be assumed to be a
added to the \fIresultPtr\fR value given (which can be assumed to be a
valid unshared Tcl list). The matches added
to \fIresultPtr\fR should include any path prefix given in \fIpathPtr\fR
(this usually means they will be absolute path specifications).
@@ -1326,7 +1327,7 @@ contents of a link. The result is a Tcl_Obj specifying the contents of
the link given by \fIlinkNamePtr\fR, or NULL if the link could
not be read. The result is owned by the caller (and should therefore
have its ref count incremented before being returned). Any callers
should call Tcl_DecrRefCount on this result when it is no longer needed.
should call \fBTcl_DecrRefCount\fR on this result when it is no longer needed.
If \fItoPtr\fR is not NULL, the function should attempt to create a link.
The result in this case should be \fItoPtr\fR if the link was successful
and NULL otherwise. In this case the result is not owned by the caller
@@ -1344,16 +1345,16 @@ typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
.CE
.PP
The result should be a list of volumes added by this filesystem, or
NULL (or an empty list) if no volumes are provided. The result object
NULL (or an empty list) if no volumes are provided. The result value
is considered to be owned by the filesystem (not by Tcl's core), but
should be given a refCount for Tcl. Tcl will use the contents of the
list and then decrement that refCount. This allows filesystems to
should be given a reference count for Tcl. Tcl will use the contents of the
list and then decrement that reference count. This allows filesystems to
choose whether they actually want to retain a
.QW "master list"
of volumes
or not (if not, they generate the list on the fly and pass it to Tcl
with a refCount of 1 and then forget about the list, if yes, then
they simply increment the refCount of their master list and pass it
with a reference count of 1 and then forget about the list, if yes, then
they simply increment the reference count of their master list and pass it
to Tcl which will copy the contents and then decrement the count back
to where it was).
.PP
@@ -1379,7 +1380,7 @@ will take that list and first increment its reference count before using it.
On completion of that use, Tcl will decrement its reference count. Hence if
the list should be disposed of by Tcl when done, it should have a
reference count of zero, and if the list should not be disposed of, the
filesystem should ensure it returns an object with a reference count
filesystem should ensure it returns a value with a reference count
of at least one.
.SS FILEATTRSGETPROC
.PP
+4 -4
View File
@@ -26,7 +26,7 @@ int
Interpreter to use for error reporting; if NULL, then no message is
provided on errors.
.AP Tcl_Obj *objPtr in/out
The string value of this object is used to search through \fItablePtr\fR.
The string value of this value is used to search through \fItablePtr\fR.
The internal representation is modified to hold the index of the matching
table entry.
.AP "const char *const" *tablePtr in
@@ -58,8 +58,8 @@ The index of the string in \fItablePtr\fR that matches the value of
.SH DESCRIPTION
.PP
These procedures provide an efficient way for looking up keywords,
switch names, option names, and similar things where the value of
an object must be one of a predefined set of values.
switch names, option names, and similar things where the literal value of
a Tcl value must be chosen from a predefined set.
\fBTcl_GetIndexFromObj\fR compares \fIobjPtr\fR against each of
the strings in \fItablePtr\fR to find a match. A match occurs if
\fIobjPtr\fR's string value is identical to one of the strings in
@@ -101,4 +101,4 @@ each of several array elements.
.SH "SEE ALSO"
prefix(n), Tcl_WrongNumArgs(3)
.SH KEYWORDS
index, object, table lookup
index, option, value, table lookup
+4 -4
View File
@@ -310,14 +310,14 @@ typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
void *\fIkeyPtr\fR);
.CE
.PP
If this is NULL then Tcl_Alloc is used to allocate enough space for a
If this is NULL then \fBTcl_Alloc\fR is used to allocate enough space for a
Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
clientData is set to NULL. String keys and array keys use this function to
allocate enough space for the entry and the key in one block, rather than
doing it in two blocks. This saves space for a pointer to the key from the
entry and another memory allocation. Tcl_Obj* keys use this function to
allocate enough space for an entry and increment the reference count on the
object.
value.
.PP
The \fIfreeEntryProc\fR member contains the address of a function called to
free space for an entry.
@@ -327,8 +327,8 @@ typedef void \fBTcl_FreeHashEntryProc\fR(
Tcl_HashEntry *\fIhPtr\fR);
.CE
.PP
If this is NULL then Tcl_Free is used to free the space for the entry.
If this is NULL then \fBTcl_Free\fR is used to free the space for the entry.
Tcl_Obj* keys use this function to decrement the reference count on the
object.
value.
.SH KEYWORDS
hash table, key, lookup, search, value
+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
+16 -15
View File
@@ -8,7 +8,7 @@
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl objects as integer values
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -56,17 +56,17 @@ int
.SH ARGUMENTS
.AS Tcl_WideInt doubleValue in/out
.AP int intValue in
Integer value used to initialize or set a Tcl object.
Integer value used to initialize or set a Tcl value.
.AP long longValue in
Long integer value used to initialize or set a Tcl object.
Long integer value used to initialize or set a Tcl value.
.AP Tcl_WideInt wideValue in
Wide integer value used to initialize or set a Tcl object.
Wide integer value used to initialize or set a Tcl value.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
and \fBTcl_SetBignumObj\fR, this points to the object in which to store an
and \fBTcl_SetBignumObj\fR, this points to the value in which to store an
integral value. For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR, this refers to the object from which
\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
to retrieve an integral value.
.AP Tcl_Interp *interp in/out
When non-NULL, an error message is left here when integral value
@@ -86,7 +86,7 @@ used to initialize a multi-precision integer value.
.BE
.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl objects
These procedures are used to create, modify, and read Tcl values
that hold integral values.
.PP
The different routines exist to accommodate different integral types in C
@@ -103,22 +103,22 @@ by the LibTomMath multiple-precision integer library.
.PP
The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
and \fBTcl_NewBignumObj\fR routines each create and return a new
Tcl object initialized to the integral value of the argument. The
returned Tcl object is unshared.
Tcl value initialized to the integral value of the argument. The
returned Tcl value is unshared.
.PP
The \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
and \fBTcl_SetBignumObj\fR routines each set the value of an existing
Tcl object pointed to by \fIobjPtr\fR to the integral value provided
Tcl value pointed to by \fIobjPtr\fR to the integral value provided
by the other argument. The \fIobjPtr\fR argument must point to an
unshared Tcl object. Any attempt to set the value of a shared Tcl object
unshared Tcl value. Any attempt to set the value of a shared Tcl value
violates Tcl's copy-on-write policy. Any existing string representation
or internal representation in the unshared Tcl object will be freed
or internal representation in the unshared Tcl value will be freed
as a consequence of setting the new value.
.PP
The \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
value of the appropriate type from the Tcl object \fIobjPtr\fR. If the
value of the appropriate type from the Tcl value \fIobjPtr\fR. If the
attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
written to the storage provided by the caller. The attempt might
fail if \fIobjPtr\fR does not hold an integral value, or if the
@@ -127,7 +127,7 @@ then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
an error message is left in \fIinterp\fR. The \fBTcl_ObjType\fR
of \fIobjPtr\fR may be changed to make subsequent calls to the
same routine more efficient. Unlike the other functions,
\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl object
\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl value
\fIobjPtr\fR to an empty string in the process of retrieving the
multiple-precision integer value.
.PP
@@ -148,4 +148,5 @@ integer value in the \fBmp_int\fR value \fIbigValue\fR.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
.SH KEYWORDS
integer, integer object, integer type, internal representation, object, object type, string representation
integer, integer value, integer type, internal representation, value,
value type, string representation
+59 -58
View File
@@ -8,7 +8,7 @@
.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl values as lists
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -38,44 +38,44 @@ int
.SH ARGUMENTS
.AS "Tcl_Obj *const" *elemListPtr in/out
.AP Tcl_Interp *interp in
If an error occurs while converting an object to be a list object,
an error message is left in the interpreter's result object
If an error occurs while converting a value to be a list value,
an error message is left in the interpreter's result value
unless \fIinterp\fR is NULL.
.AP Tcl_Obj *listPtr in/out
Points to the list object to be manipulated.
If \fIlistPtr\fR does not already point to a list object,
Points to the list value to be manipulated.
If \fIlistPtr\fR does not already point to a list value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *elemListPtr in/out
For \fBTcl_ListObjAppendList\fR, this points to a list object
For \fBTcl_ListObjAppendList\fR, this points to a list value
containing elements to be appended onto \fIlistPtr\fR.
Each element of *\fIelemListPtr\fR will
become a new element of \fIlistPtr\fR.
If *\fIelemListPtr\fR is not NULL and
does not already point to a list object,
does not already point to a list value,
an attempt will be made to convert it to one.
.AP Tcl_Obj *objPtr in
For \fBTcl_ListObjAppendElement\fR,
points to the Tcl object that will be appended to \fIlistPtr\fR.
points to the Tcl value that will be appended to \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
this points to the Tcl object that will be converted to a list object
this points to the Tcl value that will be converted to a list value
containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
.AP int *objcPtr in
Points to location where \fBTcl_ListObjGetElements\fR
stores the number of element objects in \fIlistPtr\fR.
stores the number of element values in \fIlistPtr\fR.
.AP Tcl_Obj ***objvPtr out
A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
of pointers to the element objects of \fIlistPtr\fR.
of pointers to the element values of \fIlistPtr\fR.
.AP int objc in
The number of Tcl objects that \fBTcl_NewListObj\fR
will insert into a new list object,
The number of Tcl values that \fBTcl_NewListObj\fR
will insert into a new list value,
and \fBTcl_ListObjReplace\fR will insert into \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
the number of Tcl objects to insert into \fIobjPtr\fR.
the number of Tcl values to insert into \fIobjPtr\fR.
.AP "Tcl_Obj *const" objv[] in
An array of pointers to objects.
\fBTcl_NewListObj\fR will insert these objects into a new list object
An array of pointers to values.
\fBTcl_NewListObj\fR will insert these values into a new list value
and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
Each object will become a separate list element.
Each value will become a separate list element.
.AP int *intPtr out
Points to location where \fBTcl_ListObjLength\fR
stores the length of the list.
@@ -85,7 +85,7 @@ is to return.
The first element has index 0.
.AP Tcl_Obj **objPtrPtr out
Points to place where \fBTcl_ListObjIndex\fR is to store
a pointer to the resulting list element object.
a pointer to the resulting list element value.
.AP int first in
Index of the starting list element that \fBTcl_ListObjReplace\fR
is to replace.
@@ -97,85 +97,85 @@ is to replace.
.SH DESCRIPTION
.PP
Tcl list objects have an internal representation that supports
Tcl list values have an internal representation that supports
the efficient indexing and appending.
The procedures described in this man page are used to
create, modify, index, and append to Tcl list objects from C code.
create, modify, index, and append to Tcl list values from C code.
.PP
\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
both add one or more objects
to the end of the list object referenced by \fIlistPtr\fR.
\fBTcl_ListObjAppendList\fR appends each element of the list object
both add one or more values
to the end of the list value referenced by \fIlistPtr\fR.
\fBTcl_ListObjAppendList\fR appends each element of the list value
referenced by \fIelemListPtr\fR while
\fBTcl_ListObjAppendElement\fR appends the single object
\fBTcl_ListObjAppendElement\fR appends the single value
referenced by \fIobjPtr\fR.
Both procedures will convert the object referenced by \fIlistPtr\fR
to a list object if necessary.
Both procedures will convert the value referenced by \fIlistPtr\fR
to a list value if necessary.
If an error occurs during conversion,
both procedures return \fBTCL_ERROR\fR and leave an error message
in the interpreter's result object if \fIinterp\fR is not NULL.
Similarly, if \fIelemListPtr\fR does not already refer to a list object,
in the interpreter's result value if \fIinterp\fR is not NULL.
Similarly, if \fIelemListPtr\fR does not already refer to a list value,
\fBTcl_ListObjAppendList\fR will attempt to convert it to one
and if an error occurs during conversion,
will return \fBTCL_ERROR\fR
and leave an error message in the interpreter's result object
and leave an error message in the interpreter's result value
if interp is not NULL.
Both procedures invalidate any old string representation of \fIlistPtr\fR
and, if it was converted to a list object,
and, if it was converted to a list value,
free any old internal representation.
Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
of \fIelemListPtr\fR if it converts it to a list object.
of \fIelemListPtr\fR if it converts it to a list value.
After appending each element in \fIelemListPtr\fR,
\fBTcl_ListObjAppendList\fR increments the element's reference count
since \fIlistPtr\fR now also refers to it.
For the same reason, \fBTcl_ListObjAppendElement\fR
increments \fIobjPtr\fR's reference count.
If no error occurs,
the two procedures return \fBTCL_OK\fR after appending the objects.
the two procedures return \fBTCL_OK\fR after appending the values.
.PP
\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
create a new object or modify an existing object to hold
create a new value or modify an existing value to hold
the \fIobjc\fR elements of the array referenced by \fIobjv\fR
where each element is a pointer to a Tcl object.
where each element is a pointer to a Tcl value.
If \fIobjc\fR is less than or equal to zero,
they return an empty object.
The new object's string representation is left invalid.
they return an empty value.
The new value's string representation is left invalid.
The two procedures increment the reference counts
of the elements in \fIobjc\fR since the list object now refers to them.
The new list object returned by \fBTcl_NewListObj\fR
of the elements in \fIobjc\fR since the list value now refers to them.
The new list value returned by \fBTcl_NewListObj\fR
has reference count zero.
.PP
\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
the elements in a list object. It returns the count by storing it in the
the elements in a list value. It returns the count by storing it in the
address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
it in the address \fIobjvPtr\fR.
The memory pointed to is managed by Tcl and should not be freed or written
to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
and NULL at \fIobjvPtr\fR.
If \fIlistPtr\fR is not already a list object, \fBTcl_ListObjGetElements\fR
If \fIlistPtr\fR is not already a list value, \fBTcl_ListObjGetElements\fR
will attempt to convert it to one; if the conversion fails, it returns
\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
object if \fIinterp\fR is not NULL.
value if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
.PP
\fBTcl_ListObjLength\fR returns the number of elements in the list object
\fBTcl_ListObjLength\fR returns the number of elements in the list value
referenced by \fIlistPtr\fR.
It returns this count by storing an integer in the address \fIintPtr\fR.
If the object is not already a list object,
If the value is not already a list value,
\fBTcl_ListObjLength\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result object
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
Otherwise it returns \fBTCL_OK\fR after storing the list's length.
.PP
The procedure \fBTcl_ListObjIndex\fR returns a pointer to the object
The procedure \fBTcl_ListObjIndex\fR returns a pointer to the value
at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
It returns this object by storing a pointer to it
It returns this value by storing a pointer to it
in the address \fIobjPtrPtr\fR.
If \fIlistPtr\fR does not already refer to a list object,
If \fIlistPtr\fR does not already refer to a list value,
\fBTcl_ListObjIndex\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result object
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
If the index is out of range,
that is, \fIindex\fR is negative or
@@ -183,19 +183,19 @@ greater than or equal to the number of elements in the list,
\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
and returns \fBTCL_OK\fR.
Otherwise it returns \fBTCL_OK\fR after storing the element's
object pointer.
value pointer.
The reference count for the list element is not incremented;
the caller must do that if it needs to retain a pointer to the element.
.PP
\fBTcl_ListObjReplace\fR replaces zero or more elements
of the list referenced by \fIlistPtr\fR
with the \fIobjc\fR objects in the array referenced by \fIobjv\fR.
If \fIlistPtr\fR does not point to a list object,
with the \fIobjc\fR values in the array referenced by \fIobjv\fR.
If \fIlistPtr\fR does not point to a list value,
\fBTcl_ListObjReplace\fR will attempt to convert it to one;
if the conversion fails, it returns \fBTCL_ERROR\fR
and leaves an error message in the interpreter's result object
and leaves an error message in the interpreter's result value
if \fIinterp\fR is not NULL.
Otherwise, it returns \fBTCL_OK\fR after replacing the objects.
Otherwise, it returns \fBTCL_OK\fR after replacing the values.
If \fIobjv\fR is NULL, no new elements are added.
If the argument \fIfirst\fR is zero or negative,
it refers to the first element.
@@ -210,13 +210,13 @@ designated by \fIfirst\fR.
old string representation.
The reference counts of any elements inserted from \fIobjv\fR
are incremented since the resulting list now refers to them.
Similarly, the reference counts for any replaced objects are decremented.
Similarly, the reference counts for any replaced values are decremented.
.PP
Because \fBTcl_ListObjReplace\fR combines
both element insertion and deletion,
it can be used to implement a number of list operations.
For example, the following code inserts the \fIobjc\fR objects
referenced by the array of object pointers \fIobjv\fR
For example, the following code inserts the \fIobjc\fR values
referenced by the array of value pointers \fIobjv\fR
just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
.PP
.CS
@@ -224,7 +224,7 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, index, 0,
objc, objv);
.CE
.PP
Similarly, the following code appends the \fIobjc\fR objects
Similarly, the following code appends the \fIobjc\fR values
referenced by the array \fIobjv\fR
to the end of the list \fIlistPtr\fR:
.PP
@@ -247,4 +247,5 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
.SH KEYWORDS
append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
append, index, insert, internal representation, length, list, list value,
list type, value, value type, replace, string representation
+2 -1
View File
@@ -31,7 +31,8 @@ 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
Reserved for future expansion. Must be 0.
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
the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
+4 -4
View File
@@ -57,7 +57,7 @@ is \fBNULL\fR, then no procedure is called before the command is deleted.
.AP int objc in
Count of parameters provided to the implementation of a command.
.AP Tcl_Obj **objv in
Pointer to an array of Tcl objects. Each object holds the value of a
Pointer to an array of Tcl values. Each value holds the value of a
single word in the command to execute.
.AP Tcl_Obj *objPtr in
Pointer to a Tcl_Obj whose value is a script or expression to execute.
@@ -141,7 +141,7 @@ trampoline.
.PP
\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
resolution is already known. The \fIcmd\fR parameter gives a
\fBTcl_Command\fR object (returned from \fBTcl_CreateObjCommand\fR or
\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.
@@ -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
@@ -323,6 +323,6 @@ and the second is for use when there is already a trampoline in place.
.SH "SEE ALSO"
Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
.SH KEYWORDS
stackless, nonrecursive, execute, command, global, object, result, script
stackless, nonrecursive, execute, command, global, value, result, script
.SH COPYRIGHT
Copyright (c) 2008 by Kevin B. Kenny
+1 -1
View File
@@ -67,7 +67,7 @@ if no such callback is to be performed.
The namespace to be manipulated, or NULL (for other than
\fBTcl_DeleteNamespace\fR) to manipulate the current namespace.
.AP Tcl_Obj *objPtr out
A reference to an unshared object to which the function output will be
A reference to an unshared value to which the function output will be
written.
.AP "const char" *pattern in
The glob-style pattern (see \fBTcl_StringMatch\fR) that describes the
+90 -88
View File
@@ -8,7 +8,7 @@
.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl objects
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -30,35 +30,36 @@ int
.SH ARGUMENTS
.AS Tcl_Obj *objPtr
.AP Tcl_Obj *objPtr in
Points to an object;
Points to a value;
must have been the result of a previous call to \fBTcl_NewObj\fR.
.BE
.SH INTRODUCTION
.PP
This man page presents an overview of Tcl objects and how they are used.
It also describes generic procedures for managing Tcl objects.
These procedures are used to create and copy objects,
and increment and decrement the count of references (pointers) to objects.
This man page presents an overview of Tcl values (called \fBTcl_Obj\fRs for
historical reasons) and how they are used.
It also describes generic procedures for managing Tcl values.
These procedures are used to create and copy values,
and increment and decrement the count of references (pointers) to values.
The procedures are used in conjunction with ones
that operate on specific types of objects such as
that operate on specific types of values such as
\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
The individual procedures are described along with the data structures
they manipulate.
.PP
Tcl's \fIdual-ported\fR objects provide a general-purpose mechanism
Tcl's \fIdual-ported\fR values provide a general-purpose mechanism
for storing and exchanging Tcl values.
They largely replace the use of strings in Tcl.
For example, they are used to store variable values,
command arguments, command results, and scripts.
Tcl objects behave like strings but also hold an internal representation
Tcl values behave like strings but also hold an internal representation
that can be manipulated more efficiently.
For example, a Tcl list is now represented as an object
For example, a Tcl list is now represented as a value
that holds the list's string representation
as well as an array of pointers to the objects for each list element.
Dual-ported objects avoid most runtime type conversions.
as well as an array of pointers to the values for each list element.
Dual-ported values avoid most runtime type conversions.
They also improve the speed of many operations
since an appropriate representation is immediately available.
The compiler itself uses Tcl objects to
The compiler itself uses Tcl values to
cache the instruction bytecodes resulting from compiling scripts.
.PP
The two representations are a cache of each other and are computed lazily.
@@ -73,39 +74,39 @@ between integers and strings.
Only when it needs a string representing the variable's value,
say to print it,
will the program regenerate the string representation from the integer.
Although objects contain an internal representation,
Although values contain an internal representation,
their semantics are defined in terms of strings:
an up-to-date string can always be obtained,
and any change to the object will be reflected in that string
when the object's string representation is fetched.
and any change to the value will be reflected in that string
when the value's string representation is fetched.
Because of this representation invalidation and regeneration,
it is dangerous for extension writers to access
\fBTcl_Obj\fR fields directly.
It is better to access Tcl_Obj information using
procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
.PP
Objects are allocated on the heap
Values are allocated on the heap
and are referenced using a pointer to their \fBTcl_Obj\fR structure.
Objects are shared as much as possible.
Values are shared as much as possible.
This significantly reduces storage requirements
because some objects such as long lists are very large.
because some values such as long lists are very large.
Also, most Tcl values are only read and never modified.
This is especially true for procedure arguments,
which can be shared between the caller and the called procedure.
Assignment and argument binding is done by
simply assigning a pointer to the value.
Reference counting is used to determine when it is safe to
reclaim an object's storage.
reclaim a value's storage.
.PP
Tcl objects are typed.
An object's internal representation is controlled by its type.
Tcl values are typed.
A value's internal representation is controlled by its type.
Several types are predefined in the Tcl core
including integer, double, list, and bytecode.
Extension writers can extend the set of types
by defining their own \fBTcl_ObjType\fR structs.
.SH "THE TCL_OBJ STRUCTURE"
.PP
Each Tcl object is represented by a \fBTcl_Obj\fR structure
Each Tcl value is represented by a \fBTcl_Obj\fR structure
which is defined as follows.
.PP
.CS
@@ -132,7 +133,7 @@ typedef struct Tcl_Obj {
.CE
.PP
The \fIbytes\fR and the \fIlength\fR members together hold
an object's UTF-8 string representation,
a value's UTF-8 string representation,
which is a \fIcounted string\fR not containing null bytes (UTF-8 null
characters should be encoded as a two byte sequence: 192, 128.)
\fIbytes\fR points to the first byte of the string representation.
@@ -142,31 +143,31 @@ at offset \fIlength\fR;
this allows string representations
to be treated as conventional null-terminated C strings.
C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
an object's string representation.
a value's string representation.
If \fIbytes\fR is NULL,
the string representation is invalid.
.PP
An object's type manages its internal representation.
A value's type manages its internal representation.
The member \fItypePtr\fR points to the Tcl_ObjType structure
that describes the type.
If \fItypePtr\fR is NULL,
the internal representation is invalid.
.PP
The \fIinternalRep\fR union member holds
an object's internal representation.
a value's internal representation.
This is either a (long) integer, a double-precision floating-point number,
a pointer to a value containing additional information
needed by the object's type to represent the object, a Tcl_WideInt
needed by the value's type to represent the value, a Tcl_WideInt
integer, two arbitrary pointers, or a pair made up of an unsigned long
integer and a pointer.
.PP
The \fIrefCount\fR member is used to tell when it is safe to free
an object's storage.
It holds the count of active references to the object.
a value's storage.
It holds the count of active references to the value.
Maintaining the correct reference count is a key responsibility
of extension writers.
Reference counting is discussed below
in the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR.
in the section \fBSTORAGE MANAGEMENT OF VALUES\fR.
.PP
Although extension writers can directly access
the members of a Tcl_Obj structure,
@@ -176,21 +177,21 @@ read or update \fIrefCount\fR directly;
they should use macros such as
\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
.PP
A key property of Tcl objects is that they hold two representations.
An object typically starts out containing only a string representation:
A key property of Tcl values is that they hold two representations.
A value typically starts out containing only a string representation:
it is untyped and has a NULL \fItypePtr\fR.
An object containing an empty string or a copy of a specified string
A value containing an empty string or a copy of a specified string
is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
An object's string value is gotten with
A value's string value is gotten with
\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
and changed with \fBTcl_SetStringObj\fR.
If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
If the value is later passed to a procedure like \fBTcl_GetIntFromObj\fR
that requires a specific internal representation,
the procedure will create one and set the object's \fItypePtr\fR.
the procedure will create one and set the value's \fItypePtr\fR.
The internal representation is computed from the string representation.
An object's two representations are duals of each other:
A value's two representations are duals of each other:
changes made to one are reflected in the other.
For example, \fBTcl_ListObjReplace\fR will modify an object's
For example, \fBTcl_ListObjReplace\fR will modify a value's
internal representation and the next call to \fBTcl_GetStringFromObj\fR
or \fBTcl_GetString\fR will reflect that change.
.PP
@@ -203,43 +204,43 @@ so that it is only regenerated if it is needed later.
Most C programmers never have to be concerned with how this is done
and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
\fBTcl_ListObjIndex\fR.
Programmers that implement their own object types
Programmers that implement their own value types
must check for invalid representations
and mark representations invalid when necessary.
The procedure \fBTcl_InvalidateStringRep\fR is used
to mark an object's string representation invalid and to
to mark a value's string representation invalid and to
free any storage associated with the old string representation.
.PP
Objects usually remain one type over their life,
but occasionally an object must be converted from one type to another.
For example, a C program might build up a string in an object
Values usually remain one type over their life,
but occasionally a value must be converted from one type to another.
For example, a C program might build up a string in a value
with repeated calls to \fBTcl_AppendToObj\fR,
and then call \fBTcl_ListObjIndex\fR to extract a list element from
the object.
The same object holding the same string value
the value.
The same value holding the same string value
can have several different internal representations
at different times.
Extension writers can also force an object to be converted from one type
Extension writers can also force a value to be converted from one type
to another using the \fBTcl_ConvertToType\fR procedure.
Only programmers that create new object types need to be concerned
Only programmers that create new value types need to be concerned
about how this is done.
A procedure defined as part of the object type's implementation
creates a new internal representation for an object
A procedure defined as part of the value type's implementation
creates a new internal representation for a value
and changes its \fItypePtr\fR.
See the man page for \fBTcl_RegisterObjType\fR
to see how to create a new object type.
.SH "EXAMPLE OF THE LIFETIME OF AN OBJECT"
to see how to create a new value type.
.SH "EXAMPLE OF THE LIFETIME OF A VALUE"
.PP
As an example of the lifetime of an object,
As an example of the lifetime of a value,
consider the following sequence of commands:
.PP
.CS
\fBset x 123\fR
.CE
.PP
This assigns to \fIx\fR an untyped object whose
This assigns to \fIx\fR an untyped value whose
\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
The object's \fItypePtr\fR member is NULL.
The value's \fItypePtr\fR member is NULL.
.PP
.CS
\fBputs "x is $x"\fR
@@ -252,16 +253,16 @@ and is fetched for the command.
\fBincr x\fR
.CE
.PP
The \fBincr\fR command first gets an integer from \fIx\fR's object
The \fBincr\fR command first gets an integer from \fIx\fR's value
by calling \fBTcl_GetIntFromObj\fR.
This procedure checks whether the object is already an integer object.
Since it is not, it converts the object
by setting the object's \fIinternalRep.longValue\fR member
This procedure checks whether the value is already an integer value.
Since it is not, it converts the value
by setting the value's \fIinternalRep.longValue\fR member
to the integer \fB123\fR
and setting the object's \fItypePtr\fR
and setting the value's \fItypePtr\fR
to point to the integer Tcl_ObjType structure.
Both representations are now valid.
\fBincr\fR increments the object's integer internal representation
\fBincr\fR increments the value's integer internal representation
then invalidates its string representation
(by calling \fBTcl_InvalidateStringRep\fR)
since the string representation
@@ -271,31 +272,31 @@ no longer corresponds to the internal representation.
\fBputs "x is now $x"\fR
.CE
.PP
The string representation of \fIx\fR's object is needed
The string representation of \fIx\fR's value is needed
and is recomputed.
The string representation is now \fB124\fR
and both representations are again valid.
.SH "STORAGE MANAGEMENT OF OBJECTS"
.SH "STORAGE MANAGEMENT OF VALUES"
.PP
Tcl objects are allocated on the heap and are shared as much as possible
Tcl values are allocated on the heap and are shared as much as possible
to reduce storage requirements.
Reference counting is used to determine when an object is
Reference counting is used to determine when a value is
no longer needed and can safely be freed.
An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
A value just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
has \fIrefCount\fR 0.
The macro \fBTcl_IncrRefCount\fR increments the reference count
when a new reference to the object is created.
when a new reference to the value is created.
The macro \fBTcl_DecrRefCount\fR decrements the count
when a reference is no longer needed and,
if the object's reference count drops to zero, frees its storage.
An object shared by different code or data structures has
if the value's reference count drops to zero, frees its storage.
A value shared by different code or data structures has
\fIrefCount\fR greater than 1.
Incrementing an object's reference count ensures that
Incrementing a value's reference count ensures that
it will not be freed too early or have its value change accidentally.
.PP
As an example, the bytecode interpreter shares argument objects
between calling and called Tcl procedures to avoid having to copy objects.
It assigns the call's argument objects to the procedure's
As an example, the bytecode interpreter shares argument values
between calling and called Tcl procedures to avoid having to copy values.
It assigns the call's argument values to the procedure's
formal parameter variables.
In doing so, it calls \fBTcl_IncrRefCount\fR to increment
the reference count of each argument since there is now a new
@@ -303,31 +304,31 @@ reference to it from the formal parameter.
When the called procedure returns,
the interpreter calls \fBTcl_DecrRefCount\fR to decrement
each argument's reference count.
When an object's reference count drops less than or equal to zero,
When a value's reference count drops less than or equal to zero,
\fBTcl_DecrRefCount\fR reclaims its storage.
Most command procedures do not have to be concerned about
reference counting since they use an object's value immediately
and do not retain a pointer to the object after they return.
However, if they do retain a pointer to an object in a data structure,
reference counting since they use a value's value immediately
and do not retain a pointer to the value after they return.
However, if they do retain a pointer to a value in a data structure,
they must be careful to increment its reference count
since the retained pointer is a new reference.
.PP
Command procedures that directly modify objects
Command procedures that directly modify values
such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
copy a shared object before changing it.
They must first check whether the object is shared
copy a shared value before changing it.
They must first check whether the value is shared
by calling \fBTcl_IsShared\fR.
If the object is shared they must copy the object
If the value is shared they must copy the value
by using \fBTcl_DuplicateObj\fR;
this returns a new duplicate of the original object
this returns a new duplicate of the original value
that has \fIrefCount\fR 0.
If the object is not shared,
If the value is not shared,
the command procedure
.QW "owns"
the object and can safely modify it directly.
the value and can safely modify it directly.
For example, the following code appears in the command procedure
that implements \fBlinsert\fR.
This procedure modifies the list object passed to it in \fIobjv[1]\fR
This procedure modifies the list value passed to it in \fIobjv[1]\fR
by inserting \fIobjc-3\fR new elements before \fIindex\fR.
.PP
.CS
@@ -340,11 +341,12 @@ result = Tcl_ListObjReplace(interp, listPtr, index, 0,
.CE
.PP
As another example, \fBincr\fR's command procedure
must check whether the variable's object is shared before
must check whether the variable's value is shared before
incrementing the integer in its internal representation.
If it is shared, it needs to duplicate the object
If it is shared, it needs to duplicate the value
in order to avoid accidentally changing values in other data structures.
.SH "SEE ALSO"
Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
.SH KEYWORDS
internal representation, object, object creation, object type, reference counting, string representation, type conversion
internal representation, value, value creation, value type,
reference counting, string representation, type conversion
+32 -31
View File
@@ -8,7 +8,7 @@
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl object types
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl value types
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -26,31 +26,32 @@ int
.SH ARGUMENTS
.AS "const char" *typeName
.AP "const Tcl_ObjType" *typePtr in
Points to the structure containing information about the Tcl object type.
Points to the structure containing information about the Tcl value type.
This storage must live forever,
typically by being statically allocated.
.AP "const char" *typeName in
The name of a Tcl object type that \fBTcl_GetObjType\fR should look up.
The name of a Tcl value type that \fBTcl_GetObjType\fR should look up.
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tcl_Obj *objPtr in
For \fBTcl_AppendAllObjTypes\fR, this points to the object onto which
it appends the name of each object type as a list element.
For \fBTcl_ConvertToType\fR, this points to an object that
For \fBTcl_AppendAllObjTypes\fR, this points to the value onto which
it appends the name of each value type as a list element.
For \fBTcl_ConvertToType\fR, this points to a value that
must have been the result of a previous call to \fBTcl_NewObj\fR.
.BE
.SH DESCRIPTION
.PP
The procedures in this man page manage Tcl object types.
They are used to register new object types, look up types,
The procedures in this man page manage Tcl value types (sometimes
referred to as object types or \fBTcl_ObjType\fRs for historical reasons).
They are used to register new value types, look up types,
and force conversions from one type to another.
.PP
\fBTcl_RegisterObjType\fR registers a new Tcl object type
in the table of all object types that \fBTcl_GetObjType\fR
can look up by name. There are other object types supported by Tcl
\fBTcl_RegisterObjType\fR registers a new Tcl value type
in the table of all value types that \fBTcl_GetObjType\fR
can look up by name. There are other value types supported by Tcl
as well, which Tcl chooses not to register. Extensions can likewise
choose to register the object types they create or not.
choose to register the value types they create or not.
The argument \fItypePtr\fR points to a Tcl_ObjType structure that
describes the new type by giving its name
and by supplying pointers to four procedures
@@ -65,13 +66,13 @@ in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
with name \fItypeName\fR.
It returns NULL if no type with that name is registered.
.PP
\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type
as a list element onto the Tcl object referenced by \fIobjPtr\fR.
\fBTcl_AppendAllObjTypes\fR appends the name of each registered value type
as a list element onto the Tcl value referenced by \fIobjPtr\fR.
The return value is \fBTCL_OK\fR unless there was an error
converting \fIobjPtr\fR to a list object;
converting \fIobjPtr\fR to a list value;
in that case \fBTCL_ERROR\fR is returned.
.PP
\fBTcl_ConvertToType\fR converts an object from one type to another
\fBTcl_ConvertToType\fR converts a value from one type to another
if possible.
It creates a new internal representation for \fIobjPtr\fR
appropriate for the target type \fItypePtr\fR
@@ -79,7 +80,7 @@ and sets its \fItypePtr\fR member as determined by calling the
\fItypePtr->setFromAnyProc\fR routine.
Any internal representation for \fIobjPtr\fR's old type is freed.
If an error occurs during conversion, it returns \fBTCL_ERROR\fR
and leaves an error message in the result object for \fIinterp\fR
and leaves an error message in the result value for \fIinterp\fR
unless \fIinterp\fR is NULL.
Otherwise, it returns \fBTCL_OK\fR.
Passing a NULL \fIinterp\fR allows this procedure to be used
@@ -94,7 +95,7 @@ use of another related Tcl_ObjType, if it sees fit.
.VE 8.5
.SH "THE TCL_OBJTYPE STRUCTURE"
.PP
Extension writers can define new object types by defining four
Extension writers can define new value types by defining four
procedures and
initializing a Tcl_ObjType structure to describe the type.
Extension writers may also pass a pointer to their Tcl_ObjType
@@ -119,12 +120,12 @@ When a type is registered, this is the name used by callers
of \fBTcl_GetObjType\fR to lookup the type. For unregistered
types, the \fIname\fR field is primarily of value for debugging.
The remaining four members are pointers to procedures
called by the generic Tcl object code:
called by the generic Tcl value code:
.SS "THE SETFROMANYPROC FIELD"
.PP
The \fIsetFromAnyProc\fR member contains the address of a function
called to create a valid internal representation
from an object's string representation.
from a value's string representation.
.PP
.CS
typedef int \fBTcl_SetFromAnyProc\fR(
@@ -134,7 +135,7 @@ typedef int \fBTcl_SetFromAnyProc\fR(
.PP
If an internal representation cannot be created from the string,
it returns \fBTCL_ERROR\fR and puts a message
describing the error in the result object for \fIinterp\fR
describing the error in the result value for \fIinterp\fR
unless \fIinterp\fR is NULL.
If \fIsetFromAnyProc\fR is successful,
it stores the new internal representation,
@@ -169,7 +170,7 @@ should \fInot\fR be registered.
.PP
The \fIupdateStringProc\fR member contains the address of a function
called to create a valid string representation
from an object's internal representation.
from a value's internal representation.
.PP
.CS
typedef void \fBTcl_UpdateStringProc\fR(
@@ -203,7 +204,7 @@ or other similar routines ask for the string representation.
.SS "THE DUPINTREPPROC FIELD"
.PP
The \fIdupIntRepProc\fR member contains the address of a function
called to copy an internal representation from one object to another.
called to copy an internal representation from one value to another.
.PP
.CS
typedef void \fBTcl_DupInternalRepProc\fR(
@@ -215,7 +216,7 @@ typedef void \fBTcl_DupInternalRepProc\fR(
internal representation.
Before the call,
\fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not.
\fIsrcPtr\fR's object type determines what
\fIsrcPtr\fR's value type determines what
copying its internal representation means.
.PP
For example, the \fIdupIntRepProc\fR for the Tcl integer type
@@ -226,7 +227,7 @@ reasonably can.
.SS "THE FREEINTREPPROC FIELD"
.PP
The \fIfreeIntRepProc\fR member contains the address of a function
that is called when an object is freed.
that is called when a value is freed.
.PP
.CS
typedef void \fBTcl_FreeInternalRepProc\fR(
@@ -234,22 +235,22 @@ typedef void \fBTcl_FreeInternalRepProc\fR(
.CE
.PP
The \fIfreeIntRepProc\fR function can deallocate the storage
for the object's internal representation
and do other type-specific processing necessary when an object is freed.
for the value's internal representation
and do other type-specific processing necessary when a value is freed.
.PP
For example, the list type's \fIfreeIntRepProc\fR respects
the storage sharing scheme established by the \fIdupIntRepProc\fR
so that it only frees storage when the last object sharing it
so that it only frees storage when the last value sharing it
is being freed.
.PP
The \fIfreeIntRepProc\fR member can be set to NULL
to indicate that the internal representation does not require freeing.
The \fIfreeIntRepProc\fR implementation must not access the
\fIbytes\fR member of the object, since Tcl makes its own internal
uses of that field during object deletion. The defined tasks for
\fIbytes\fR member of the value, since Tcl makes its own internal
uses of that field during value deletion. The defined tasks for
the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
member.
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
.SH KEYWORDS
internal representation, object, object type, string representation, type conversion
internal representation, value, value type, string representation, type conversion
+13 -13
View File
@@ -152,24 +152,24 @@ The pattern to match on, passed to Tcl_StringMatch, or NULL.
A Tcl channel for input or output. Must have been the return value
from a procedure such as \fBTcl_OpenFileChannel\fR.
.AP Tcl_Obj *readObjPtr in/out
A pointer to a Tcl Object in which to store the characters read from the
A pointer to a Tcl value in which to store the characters read from the
channel.
.AP int charsToRead in
The number of characters to read from the channel. If the channel's encoding
is \fBbinary\fR, this is equivalent to the number of bytes to read from the
channel.
.AP int appendFlag in
If non-zero, data read from the channel will be appended to the object.
Otherwise, the data will replace the existing contents of the object.
If non-zero, data read from the channel will be appended to the value.
Otherwise, the data will replace the existing contents of the value.
.AP char *readBuf out
A buffer in which to store the bytes read from the channel.
.AP int bytesToRead in
The number of bytes to read from the channel. The buffer \fIreadBuf\fR must
be large enough to hold this many bytes.
.AP Tcl_Obj *lineObjPtr in/out
A pointer to a Tcl object in which to store the line read from the
A pointer to a Tcl value in which to store the line read from the
channel. The line read will be appended to the current value of the
object.
value.
.AP Tcl_DString *lineRead in/out
A pointer to a Tcl dynamic string in which to store the line read from the
channel. Must have been initialized by the caller. The line read will be
@@ -182,7 +182,7 @@ Length of the input
Flag indicating whether the input should be added to the end or
beginning of the channel buffer.
.AP Tcl_Obj *writeObjPtr in
A pointer to a Tcl Object whose contents will be output to the channel.
A pointer to a Tcl value whose contents will be output to the channel.
.AP "const char" *charBuf in
A buffer containing the characters to output to the channel.
.AP "const char" *byteBuf in
@@ -239,7 +239,7 @@ returns NULL and records a POSIX error code that can be
retrieved with \fBTcl_GetErrno\fR.
In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
leaves an error message in \fIinterp\fR's result after any error.
As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should
As of Tcl 8.4, the value-based API \fBTcl_FSOpenFileChannel\fR should
be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
.PP
The newly created channel is not registered in the supplied interpreter; to
@@ -305,7 +305,7 @@ open for reading and writing.
.PP
\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
names of the registered channels to the interpreter's result as a
list object. \fBTcl_GetChannelNamesEx\fR will filter these names
list value. \fBTcl_GetChannelNamesEx\fR will filter these names
according to the \fIpattern\fR. If \fIpattern\fR is NULL, then it
will not do any filtering. The return value is \fBTCL_OK\fR if no
errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
@@ -435,7 +435,7 @@ platform-specific modes are described in the manual entry for the Tcl
As a performance optimization, when reading from a channel with the encoding
\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
byte-array object. The string representation of this object will only be
byte-array value. The string representation of this value will only be
constructed if it is needed (e.g., because of a call to
\fBTcl_GetStringFromObj\fR). In this way, byte-oriented data can be read
from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
@@ -484,7 +484,7 @@ of input unavailability.
.PP
\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
characters are appended to the dynamic string given by
\fIlineRead\fR rather than a Tcl object.
\fIlineRead\fR rather than a Tcl value.
.SH "TCL_UNGETS"
.PP
\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
@@ -523,14 +523,14 @@ end-of-line sequences according to the \fB\-translation\fR option for the
channel. This is done even if the channel has no encoding.
.PP
\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
accepts a Tcl object whose contents will be output to the channel. The
accepts a Tcl value whose contents will be output to the channel. The
UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
to the channel's encoding and queued for output to \fIchannel\fR.
As a performance optimization, when writing to a channel with the encoding
\fBbinary\fR, UTF-8 characters are not converted as they are written.
Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
byte-array object are written to the channel. The byte-array representation
of the object will be constructed if it is needed. In this way,
byte-array value are written to the channel. The byte-array representation
of the value will be constructed if it is needed. In this way,
byte-oriented data can be read from a channel, manipulated by calling
\fBTcl_GetByteArrayFromObj\fR and related functions, and then written to a
channel without the expense of ever converting to or from UTF-8.
+2 -2
View File
@@ -134,7 +134,7 @@ typedef int (\fBTcl_ArgvFuncProc\fR)(
.PP
The result is a boolean value indicating whether to consume the following
argument. The \fIclientData\fR is the value from the table entry, the
\fIobjPtr\fR is the object that represents the following argument or NULL if
\fIobjPtr\fR is the value that represents the following argument or NULL if
there are no following arguments at all, and the \fIdstPtr\fR argument to the
\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
.RE
@@ -186,7 +186,7 @@ marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
.
This argument takes a following string value argument. A pointer to the string
will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
to the lifetime of the string representation of the argument object that it
to the lifetime of the string representation of the argument value that it
came from, and so should be copied if it needs to be retained. The
\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
.SH "SEE ALSO"
+2 -2
View File
@@ -194,9 +194,9 @@ result; it can be retrieved using \fBTcl_GetObjResult\fR.
.PP
\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
the return convention used: it returns the result in a new Tcl_Obj.
The reference count of the object returned as result has been
The reference count of the value returned as result has been
incremented, so the caller must
invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
invoke \fBTcl_DecrRefCount\fR when it is finished with the value.
If an error or other exception occurs while evaluating the tokens
(such as a reference to a non-existent variable) then the return value
is NULL and an error message is left in \fIinterp\fR's result. The use
+3 -3
View File
@@ -20,7 +20,7 @@ int
.AP Tcl_Interp *interp in
Tcl interpreter in which to evaluate command.
.AP Tcl_Obj *cmdPtr in
Points to a Tcl object containing a command (or sequence of commands)
Points to a Tcl value containing a command (or sequence of commands)
to execute.
.AP int flags in
An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
@@ -35,7 +35,7 @@ on the history list and then execute it using \fBTcl_EvalObjEx\fR
(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
in \fIflags\fR).
It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
as well as a result object containing additional information
as well as a result value containing additional information
(a result value or error message)
that can be retrieved using \fBTcl_GetObjResult\fR.
If you do not want the command recorded on the history list then
@@ -50,4 +50,4 @@ the command is recorded without being evaluated.
Tcl_EvalObjEx, Tcl_GetObjResult
.SH KEYWORDS
command, event, execute, history, interpreter, object, record
command, event, execute, history, interpreter, value, record
+3 -3
View File
@@ -44,9 +44,9 @@ If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
the command is recorded without being evaluated.
.PP
Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
object-based procedure \fBTcl_RecordAndEvalObj\fR.
That object-based procedure records and optionally executes
a command held in a Tcl object instead of a string.
value-based procedure \fBTcl_RecordAndEvalObj\fR.
That value-based procedure records and optionally executes
a command held in a Tcl value instead of a string.
.SH "SEE ALSO"
Tcl_RecordAndEvalObj
+9 -9
View File
@@ -45,12 +45,12 @@ void
Tcl interpreter to use for error reporting. The interpreter may be
NULL if no error reporting is desired.
.AP Tcl_Obj *textObj in/out
Refers to the object from which to get the text to search. The
internal representation of the object may be converted to a form that
Refers to the value from which to get the text to search. The
internal representation of the value may be converted to a form that
can be efficiently searched.
.AP Tcl_Obj *patObj in/out
Refers to the object from which to get a regular expression. The
compiled regular expression is cached in the object.
Refers to the value from which to get a regular expression. The
compiled regular expression is cached in the value.
.AP char *text in
Text to search for a match with a regular expression.
.AP "const char" *pattern in
@@ -110,7 +110,7 @@ If an error occurs in the matching process (e.g. \fIpattern\fR
is not a valid regular expression) then \fBTcl_RegExpMatch\fR
returns \-1 and leaves an error message in the interpreter result.
\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
operates on the Tcl objects \fItextObj\fR and \fIpatObj\fR instead of
operates on the Tcl values \fItextObj\fR and \fIpatObj\fR instead of
UTF strings.
\fBTcl_RegExpMatchObj\fR is generally more efficient than
\fBTcl_RegExpMatch\fR, so it is the preferred interface.
@@ -164,18 +164,18 @@ If there is no range corresponding to \fIindex\fR then NULL
is stored in \fI*startPtr\fR and \fI*endPtr\fR.
.PP
\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
\fBTcl_RegExpGetInfo\fR are value interfaces that provide the most
direct control of Henry Spencer's regular expression library. For
users that need to modify compilation and execution options directly,
it is recommended that you use these interfaces instead of calling the
internal regexp functions. These interfaces handle the details of UTF
to Unicode translations as well as providing improved performance
through caching in the pattern and string objects.
through caching in the pattern and string values.
.PP
\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
expression from the \fIpatObj\fR. If the object does not already
expression from the \fIpatObj\fR. If the value does not already
contain a compiled regular expression it will attempt to create one
from the string in the object and assign it to the internal
from the string in the value and assign it to the internal
representation of the \fIpatObj\fR. The return value of this function
is of type \fBTcl_RegExp\fR. The return value is a token for this
compiled form, which can be used in subsequent calls to
+2 -2
View File
@@ -96,12 +96,12 @@ or \fBTcl_DiscardInterpState\fR to avoid a memory leak. Once
the \fBTcl_InterpState\fR token is passed to one of them, the
token is no longer valid and should not be used anymore.
.PP
\fBTcl_SaveResult\fR moves the string and object results
\fBTcl_SaveResult\fR moves the string and value results
of \fIinterp\fR into the location specified by \fIstatePtr\fR.
\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
leaves the result in its normal empty initialized state.
.PP
\fBTcl_RestoreResult\fR moves the string and object results from
\fBTcl_RestoreResult\fR moves the string and value results from
\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was
already in the interpreter will be cleared. The \fIstatePtr\fR is left
in an uninitialized state and cannot be used until another call to
+4 -4
View File
@@ -55,12 +55,12 @@ arrange for their return as errors. The POSIX error codes set by a driver are
used now if and only if no messages are present.
.PP
\fBTcl_SetChannelError\fR stores error information in the bypass area of the
specified channel. The number of references to the \fBmsg\fR object goes up by
specified channel. The number of references to the \fBmsg\fR value goes up by
one. Previously stored information will be discarded, by releasing the
reference held by the channel. The channel reference must not be NULL.
.PP
\fBTcl_SetChannelErrorInterp\fR stores error information in the bypass area of
the specified interpreter. The number of references to the \fBmsg\fR object
the specified interpreter. The number of references to the \fBmsg\fR value
goes up by one. Previously stored information will be discarded, by releasing
the reference held by the interpreter. The interpreter reference must not be
NULL.
@@ -72,7 +72,7 @@ NULL, until an intervening invocation of \fBTcl_SetChannelError\fR with a
non-NULL message. The \fImsgPtr\fR must not be NULL. The reference count of
the message is not touched. The reference previously held by the channel is
now held by the caller of the function and it is its responsibility to release
that reference when it is done with the object.
that reference when it is done with the value.
.PP
\fBTcl_GetChannelErrorInterp\fR places either the error message held in the
bypass area of the specified interpreter into \fImsgPtr\fR, or NULL; and
@@ -82,7 +82,7 @@ return NULL, until an intervening invocation of
not be NULL. The reference count of the message is not touched. The reference
previously held by the interpreter is now held by the caller of the function
and it is its responsibility to release that reference when it is done with
the object.
the value.
.PP
Which functions of a channel driver are allowed to use which bypass function
is listed below, as is which functions of the public channel API may leave a
+21 -21
View File
@@ -42,7 +42,7 @@ const char *
.AP Tcl_Interp *interp out
Interpreter whose result is to be modified or read.
.AP Tcl_Obj *objPtr in
Object value to become result for \fIinterp\fR.
Tcl value to become result for \fIinterp\fR.
.AP char *result in
String value to become result for \fIinterp\fR or to be
appended to the existing result.
@@ -74,32 +74,32 @@ information as well.
.PP
The procedures described here are utilities for manipulating the
result value in a Tcl interpreter.
The interpreter result may be either a Tcl object or a string.
The interpreter result may be either a Tcl value or a string.
For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
set the interpreter result to, respectively, an object and a string.
set the interpreter result to, respectively, a value and a string.
Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
return the interpreter result as an object and as a string.
The procedures always keep the string and object forms
return the interpreter result as a value and as a string.
The procedures always keep the string and value forms
of the interpreter result consistent.
For example, if \fBTcl_SetObjResult\fR is called to set
the result to an object,
the result to a value,
then \fBTcl_GetStringResult\fR is called,
it will return the object's string value.
it will return the value's string representation.
.PP
\fBTcl_SetObjResult\fR
arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
replacing any existing result.
The result is left pointing to the object
The result is left pointing to the value
referenced by \fIobjPtr\fR.
\fIobjPtr\fR's reference count is incremented
since there is now a new reference to it from \fIinterp\fR.
The reference count for any old result object
is decremented and the old result object is freed if no
The reference count for any old result value
is decremented and the old result value is freed if no
references to it remain.
.PP
\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as an object.
The object's reference count is not incremented;
if the caller needs to retain a long-term pointer to the object
\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as a value.
The value's reference count is not incremented;
if the caller needs to retain a long-term pointer to the value
they should use \fBTcl_IncrRefCount\fR to increment its reference count
in order to keep it from being freed too early or accidentally changed.
.PP
@@ -115,19 +115,19 @@ and \fBTcl_SetResult\fR
re-initializes \fIinterp\fR's result to point to an empty string.
.PP
\fBTcl_GetStringResult\fR returns the result for \fIinterp\fR as a string.
If the result was set to an object by a \fBTcl_SetObjResult\fR call,
the object form will be converted to a string and returned.
If the object's string representation contains null bytes,
If the result was set to a value by a \fBTcl_SetObjResult\fR call,
the value form will be converted to a string and returned.
If the value's string representation contains null bytes,
this conversion will lose information.
For this reason, programmers are encouraged to
write their code to use the new object API procedures
write their code to use the new value API procedures
and to call \fBTcl_GetObjResult\fR instead.
.PP
\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
and leaves the result in its normal empty initialized state.
If the result is an object,
If the result is a value,
its reference count is decremented and the result is left
pointing to an unshared object representing an empty string.
pointing to an unshared value representing an empty string.
If the result is a dynamically allocated string, its memory is free*d
and the result is left as a empty string.
\fBTcl_ResetResult\fR also clears the error state managed by
@@ -167,7 +167,7 @@ The source interpreter will have its result reset by this operation.
Use of the following procedures (is deprecated
since they manipulate the Tcl result as a string.
Procedures such as \fBTcl_SetObjResult\fR
that manipulate the result as an object
that manipulate the result as a value
can be significantly more efficient.
.PP
\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
@@ -252,4 +252,4 @@ the value of \fIresult\fR passed to \fBTcl_SetResult\fR.
.SH "SEE ALSO"
Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp
.SH KEYWORDS
append, command, element, list, object, result, return value, interpreter
append, command, element, list, value, result, return value, interpreter
+4 -4
View File
@@ -57,7 +57,7 @@ to specify a variable in a particular namespace.
If non-NULL, gives name of element within array; in this
case \fIname1\fR must refer to an array variable.
.AP Tcl_Obj *newValuePtr in
Points to a Tcl object containing the new value for the variable.
Points to a Tcl value containing the new value for the variable.
.AP int flags in
OR-ed combination of bits providing additional information. See below
for valid values.
@@ -71,12 +71,12 @@ an array.
New value for variable, specified as a null-terminated string.
A copy of this value is stored in the variable.
.AP Tcl_Obj *part1Ptr in
Points to a Tcl object containing the variable's name.
Points to a Tcl value containing the variable's name.
The name may include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of an array variable.
.AP Tcl_Obj *part2Ptr in
If non-NULL, points to an object containing the name of an element
If non-NULL, points to a value containing the name of an element
within an array and \fIpart1Ptr\fR must refer to an array variable.
.BE
@@ -246,4 +246,4 @@ array is removed.
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
.SH KEYWORDS
array, get variable, interpreter, object, scalar, set, unset, variable
array, get variable, interpreter, scalar, set, unset, value, variable
+1 -1
View File
@@ -43,7 +43,7 @@ A pointer to an initialized \fBTcl_DString\fR to which the result of
.SH DESCRIPTION
.PP
These procedures have been superseded by the objectified procedures in
These procedures have been superseded by the Tcl-value-aware procedures in
the \fBFileSystem\fR man page, which are more efficient.
.PP
These procedures may be used to disassemble and reassemble file
+51 -51
View File
@@ -8,7 +8,7 @@
.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl objects as strings
Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl values as strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -88,7 +88,7 @@ Tcl_Obj *
.AS "const Tcl_UniChar" *appendObjPtr in/out
.AP "const char" *bytes in
Points to the first byte of an array of UTF-8-encoded bytes
used to set or append to a string object.
used to set or append to a string value.
This byte array may contain embedded null characters
unless \fInumChars\fR is negative. (Applications needing null bytes
should represent them as the two-byte sequence \fI\e700\e600\fR, use
@@ -96,32 +96,32 @@ should represent them as the two-byte sequence \fI\e700\e600\fR, use
the string is a collection of uninterpreted bytes.)
.AP int length in
The number of bytes to copy from \fIbytes\fR when
initializing, setting, or appending to a string object.
initializing, setting, or appending to a string value.
If negative, all bytes up to the first null are used.
.AP "const Tcl_UniChar" *unicode in
Points to the first byte of an array of Unicode characters
used to set or append to a string object.
used to set or append to a string value.
This byte array may contain embedded null characters
unless \fInumChars\fR is negative.
.AP int numChars in
The number of Unicode characters to copy from \fIunicode\fR when
initializing, setting, or appending to a string object.
initializing, setting, or appending to a string value.
If negative, all characters up to the first null character are used.
.AP int index in
The index of the Unicode character to return.
.AP int first in
The index of the first Unicode character in the Unicode range to be
returned as a new object.
returned as a new value.
.AP int last in
The index of the last Unicode character in the Unicode range to be
returned as a new object.
returned as a new value.
.AP Tcl_Obj *objPtr in/out
Points to an object to manipulate.
Points to a value to manipulate.
.AP Tcl_Obj *appendObjPtr in
The object to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
.AP int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
the length of an object's string representation.
the length of a value's string representation.
.AP "const char" *string in
Null-terminated string value to append to \fIobjPtr\fR.
.AP va_list argList in
@@ -139,46 +139,46 @@ Format control string including % conversion specifiers.
.AP int objc in
The number of elements to format or concatenate.
.AP Tcl_Obj *objv[] in
The array of objects to format or concatenate.
The array of values to format or concatenate.
.AP int newLength in
New length for the string value of \fIobjPtr\fR, not including the
final null character.
.BE
.SH DESCRIPTION
.PP
The procedures described in this manual entry allow Tcl objects to
The procedures described in this manual entry allow Tcl values to
be manipulated as string values. They use the internal representation
of the object to store additional information to make the string
of the value to store additional information to make the string
manipulations more efficient. In particular, they make a series of
append operations efficient by allocating extra storage space for the
string so that it does not have to be copied for each append.
Also, indexing and length computations are optimized because the
Unicode string representation is calculated and cached as needed.
When using the \fBTcl_Append*\fR family of functions where the
interpreter's result is the object being appended to, it is important
interpreter's result is the value being appended to, it is important
to call Tcl_ResetResult first to ensure you are not unintentionally
appending to existing data in the result object.
appending to existing data in the result value.
.PP
\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new object
or modify an existing object to hold a copy of the string given by
\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new value
or modify an existing value to hold a copy of the string given by
\fIbytes\fR and \fIlength\fR. \fBTcl_NewUnicodeObj\fR and
\fBTcl_SetUnicodeObj\fR create a new object or modify an existing
object to hold a copy of the Unicode string given by \fIunicode\fR and
\fBTcl_SetUnicodeObj\fR create a new value or modify an existing
value to hold a copy of the Unicode string given by \fIunicode\fR and
\fInumChars\fR. \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
return a pointer to a newly created object with reference count zero.
All four procedures set the object to hold a copy of the specified
return a pointer to a newly created value with reference count zero.
All four procedures set the value to hold a copy of the specified
string. \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
old string representation as well as any old internal representation
of the object.
of the value.
.PP
\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return an object's
\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return a value's
string representation. This is given by the returned byte pointer and
(for \fBTcl_GetStringFromObj\fR) length, which is stored in
\fIlengthPtr\fR if it is non-NULL. If the object's UTF string
\fIlengthPtr\fR if it is non-NULL. If the value's UTF string
representation is invalid (its byte pointer is NULL), the string
representation is regenerated from the object's internal
representation is regenerated from the value's internal
representation. The storage referenced by the returned byte pointer
is owned by the object manager. It is passed back as a writable
is owned by the value manager. It is passed back as a writable
pointer so that extension author creating their own \fBTcl_ObjType\fR
will be able to modify the string representation within the
\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
@@ -194,45 +194,45 @@ The procedure \fBTcl_GetString\fR is used in the common case
where the caller does not need the length of the string
representation.
.PP
\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return an object's
\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return a value's
value as a Unicode string. This is given by the returned pointer and
(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
\fIlengthPtr\fR if it is non-NULL. The storage referenced by the returned
byte pointer is owned by the object manager and should not be modified by
byte pointer is owned by the value manager and should not be modified by
the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case
where the caller does not need the length of the unicode string
representation.
.PP
\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
object's Unicode representation.
value's Unicode representation.
.PP
\fBTcl_GetRange\fR returns a newly created object comprised of the
\fBTcl_GetRange\fR returns a newly created value comprised of the
characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
object's Unicode representation. If the object's Unicode
value's Unicode representation. If the value's Unicode
representation is invalid, the Unicode representation is regenerated
from the object's string representation.
from the value's string representation.
.PP
\fBTcl_GetCharLength\fR returns the number of characters (as opposed
to bytes) in the string object.
to bytes) in the string value.
.PP
\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
\fIlength\fR to the string representation of the object specified by
\fIobjPtr\fR. If the object has an invalid string representation,
\fIlength\fR to the string representation of the value specified by
\fIobjPtr\fR. If the value has an invalid string representation,
then an attempt is made to convert \fIbytes\fR is to the Unicode
format. If the conversion is successful, then the converted form of
\fIbytes\fR is appended to the object's Unicode representation.
Otherwise, the object's Unicode representation is invalidated and
\fIbytes\fR is appended to the value's Unicode representation.
Otherwise, the value's Unicode representation is invalidated and
converted to the UTF format, and \fIbytes\fR is appended to the
object's new string representation.
value's new string representation.
.PP
\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
\fIunicode\fR and \fInumChars\fR to the object specified by
\fIobjPtr\fR. If the object has an invalid Unicode representation,
\fIunicode\fR and \fInumChars\fR to the value specified by
\fIobjPtr\fR. If the value has an invalid Unicode representation,
then \fIunicode\fR is converted to the UTF format and appended to the
object's string representation. Appends are optimized to handle
value's string representation. Appends are optimized to handle
repeated appends relatively efficiently (it over-allocates the string
or Unicode space to avoid repeated reallocations and copies of
object's string value).
value's string value).
.PP
\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
appends the string or Unicode value (whichever exists and is best
@@ -345,14 +345,14 @@ functionality is needed.
.PP
The \fBTcl_SetObjLength\fR procedure changes the length of the
string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
argument is greater than the space allocated for the object's
argument is greater than the space allocated for the value's
string, then the string space is reallocated and the old value
is copied to the new space; the bytes between the old length of
the string and the new length may have arbitrary values.
If the \fInewLength\fR argument is less than the current length
of the object's string, with \fIobjPtr->length\fR is reduced without
of the value's string, with \fIobjPtr->length\fR is reduced without
reallocating the string space; the original allocated size for the
string is recorded in the object, so that the string length can be
string is recorded in the value, so that the string length can be
enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
reallocating storage. In all cases \fBTcl_SetObjLength\fR leaves
a null character at \fIobjPtr->bytes[newLength]\fR.
@@ -361,24 +361,24 @@ a null character at \fIobjPtr->bytes[newLength]\fR.
\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
request cannot be allocated, it does not cause the Tcl interpreter to
\fBpanic\fR. Thus, if \fInewLength\fR is greater than the space
allocated for the object's string, and there is not enough memory
allocated for the value's string, and there is not enough memory
available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
no action and return 0 to indicate failure. If there is enough memory
to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
\fBTcl_SetObjLength\fR and returns 1 to indicate success.
.PP
The \fBTcl_ConcatObj\fR function returns a new string object whose
The \fBTcl_ConcatObj\fR function returns a new string value whose
value is the space-separated concatenation of the string
representations of all of the objects in the \fIobjv\fR
representations of all of the values in the \fIobjv\fR
array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
as it copies the string representations of the \fIobjv\fR array to the
result. If an element of the \fIobjv\fR array consists of nothing but
white space, then that object is ignored entirely. This white-space
white space, then that value is ignored entirely. This white-space
removal was added to make the output of the \fBconcat\fR command
cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
newly-created object whose ref count is zero.
newly-created value whose ref count is zero.
.SH "SEE ALSO"
Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
.SH KEYWORDS
append, internal representation, object, object type, string object,
append, internal representation, value, value type, string value,
string type, string representation, concat, concatenate, unicode
+3 -3
View File
@@ -8,7 +8,7 @@
.TH Tcl_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SubstObj \- perform substitutions on Tcl objects
Tcl_SubstObj \- perform substitutions on Tcl values
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -22,7 +22,7 @@ Interpreter in which to execute Tcl scripts and lookup variables. If
an error occurs, the interpreter's result is modified to hold an error
message.
.AP Tcl_Obj *objPtr in
A Tcl object containing the string to perform substitutions on.
A Tcl value containing the string to perform substitutions on.
.AP int flags in
ORed combination of flag bits that specify which substitutions to
perform. The flags \fBTCL_SUBST_COMMANDS\fR,
@@ -36,7 +36,7 @@ The \fBTcl_SubstObj\fR function is used to perform substitutions on
strings in the fashion of the \fBsubst\fR command. It gets the value
of the string contained in \fIobjPtr\fR and scans it, copying
characters and performing the chosen substitutions as it goes to an
output object which is returned as the result of the function. In the
output value which is returned as the result of the function. In the
event of an error occurring during the execution of a command or
variable substitution, the function returns NULL and an error message
is left in \fIinterp\fR's result.
+1 -1
View File
@@ -26,7 +26,7 @@ version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined
for all modules that are going to be linked together. If they are not, link
errors will occur, with either \fBTcl_DbCkfree\fR and \fBTcl_DbCkalloc\fR or
\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined.
\fBTcl_Alloc\fR and \fBTcl_Free\fR being undefined.
.PP
Once memory debugging support has been compiled into Tcl, the C
functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
+36 -8
View File
@@ -49,9 +49,11 @@ int
.sp
int
\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
.sp
\fBTcl_ZlibStreamSetCompressionDictionary\fR(\fIzshandle, compDict\fR)
.fi
.SH ARGUMENTS
.AS Tcl_ZlibStream *zshandlePtr out
.AS Tcl_ZlibStream zshandle in
.AP Tcl_Interp *interp in
The interpreter to store resulting compressed or uncompressed data in. Also
where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
@@ -64,7 +66,7 @@ addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
chosen which can automatically detect whether the compressed data was in zlib
or gzip format.
.AP Tcl_Obj *dataObj in/out
A byte-array object containing the data to be compressed or decompressed, or
A byte-array value containing the data to be compressed or decompressed, or
to which the data extracted from the stream is appended when passed to
\fBTcl_ZlibStreamGet\fR.
.AP int level in
@@ -108,6 +110,13 @@ trailer demanded by the format is written.
.AP int count in
The maximum number of bytes to get from the stream, or -1 to get all remaining
bytes from the stream's buffers.
.AP Tcl_Obj *compDict in
A byte array value that is the compression dictionary to use with the stream.
Note that this is \fInot a Tcl dictionary\fR, and it is recommended that this
only ever be used with streams that were created with their \fIformat\fR set
to \fBTCL_ZLIB_FORMAT_ZLIB\fR because the other formats have no mechanism to
indicate whether a compression dictionary was present other than to fail on
decompression.
.BE
.SH DESCRIPTION
These functions form the interface from the Tcl library to the Zlib
@@ -122,7 +131,7 @@ the dictionary is only used when the \fIformat\fR parameter is
\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
below. Upon success, both functions leave the resulting compressed or
decompressed data in a byte-array object that is the Tcl interpreter's result;
decompressed data in a byte-array value that is the Tcl interpreter's result;
the returned value is a standard Tcl result code.
.PP
\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
@@ -154,7 +163,7 @@ the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
headers, and on decompression allows discovery of the existing headers. Note
that the dictionary will be written to on decompression once sufficient data
has been read to have a complete header. This means that the dictionary must
be an unshared object in that case; a blank object created with
be an unshared value in that case; a blank value created with
\fBTcl_NewObj\fR is suggested.
.PP
Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
@@ -162,8 +171,8 @@ data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
the stream after processing. Both return normal Tcl result codes and leave an
error message in the result of the interpreter that the stream is registered
with in the error case (if such a registration has been performed). With
\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
\fBTcl_ZlibStreamPut\fR, the data buffer value passed to it should not be
modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer value
passed to it will have the data bytes appended to it. Internally to the
stream, data is kept compressed so as to minimize the cost of buffer space.
.PP
@@ -172,6 +181,25 @@ uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
a boolean value indicating whether the end of the uncompressed data has been
reached.
.PP
\fBTcl_ZlibStreamSetCompressionDictionary\fR is used to control the
compression dictionary used with the stream, a compression dictionary being an
array of bytes (such as might be created with \fBTcl_NewByteArrayObj\fR) that
is used to initialize the compression engine rather than leaving it to create
it on the fly from the data being compressed. Setting a compression dictionary
allows for more efficient compression in the case where the start of the data
is highly regular, but it does require both the compressor and the
decompressor to agreee on the value to use. Compression dictionaries are only
fully supported for zlib-format data; on compression, they must be set before
any data is sent in with \fBTcl_ZlibStreamPut\fR, and on decompression they
should be set when \fBTcl_ZlibStreamGet\fR produces an \fBerror\fR with its
\fB\-errorcode\fR set to
.QW "\fBZLIB NEED_DICT\fI code\fR" ;
the \fIcode\fR will be the Adler-32 checksum (see \fBTcl_ZlibAdler32\fR) of
the compression dictionary sought. (Note that this is only true for
zlib-format streams; gzip streams ignore compression dictionaries as the
format specification doesn't permit them, and raw streams just produce a data
error if the compression dictionary is missing or incorrect.)
.PP
If you wish to clear a stream and reuse it for a new compression or
decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
normal Tcl result code to indicate whether it was successful; if the stream is
@@ -187,9 +215,9 @@ and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
that is used to describe the gzip header in the compressed data. When creating
compressed data, the dictionary is read and when unpacking compressed data the
dictionary is written (in which case the \fIdictObj\fR parameter must refer to
an unshared dictionary object).
an unshared dictionary value).
.PP
The following fields in the dictionary object are understood. All other fields
The following fields in the dictionary value are understood. All other fields
are ignored. No field is required when creating a gzip-format stream.
.TP
\fBcomment\fR
+7 -7
View File
@@ -18,7 +18,7 @@ Tcl_WrongNumArgs \- generate standard error message for wrong number of argument
.AS "Tcl_Obj *const" *message
.AP Tcl_Interp interp in
Interpreter in which error will be reported: error message gets stored
in its result object.
in its result value.
.AP int objc in
Number of leading arguments from \fIobjv\fR to include in error
message.
@@ -34,13 +34,13 @@ of the command. This argument may be NULL.
\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
command procedures when they discover that they have received the
wrong number of arguments. \fBTcl_WrongNumArgs\fR generates a
standard error message and stores it in the result object of
standard error message and stores it in the result value of
\fIinterp\fR. The message includes the \fIobjc\fR initial
elements of \fIobjv\fR plus \fImessage\fR. For example, if
\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
\fIobjc\fR is 1, and \fImessage\fR is
.QW "\fBfileName count\fR"
then \fIinterp\fR's result object will be set to the following
then \fIinterp\fR's result value will be set to the following
string:
.PP
.CS
@@ -57,17 +57,17 @@ wrong # args: should be "foo bar fileName count"
\fBstring\fR and the Tk widget commands, which use the first argument
as a subcommand.
.PP
Some of the objects in the \fIobjv\fR array may be abbreviations for
Some of the values in the \fIobjv\fR array may be abbreviations for
a subcommand. The command
\fBTcl_GetIndexFromObj\fR will convert the abbreviated string object
\fBTcl_GetIndexFromObj\fR will convert the abbreviated string value
into an \fIindexObject\fR. If an error occurs in the parsing of the
subcommand we would like to use the full subcommand name rather than
the abbreviation. If the \fBTcl_WrongNumArgs\fR command finds any
\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
name in the error message instead of the abbreviated name that was
originally passed in. Using the above example, let us assume that
\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the object
is now an indexObject because it was passed to
\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the value
is now an \fIindexObject\fR because it was passed to
\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
.PP
.CS
+1 -1
View File
@@ -158,7 +158,7 @@ variables set appropriately (in the manner of \fBlmap\fR). In an iteration
where the evaluated script completes normally (\fBTCL_OK\fR, as opposed to an
\fBerror\fR, etc.) the result of the script is put into an accumulator
dictionary using the key that is the current contents of the \fIkeyVar\fR
variable at that point. The result of the \fBdict map\fB command is the
variable at that point. The result of the \fBdict map\fR command is the
accumulator dictionary after all keys have been iterated over.
.RS
.PP
+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
.
+19 -3
View File
@@ -11,11 +11,11 @@
.SH NAME
load \- Load machine code and initialize new commands
.SH SYNOPSIS
\fBload \fIfileName\fR
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR
.br
\fBload \fIfileName packageName\fR
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR
.br
\fBload \fIfileName packageName interp\fR
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR
.BE
.SH DESCRIPTION
.PP
@@ -104,6 +104,22 @@ Otherwise, the \fBload\fR command searches for a dynamically loaded
package by that name, and uses it if it is found. If several
different files have been \fBload\fRed with different versions of
the package, Tcl picks the file that was loaded first.
.PP
If \fB\-global\fR is specified preceding the filename, all symbols
found in the shared library are exported for global use by other
libraries. The option \fB\-lazy\fR delays the actual loading of
symbols until their first actual use. The options may be abbreviated.
The option \fB\-\-\fR indicates the end of the options, and should
be used if you wish to use a filename which starts with \fB\-\fR
and you provide a packageName to the \fBload\fR command.
.PP
On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR
options, the options still exist but have no effect. Note that use
of the \fB\-global\fR or \fB\-lazy\fR option may lead to crashes
in your application later (in case of symbol conflicts resp. missing
symbols), which cannot be detected during the \fBload\fR. So, only
use this when you know what you are doing, you will not get a nice
error message when something is wrong with the loaded library.
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR\0\0\0\0\0
-91
View File
@@ -1,91 +0,0 @@
'\"
'\" Copyright (c) 2012 Trevor Davel
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
.TH mapeach n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
mapeach \- Iterate over all elements in one or more lists and collect results
.SH SYNOPSIS
\fBmapeach \fIvarname list body\fR
.br
\fBmapeach \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
.BE
.SH DESCRIPTION
.PP
The \fBmapeach\fR command implements a loop where the loop
variable(s) take on values from one or more lists, and the loop returns a list
of results collected from each iteration.
.PP
In the simplest case there is one loop variable, \fIvarname\fR,
and one list, \fIlist\fR, that is a list of values to assign to \fIvarname\fR.
The \fIbody\fR argument is a Tcl script.
For each element of \fIlist\fR (in order
from first to last), \fBmapeach\fR assigns the contents of the
element to \fIvarname\fR as if the \fBlindex\fR command had been used
to extract the element, then calls the Tcl interpreter to execute
\fIbody\fR. If execution of the body completes normally then the result of the
body is appended to an accumulator list. \fBmapeach\fR returns the accumulator
list.
.PP
In the general case there can be more than one value list
(e.g., \fIlist1\fR and \fIlist2\fR),
and each value list can be associated with a list of loop variables
(e.g., \fIvarlist1\fR and \fIvarlist2\fR).
During each iteration of the loop
the variables of each \fIvarlist\fR are assigned
consecutive values from the corresponding \fIlist\fR.
Values in each \fIlist\fR are used in order from first to last,
and each value is used exactly once.
The total number of loop iterations is large enough to use
up all the values from all the value lists.
If a value list does not contain enough
elements for each of its loop variables in each iteration,
empty values are used for the missing elements.
.PP
The \fBbreak\fR and \fBcontinue\fR statements may be
invoked inside \fIbody\fR, with the same effect as in the \fBfor\fR
and \fBforeach\fR commands. In these cases the body does not complete normally
and the result is not appended to the accumulator list.
.SH EXAMPLES
.PP
Zip lists together:
.PP
.CS
'\" Maintainers: notice the tab hacking below!
.ta 3i
set list1 {a b c d}
set list2 {1 2 3 4}
set zipped [\fBmapeach\fR a $list1 b $list2 {list $a $b}]
# The value of zipped is "{a 1} {b 2} {c 3} {d 4}"
.CE
.PP
Filter a list:
.PP
.CS
set values {1 2 3 4 5 6 7 8}
proc isGood {n} { expr { ($n % 2) == 0 } }
set goodOnes [\fBmapeach\fR x $values {expr {[isGood $x] ? $x : [continue]}}]
# The value of goodOnes is "2 4 6 8"
.CE
.PP
Take a prefix from a list:
.PP
.CS
set values {8 7 6 5 4 3 2 1}
proc isGood {n} { expr { $n > 3 } }
set prefix [\fBmapeach\fR x $values {expr {[isGood $x] ? $x : [break]}}]
# The value of prefix is "8 7 6 5 4"
.CE
.SH "SEE ALSO"
for(n), while(n), break(n), continue(n), foreach(n)
.SH KEYWORDS
foreach, iteration, list, loop, map
+1 -1
View File
@@ -5,7 +5,7 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
.TH "msgcat" n 1.4 msgcat "Tcl Bundled Packages"
.TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
+1 -1
View File
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
next \- invoke superclass method implementations
next, nextto \- invoke superclass method implementations
.SH SYNOPSIS
.nf
package require TclOO
+36 -28
View File
@@ -19,24 +19,6 @@ 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. In almost all cases, you should use the
\fBstring length\fR operation (including determining the length of a
Tcl ByteArray object). Refer to the \fBTcl_NumUtfChars\fR manual
entry for more details on the UTF\-8 representation.
.RS
.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
.
Perform a character-by-character comparison of strings \fIstring1\fR
@@ -149,7 +131,8 @@ Any Unicode printing character, including space.
.IP \fBpunct\fR 12
Any Unicode punctuation character.
.IP \fBspace\fR 12
Any Unicode space character.
Any Unicode whitespace character, zero width space (U+200b),
word joiner (U+2060) and zero width no-break space (U+feff) (=BOM).
.IP \fBtrue\fR 12
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
true.
@@ -198,9 +181,9 @@ will return \fB1\fR.
.
Returns a decimal string giving the number of characters in
\fIstring\fR. Note that this is not necessarily the same as the
number of bytes used to store the string. If the object is a
ByteArray object (such as those returned from reading a binary encoded
channel), then this will return the actual byte length of the object.
number of bytes used to store the string. If the value is a
byte array value (such as those returned from reading a binary encoded
channel), then this will return the actual byte length of the value.
.TP
\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
.
@@ -335,22 +318,47 @@ specified using the forms described in \fBSTRING INDICES\fR.
.
Returns a value equal to \fIstring\fR except that any leading or
trailing characters present in the string given by \fIchars\fR are removed. If
\fIchars\fR is not specified then white space is removed (spaces,
tabs, newlines, and carriage returns).
\fIchars\fR is not specified then white space is removed (any character
for which \fBstring is space\fR returns 1, and "\0").
.TP
\fBstring trimleft \fIstring\fR ?\fIchars\fR?
.
Returns a value equal to \fIstring\fR except that any leading
characters present in the string given by \fIchars\fR are removed. If
\fIchars\fR is not specified then white space is removed (spaces,
tabs, newlines, and carriage returns).
\fIchars\fR is not specified then white space is removed (any character
for which \fBstring is space\fR returns 1, and "\0").
.TP
\fBstring trimright \fIstring\fR ?\fIchars\fR?
.
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 (spaces,
tabs, newlines, and carriage returns).
\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
@@ -12,7 +12,7 @@
.SH NAME
tclsh \- Simple shell containing Tcl interpreter
.SH SYNOPSIS
\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
\fBtclsh\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
+103 -34
View File
@@ -1,5 +1,5 @@
'\"
'\" Copyright (c) 2008 Donal K. Fellows
'\" Copyright (c) 2008-2012 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -170,6 +170,13 @@ the
.QW "\fIoptions ...\fR"
to the \fBzlib push\fR command:
.TP
\fB\-dictionary\fI binData\fR
.VS "TIP 400"
Sets the compression dictionary to use when working with compressing or
decompressing the data to be \fIbinData\fR. Not valid for transformations that
work with gzip-format data.
.VE
.TP
\fB\-header\fI dictionary\fR
.
Passes a description of the gzip header to create, in the same format that
@@ -179,15 +186,33 @@ Passes a description of the gzip header to create, in the same format that
.
How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
(maximally compressed).
'\".TP
'\"\fB\-limit\fI readaheadLimit\fR
'\".
'\"The maximum number of bytes ahead to read.
'\"\fITODO: not yet implemented!\fR
.TP
\fB\-limit\fI readaheadLimit\fR
.
The maximum number of bytes ahead to read when decompressing. This defaults to
1, which ensures that data is always decompressed correctly, but may be
increased to improve performance. This is more useful when the channel is
non-blocking.
.PP
Both compressing and decompressing channel transformations add extra
configuration options that may be accessed through \fBchan configure\fR. Each
option is either a read-only or a write-only option. The options are:
configuration options that may be accessed through \fBchan configure\fR. The
options are:
.TP
\fB\-checksum\fI checksum\fR
.
This read-only option gets the current checksum for the uncompressed data that
the compression engine has seen so far. It is valid for both compressing and
decompressing transforms, but not for the raw inflate and deflate formats. The
compression algorithm depends on what format is being produced or consumed.
.TP
\fB\-dictionary\fI binData\fR
.VS "TIP 400"
This read-write options gets or sets the compression dictionary to use when
working with compressing or decompressing the data to be \fIbinData\fR. It is
not valid for transformations that work with gzip-format data, and should not
normally be set on compressing transformations other than at the point where
the transformation is stacked.
.VE
.TP
\fB\-flush\fI type\fR
.
@@ -198,63 +223,80 @@ expensive flush respectively. Flushing degrades the compression ratio, but
makes it easier for a decompressor to recover more of the file in the case of
data corruption.
.TP
\fB\-checksum\fR
.
This read-only option gets the current checksum for the uncompressed data
that the compression engine has seen so far. It is valid for both
compressing and decompressing transforms, but not for the raw inflate
and deflate formats. The compression algorithm depends on what
format is being produced or consumed.
.TP
\fB\-header\fR
\fB\-header\fI dictionary\fR
.
This read-only option, only valid for decompressing transforms that are
processing gzip-format data, returns the dictionary describing the header read
off the data stream.
.TP
\fB\-limit\fI readaheadLimit\fR
.
This read-write option is used by decompressing channels to control the
maximum number of bytes ahead to read from the underlying data source. This
defaults to 1, which ensures that data is always decompressed correctly, but
may be increased to improve performance. This is more useful when the channel
is non-blocking.
.RE
.SS "STREAMING SUBCOMMAND"
.TP
\fBzlib stream\fI mode\fR ?\fIlevel\fR?
\fBzlib stream\fI mode\fR ?\fIoptions\fR?
.
Creates a streaming compression or decompression command based on the
\fImode\fR, and return the name of the command. For a description of how that
command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
are supported:
and \fIoptions\fR are supported:
.RS
.TP
\fBzlib stream compress\fR ?\fIlevel\fR?
\fBzlib stream compress\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces zlib-format output,
using compression level \fIlevel\fR (if specified) which will be an integer
from 0 to 9.
from 0 to 9,
.VS "TIP 400"
and the compression dictionary \fIbindata\fR (if specified).
.VE
.TP
\fBzlib stream decompress\fR
\fBzlib stream decompress\fR ?\fB\-dictionary \fIbindata\fR?
.
The stream will be a decompressing stream that takes zlib-format input and
produces uncompressed output.
.VS "TIP 400"
If \fIbindata\fR is supplied, it is a compression dictionary to use if
required.
.VE
.TP
\fBzlib stream deflate\fR ?\fIlevel\fR?
\fBzlib stream deflate\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces raw output, using
compression level \fIlevel\fR (if specified) which will be an integer from 0
to 9.
to 9,
.VS "TIP 400"
and the compression dictionary \fIbindata\fR (if specified). Note that
the raw compressed data includes no metadata about what compression
dictionary was used, if any; that is a feature of the zlib-format data.
.VE
.TP
\fBzlib stream gunzip\fR
.
The stream will be a decompressing stream that takes gzip-format input and
produces uncompressed output.
.TP
\fBzlib stream gzip\fR ?\fIlevel\fR?
\fBzlib stream gzip\fR ?\fB\-header \fIheader\fR? ?\fB\-level \fIlevel\fR?
.
The stream will be a compressing stream that produces gzip-format output,
using compression level \fIlevel\fR (if specified) which will be an integer
from 0 to 9.
'\" TODO: Header dictionary!
from 0 to 9, and the header descriptor dictionary \fIheader\fR (if specified;
for keys see \fBzlib gzip\fR).
.TP
\fBzlib stream inflate\fR
\fBzlib stream inflate\fR ?\fB\-dictionary \fIbindata\fR?
.
The stream will be a decompressing stream that takes raw compressed input and
produces uncompressed output.
.VS "TIP 400"
If \fIbindata\fR is supplied, it is a compression dictionary to use. Note that
there are no checks in place to determine whether the compression dictionary
is correct.
.VE
.RE
.SS "CHECKSUMMING SUBCOMMANDS"
.TP
@@ -277,10 +319,10 @@ the transformed data.
The full set of subcommands supported by a streaming instance command,
\fIstream\fR, is as follows:
.TP
\fIstream \fBadd\fR ?\fIoption\fR? \fIdata\fR
\fIstream \fBadd\fR ?\fIoption...\fR? \fIdata\fR
.
A short-cut for
.QW "\fIstream \fBput \fIoption data\fR"
.QW "\fIstream \fBput \fR?\fIoption...\fR? \fIdata\fR"
followed by
.QW "\fIstream \fBget\fR" .
.TP
@@ -318,15 +360,27 @@ A short-cut for
Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
transformation applied. If \fIcount\fR is omitted, the entire contents of the
buffers are returned.
.
\fIstream \fBheader\fR
.
Return the gzip header description dictionary extracted from the stream. Only
supported for streams created with their \fImode\fR parameter set to
\fBgunzip\fR.
.TP
\fIstream \fBput\fR ?\fIoption\fR? \fIdata\fR
\fIstream \fBput\fR ?\fIoption...\fR? \fIdata\fR
.
Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
buffers while applying the transformation. If present, \fIoption\fR must be
one of the following (or an unambiguous prefix) which are used to modify the
buffers while applying the transformation. The following \fIoption\fRs are
supported (or an unambiguous prefix of them), which are used to modify the
way in which the transformation is applied:
.RS
.TP
\fB\-dictionary\fI binData\fR
.VS "TIP 400"
Sets the compression dictionary to use when working with compressing or
decompressing the data to be \fIbinData\fR.
.VE
.TP
\fB\-finalize\fR
.
Mark the stream as finished, ensuring that all bytes have been wholly
@@ -334,12 +388,22 @@ compressed or decompressed. For gzip streams, this also ensures that the
footer is written to the stream. The stream will need to be reset before
having more data written to it after this, though data can still be read out
of the stream with the \fBget\fR subcommand.
.RS
.PP
This option is mutually exclusive with the \fB\-flush\fR and \fB\-fullflush\fR
options.
.RE
.TP
\fB\-flush\fR
.
Ensure that a decompressor consuming the bytes that the current (compressing)
stream is producing will be able to produce all the bytes that have been
compressed so far, at some performance penalty.
.RS
.PP
This option is mutually exclusive with the \fB\-finalize\fR and
\fB\-fullflush\fR options.
.RE
.TP
\fB\-fullflush\fR
.
@@ -347,6 +411,11 @@ Ensure that not only can a decompressor handle all the bytes produced so far
(as with \fB\-flush\fR above) but also that it can restart from this point if
it detects that the stream is partially corrupt. This incurs a substantial
performance penalty.
.RS
.PP
This option is mutually exclusive with the \fB\-finalize\fR and \fB\-flush\fR
options.
.RE
.RE
.TP
\fIstream \fBreset\fR
@@ -385,7 +454,7 @@ $\fIstrm \fBclose\fR
.SH "SEE ALSO"
binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
.SH "KEYWORDS"
compress, decompress, deflate, gzip, inflate
compress, decompress, deflate, gzip, inflate, zlib
'\" Local Variables:
'\" mode: nroff
'\" End:
+3 -2
View File
@@ -354,13 +354,14 @@ static const chr punctCharTable[] = {
*/
static const crange spaceRangeTable[] = {
{0x9, 0xd}, {0x2000, 0x200a}
{0x9, 0xd}, {0x2000, 0x200b}
};
#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
static const chr spaceCharTable[] = {
0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f,
0x2060, 0x3000, 0xfeff
};
#define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
+6
View File
@@ -2318,6 +2318,12 @@ declare 629 {
int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr)
}
# TIP #400
declare 630 {
void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle,
Tcl_Obj *compressionDictionaryObj)
}
# ----- BASELINE -- FOR -- 8.6.0 ----- #
##############################################################################
+20 -10
View File
@@ -51,17 +51,15 @@ extern "C" {
* win/README (not patchlevel) (sections 0 and 2)
* unix/tcl.spec (1 LOC patch)
* tools/tcl.hpj.in (not patchlevel, for windows installer)
* tools/tcl.wse.in (for windows installer)
* tools/tclSplash.bmp (not patchlevel)
*/
#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"
/*
*----------------------------------------------------------------------------
@@ -856,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);
@@ -1073,6 +1068,8 @@ typedef struct Tcl_DString {
#define TCL_EVAL_INVOKE 0x080000
#define TCL_CANCEL_UNWIND 0x100000
#define TCL_EVAL_NOERR 0x200000
#define TCL_EVAL_REDIRECT 0x400000
/*
* Special freeProc values that may be passed to Tcl_SetResult (see the man
@@ -2362,6 +2359,14 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
#define TCL_ZLIB_FULLFLUSH 3
#define TCL_ZLIB_FINALIZE 4
/*
*----------------------------------------------------------------------------
* Definitions needed for the Tcl_LoadFile function. [TIP #416]
*/
#define TCL_LOAD_GLOBAL 1
#define TCL_LOAD_LAZY 2
/*
*----------------------------------------------------------------------------
* Single public declaration for NRE.
@@ -2498,7 +2503,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
+27 -1
View File
@@ -362,6 +362,10 @@ static const TalInstDesc TalInstructionTable[] = {
| INST_APPEND_ARRAY4), 2, 1},
{"appendArrayStk", ASSEM_1BYTE, INST_APPEND_ARRAY_STK, 3, 1},
{"appendStk", ASSEM_1BYTE, INST_APPEND_STK, 2, 1},
{"arrayExistsImm", ASSEM_LVT4, INST_ARRAY_EXISTS_IMM, 0, 1},
{"arrayExistsStk", ASSEM_1BYTE, INST_ARRAY_EXISTS_STK, 1, 1},
{"arrayMakeImm", ASSEM_LVT4, INST_ARRAY_MAKE_IMM, 0, 0},
{"arrayMakeStk", ASSEM_1BYTE, INST_ARRAY_MAKE_STK, 1, 0},
{"beginCatch", ASSEM_BEGIN_CATCH,
INST_BEGIN_CATCH4, 0, 0},
{"bitand", ASSEM_1BYTE, INST_BITAND, 2, 1},
@@ -369,7 +373,10 @@ static const TalInstDesc TalInstructionTable[] = {
{"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1},
{"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1},
{"concat", ASSEM_CONCAT1, INST_CONCAT1, INT_MIN,1},
{"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1},
{"currentNamespace",ASSEM_1BYTE, INST_NS_CURRENT, 0, 1},
{"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1},
{"dictExists", ASSEM_DICT_GET, INST_DICT_EXISTS, INT_MIN,1},
{"dictExpand", ASSEM_1BYTE, INST_DICT_EXPAND, 3, 1},
{"dictGet", ASSEM_DICT_GET, INST_DICT_GET, INT_MIN,1},
{"dictIncrImm", ASSEM_SINT4_LVT4,
@@ -406,6 +413,8 @@ static const TalInstDesc TalInstructionTable[] = {
{"incrStk", ASSEM_1BYTE, INST_INCR_SCALAR_STK, 2, 1},
{"incrStkImm", ASSEM_SINT1, INST_INCR_SCALAR_STK_IMM,
1, 1},
{"infoLevelArgs", ASSEM_1BYTE, INST_INFO_LEVEL_ARGS, 1, 1},
{"infoLevelNumber", ASSEM_1BYTE, INST_INFO_LEVEL_NUM, 0, 1},
{"invokeStk", ASSEM_INVOKE, (INST_INVOKE_STK1 << 8
| INST_INVOKE_STK4), INT_MIN,1},
{"jump", ASSEM_JUMP, INST_JUMP1, 0, 0},
@@ -457,6 +466,7 @@ static const TalInstDesc TalInstructionTable[] = {
0, 1},
{"pushResult", ASSEM_1BYTE, INST_PUSH_RESULT, 0, 1},
{"regexp", ASSEM_REGEXP, INST_REGEXP, 2, 1},
{"resolveCmd", ASSEM_1BYTE, INST_RESOLVE_COMMAND, 1, 1},
{"reverse", ASSEM_REVERSE, INST_REVERSE, INT_MIN,-1-0},
{"rshift", ASSEM_1BYTE, INST_RSHIFT, 2, 1},
{"store", ASSEM_LVT, (INST_STORE_SCALAR1<<8
@@ -467,11 +477,19 @@ static const TalInstDesc TalInstructionTable[] = {
{"storeStk", ASSEM_1BYTE, INST_STORE_SCALAR_STK, 2, 1},
{"strcmp", ASSEM_1BYTE, INST_STR_CMP, 2, 1},
{"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1},
{"strfind", ASSEM_1BYTE, INST_STR_FIND, 2, 1},
{"strindex", ASSEM_1BYTE, INST_STR_INDEX, 2, 1},
{"strlen", ASSEM_1BYTE, INST_STR_LEN, 1, 1},
{"strmap", ASSEM_1BYTE, INST_STR_MAP, 3, 1},
{"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1},
{"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1},
{"strrange", ASSEM_1BYTE, INST_STR_RANGE, 3, 1},
{"strrfind", ASSEM_1BYTE, INST_STR_FIND_LAST, 2, 1},
{"sub", ASSEM_1BYTE, INST_SUB, 2, 1},
{"tclooClass", ASSEM_1BYTE, INST_TCLOO_CLASS, 1, 1},
{"tclooIsObject", ASSEM_1BYTE, INST_TCLOO_IS_OBJECT, 1, 1},
{"tclooNamespace", ASSEM_1BYTE, INST_TCLOO_NS, 1, 1},
{"tclooSelf", ASSEM_1BYTE, INST_TCLOO_SELF, 0, 1},
{"tryCvtToNumeric", ASSEM_1BYTE, INST_TRY_CVT_TO_NUMERIC,1, 1},
{"uminus", ASSEM_1BYTE, INST_UMINUS, 1, 1},
{"unset", ASSEM_BOOL_LVT4,INST_UNSET_SCALAR, 0, 0},
@@ -481,6 +499,8 @@ static const TalInstDesc TalInstructionTable[] = {
{"uplus", ASSEM_1BYTE, INST_UPLUS, 1, 1},
{"upvar", ASSEM_LVT4, INST_UPVAR, 2, 1},
{"variable", ASSEM_LVT4, INST_VARIABLE, 1, 0},
{"verifyDict", ASSEM_1BYTE, INST_DICT_VERIFY, 1, 0},
{"yield", ASSEM_1BYTE, INST_YIELD, 1, 1},
{NULL, 0, 0, 0, 0}
};
@@ -499,7 +519,13 @@ static const unsigned char NonThrowingByteCodes[] = {
INST_OVER, /* 95 */
INST_PUSH_RETURN_OPTIONS, /* 108 */
INST_REVERSE, /* 126 */
INST_NOP /* 132 */
INST_NOP, /* 132 */
INST_STR_MAP, /* 143 */
INST_STR_FIND, /* 144 */
INST_COROUTINE_NAME, /* 149 */
INST_NS_CURRENT, /* 151 */
INST_INFO_LEVEL_NUM, /* 152 */
INST_RESOLVE_COMMAND /* 154 */
};
/*
+224 -112
View File
@@ -131,13 +131,11 @@ static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc,
Tcl_Obj *const objv[], int lookup);
static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
int actual, Tcl_Obj *const *objv);
static Tcl_NRPostProc NRCoroutineActivateCallback;
static Tcl_NRPostProc NRCoroutineCallerCallback;
static Tcl_NRPostProc NRCoroutineExitCallback;
static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
static Tcl_NRPostProc NRRunObjProc;
static Tcl_NRPostProc NRTailcallEval;
static Tcl_ObjCmdProc OldMathFuncProc;
static void OldMathFuncDeleteProc(ClientData clientData);
static void ProcessUnexpectedResult(Tcl_Interp *interp,
@@ -164,10 +162,10 @@ 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;
static inline void SpliceDeferred(Tcl_Interp *interp);
MODULE_SCOPE const TclStubs tclStubs;
/*
@@ -219,7 +217,7 @@ static const CmdInfo builtInCmds[] = {
{"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, 1},
{"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, 1},
{"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, 1},
{"format", Tcl_FormatObjCmd, NULL, NULL, 1},
{"format", Tcl_FormatObjCmd, TclCompileFormatCmd, NULL, 1},
{"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, NULL, 1},
{"if", Tcl_IfObjCmd, TclCompileIfCmd, TclNRIfObjCmd, 1},
{"incr", Tcl_IncrObjCmd, TclCompileIncrCmd, NULL, 1},
@@ -241,7 +239,7 @@ static const CmdInfo builtInCmds[] = {
{"package", Tcl_PackageObjCmd, NULL, NULL, 1},
{"proc", Tcl_ProcObjCmd, NULL, NULL, 1},
{"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, 1},
{"regsub", Tcl_RegsubObjCmd, NULL, NULL, 1},
{"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, 1},
{"rename", Tcl_RenameObjCmd, NULL, NULL, 1},
{"return", Tcl_ReturnObjCmd, TclCompileReturnCmd, NULL, 1},
{"scan", Tcl_ScanObjCmd, NULL, NULL, 1},
@@ -249,7 +247,7 @@ static const CmdInfo builtInCmds[] = {
{"split", Tcl_SplitObjCmd, NULL, NULL, 1},
{"subst", Tcl_SubstObjCmd, TclCompileSubstCmd, TclNRSubstObjCmd, 1},
{"switch", Tcl_SwitchObjCmd, TclCompileSwitchCmd, TclNRSwitchObjCmd, 1},
{"tailcall", NULL, NULL, TclNRTailcallObjCmd, 1},
{"tailcall", NULL, TclCompileTailcallCmd, TclNRTailcallObjCmd, 1},
{"throw", Tcl_ThrowObjCmd, TclCompileThrowCmd, NULL, 1},
{"trace", Tcl_TraceObjCmd, NULL, NULL, 1},
{"try", Tcl_TryObjCmd, TclCompileTryCmd, TclNRTryObjCmd, 1},
@@ -258,7 +256,7 @@ static const CmdInfo builtInCmds[] = {
{"upvar", Tcl_UpvarObjCmd, TclCompileUpvarCmd, NULL, 1},
{"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, 1},
{"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, 1},
{"yield", NULL, NULL, TclNRYieldObjCmd, 1},
{"yield", NULL, TclCompileYieldCmd, TclNRYieldObjCmd, 1},
{"yieldto", NULL, NULL, TclNRYieldToObjCmd, 1},
/*
@@ -3758,41 +3756,28 @@ Tcl_ListMathFuncs(
Tcl_Interp *interp,
const char *pattern)
{
Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
Namespace *nsPtr;
Namespace *dummy1NsPtr;
Namespace *dummy2NsPtr;
const char *dummyNamePtr;
Tcl_Obj *result = Tcl_NewObj();
Tcl_Obj *script = Tcl_NewStringObj("::info functions ", -1);
Tcl_Obj *result;
Tcl_InterpState state;
TclGetNamespaceForQualName(interp, "::tcl::mathfunc",
globalNsPtr, TCL_FIND_ONLY_NS | TCL_GLOBAL_ONLY,
&nsPtr, &dummy1NsPtr, &dummy2NsPtr, &dummyNamePtr);
if (nsPtr == NULL) {
return result;
if (pattern) {
Tcl_Obj *patternObj = Tcl_NewStringObj(pattern, -1);
Tcl_Obj *arg = Tcl_NewListObj(1, &patternObj);
Tcl_AppendObjToObj(script, arg);
Tcl_DecrRefCount(arg); /* Should tear down patternObj too */
}
if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
if (Tcl_FindHashEntry(&nsPtr->cmdTable, pattern) != NULL) {
Tcl_ListObjAppendElement(NULL, result,
Tcl_NewStringObj(pattern, -1));
}
state = Tcl_SaveInterpState(interp, TCL_OK);
Tcl_IncrRefCount(script);
if (TCL_OK == Tcl_EvalObjEx(interp, script, 0)) {
result = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
} else {
Tcl_HashSearch cmdHashSearch;
Tcl_HashEntry *cmdHashEntry =
Tcl_FirstHashEntry(&nsPtr->cmdTable,&cmdHashSearch);
for (; cmdHashEntry != NULL;
cmdHashEntry = Tcl_NextHashEntry(&cmdHashSearch)) {
const char *cmdNamePtr =
Tcl_GetHashKey(&nsPtr->cmdTable, cmdHashEntry);
if (pattern == NULL || Tcl_StringMatch(cmdNamePtr, pattern)) {
Tcl_ListObjAppendElement(NULL, result,
Tcl_NewStringObj(cmdNamePtr, -1));
}
}
result = Tcl_NewObj();
}
Tcl_DecrRefCount(script);
Tcl_RestoreInterpState(interp, state);
return result;
}
@@ -4189,15 +4174,14 @@ TclNREvalObjv(
* finishes the source command and not just the target.
*/
if (iPtr->evalFlags & TCL_EVAL_REDIRECT) {
if (flags & TCL_EVAL_REDIRECT) {
TclNRAddCallback(interp, NRCommand, NULL, INT2PTR(1), INT2PTR(objc), objv);
iPtr->evalFlags &= ~TCL_EVAL_REDIRECT;
} else {
TclNRAddCallback(interp, NRCommand, NULL, NULL, INT2PTR(objc), objv);
}
cmdPtrPtr = (Command **) &(TOP_CB(interp)->data[0]);
TclNRSpliceDeferred(interp);
SpliceDeferred(interp);
iPtr->numLevels++;
result = TclInterpReady(interp);
@@ -4318,6 +4302,7 @@ TclNREvalObjv(
if (cmdPtr->nreProc) {
TclNRAddCallback(interp, NRRunObjProc, cmdPtr,
INT2PTR(objc), (ClientData) objv, NULL);
return TCL_OK;
} else {
return cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
@@ -4341,7 +4326,7 @@ TclNRRunCallbacks(
* are to be run. */
{
Interp *iPtr = (Interp *) interp;
NRE_callback *callbackPtr;
NRE_callback *cbPtr;
Tcl_NRPostProc *procPtr;
/*
@@ -4359,11 +4344,10 @@ TclNRRunCallbacks(
}
while (TOP_CB(interp) != rootPtr) {
callbackPtr = TOP_CB(interp);
procPtr = callbackPtr->procPtr;
TOP_CB(interp) = callbackPtr->nextPtr;
result = procPtr(callbackPtr->data, interp, result);
TCLNR_FREE(interp, callbackPtr);
POP_CB(interp, cbPtr);
procPtr = cbPtr->procPtr;
result = procPtr(cbPtr->data, interp, result);
FREE_CB(cbPtr);
}
return result;
}
@@ -4383,6 +4367,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?
@@ -4640,10 +4632,10 @@ TEOV_NotFound(
savedNsPtr = varFramePtr->nsPtr;
varFramePtr->nsPtr = lookupNsPtr;
}
TclNRDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
TclDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
newObjv, savedNsPtr, NULL);
iPtr->evalFlags |= TCL_EVAL_REDIRECT;
return TclNREvalObjv(interp, newObjc, newObjv, TCL_EVAL_NOERR, NULL);
return TclNREvalObjv(interp, newObjc, newObjv, (TCL_EVAL_NOERR|TCL_EVAL_REDIRECT),
NULL);
}
static int
@@ -6027,7 +6019,7 @@ TclNREvalObjEx(
iPtr->cmdFramePtr = eoFramePtr;
}
TclNRDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
TclDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
NULL, NULL);
ListObjGetElements(listPtr, objc, objv);
@@ -8283,10 +8275,151 @@ Tcl_NRCmdSwap(
* FIXME NRE!
*/
//#define PR(x) fprint(stdout, x)
#define PR(x)
void
TclSpliceTailcall(
TclDeferCallback(
Tcl_Interp *interp,
NRE_callback *tailcallPtr)
Tcl_NRPostProc *postProcPtr,
ClientData data0, ClientData data1,
ClientData data2, ClientData data3)
{
Interp *iPtr = (Interp *) interp;
NRE_callback *cbPtr;
TclNRAddCallback(interp, postProcPtr, data0, data1,
data2, data3);
cbPtr = TOP_CB(interp);
cbPtr->nextPtr = iPtr->deferredCallbacks;
iPtr->deferredCallbacks = cbPtr;
}
static void
SpliceDeferred(
Tcl_Interp *interp)
{
PR("CALLED SpliceDeferred\n");
return;
/* STUPID: optimize a bit */
#if 0
Interp *iPtr = (Interp *) interp;
int deferred = iPtr->deferredCallbacks;
NRE_callback *tosPtr = TOP_CB(interp), *runPtr;
if (deferred) {
NRE_callback *tmp;
int i;
tmp = ckalloc(deferred*sizeof(NRE_callback));
i = deferred;
while (i--) {
POP_CB(interp, runPtr);
tmp[i] = *runPtr;
}
ALLOC_CB(interp, runPtr);
*runPtr = *tosPtr;
i = deferred;
for (i=0; i < deferred; i++) {
ALLOC_CB(interp, runPtr);
*runPtr = tmp[i];
}
ckfree(tmp);
iPtr->deferredCallbacks = 0;
}
#endif
}
int
TclNRStackBottom(
ClientData data[],
Tcl_Interp *interp,
int result)
{
Interp *iPtr = (Interp *) interp;
ExecEnv *eePtr = iPtr->execEnvPtr;
NRE_stack *this = eePtr->NRStack;
NRE_stack *prev = data[0];
PR("CALLED TclNRStackBottom\n");
if (!prev) {
Tcl_Panic("Reached the NRE-stack bottom, should not happen!");
}
/*
* Go back to the previous stack.
*/
eePtr->NRStack = prev;
eePtr->callbackPtr = &prev->items[NRE_STACK_SIZE-1];
/*
* Keep this stack in reserve. If this one had a successor, free that one:
* we always keep just one in reserve.
*/
if (this->next) {
ckfree (this->next);
this->next = NULL;
}
return result;
}
NRE_callback *
TclNewCallback(
Tcl_Interp *interp)
{
Interp *iPtr = (Interp *) interp;
ExecEnv *eePtr = iPtr->execEnvPtr;
NRE_callback *cbPtr = eePtr->callbackPtr;
NRE_stack *this = eePtr->NRStack;
#if NEW
if (!this || (cbPtr == &this->items[NRE_STACK_SIZE-1])) {
PR("ALLOC\n");
if (this && this->next) {
eePtr->NRStack = this->next;
} else {
eePtr->NRStack = (NRE_stack *) ckalloc(sizeof(NRE_stack));
eePtr->NRStack->next = NULL;
}
eePtr->callbackPtr = &eePtr->NRStack->items[-1];
TclNRAddCallback(interp, TclNRStackBottom, this, NULL, NULL, NULL);
} else {
PR("PUSH\n");
}
cbPtr++;
cbPtr->nextPtr = eePtr->callbackPtr;
eePtr->callbackPtr = cbPtr;
#endif
return eePtr->callbackPtr;
}
NRE_callback *
TclPopCallback(
Tcl_Interp *interp)
{
Interp *iPtr = (Interp *) interp;
ExecEnv *eePtr = iPtr->execEnvPtr;
NRE_callback *cbPtr = eePtr->callbackPtr, *tmp;
NRE_stack *this = eePtr->NRStack;
int depth = cbPtr - &this->items[1];
PR("POP\n");
--eePtr->callbackPtr;
return cbPtr;
}
/* ***************************************** */
void
TclSetTailcall(
Tcl_Interp *interp,
Tcl_Obj *listPtr)
{
/*
* Find the splicing spot: right before the NRCommand of the thing
@@ -8305,8 +8438,14 @@ TclSpliceTailcall(
Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!");
}
tailcallPtr->nextPtr = runPtr->nextPtr;
runPtr->nextPtr = tailcallPtr;
if (runPtr->data[1]) {
/*
* A tailcall was already scheduled: clear it!
*/
Tcl_Obj *oldPtr = (Tcl_Obj *) runPtr->data[1];
Tcl_DecrRefCount(oldPtr);
}
runPtr->data[1] = listPtr;
}
int
@@ -8323,7 +8462,7 @@ TclNRTailcallObjCmd(
return TCL_ERROR;
}
if (!iPtr->varFramePtr->isProcCallFrame) { /* or is upleveled */
if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { /* or is upleveled */
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"tailcall can only be called from a proc or lambda", -1));
Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
@@ -8336,7 +8475,7 @@ TclNRTailcallObjCmd(
*/
if (iPtr->varFramePtr->tailcallPtr) {
ClearTailcall(interp, iPtr->varFramePtr->tailcallPtr);
Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
iPtr->varFramePtr->tailcallPtr = NULL;
}
@@ -8351,40 +8490,39 @@ 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, NRTailcallEval, 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;
}
int
NRTailcallEval(
TclNRTailcallEval(
ClientData data[],
Tcl_Interp *interp,
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);
}
@@ -8403,10 +8541,9 @@ NRTailcallEval(
* Perform the tailcall
*/
TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsObjPtr, NULL,NULL);
TclDeferCallback(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
@@ -8416,19 +8553,8 @@ 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(
@@ -8495,7 +8621,7 @@ TclNRYieldObjCmd(
}
NRE_ASSERT(!COR_IS_SUSPENDED(corPtr));
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
clientData, NULL, NULL);
return TCL_OK;
}
@@ -8530,23 +8656,22 @@ TclNRYieldToObjCmd(
* This is essentially code from TclNRTailcallObjCmd
*/
listPtr = Tcl_NewListObj(objc-1, objv+1);
Tcl_IncrRefCount(listPtr);
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);
TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, NULL, NULL);
iPtr->execEnvPtr = corPtr->eePtr;
return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv);
@@ -8558,20 +8683,7 @@ YieldToCallback(
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, NRTailcallEval, listPtr, nsPtr, NULL, NULL);
cbPtr = TOP_CB(interp);
TOP_CB(interp) = cbPtr->nextPtr;
TclSpliceTailcall(interp, cbPtr);
TclSetTailcall(interp, (Tcl_Obj *) data[1]);
return TCL_OK;
}
@@ -8712,7 +8824,7 @@ NRCoroutineExitCallback(
/*
*----------------------------------------------------------------------
*
* NRCoroutineActivateCallback --
* TclNRCoroutineActivateCallback --
*
* This is the workhorse for coroutines: it implements both yield and
* resume.
@@ -8726,8 +8838,8 @@ NRCoroutineExitCallback(
*----------------------------------------------------------------------
*/
static int
NRCoroutineActivateCallback(
int
TclNRCoroutineActivateCallback(
ClientData data[],
Tcl_Interp *interp,
int result)
@@ -8902,7 +9014,7 @@ TclNRInterpCoroutine(
break;
}
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
NULL, NULL, NULL);
return TCL_OK;
}
@@ -9028,7 +9140,6 @@ TclNRCoroutineObjCmd(
corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
corPtr->stackLevel = NULL;
corPtr->auxNumLevels = 0;
iPtr->numLevels--;
/*
* Create the coro's execEnv, switch to it to push the exit and coro
@@ -9047,19 +9158,20 @@ TclNRCoroutineObjCmd(
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
NULL, NULL, NULL);
/* insure that the command is looked up in the correct namespace */
iPtr->lookupNsPtr = lookupNsPtr;
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
iPtr->numLevels--;
SAVE_CONTEXT(corPtr->running);
RESTORE_CONTEXT(corPtr->caller);
iPtr->execEnvPtr = corPtr->callerEEPtr;
/*
* Now just resume the coroutine. Take care to insure that the command is
* looked up in the correct namespace.
* Now just resume the coroutine.
*/
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
NULL, NULL, NULL);
return TCL_OK;
}
+98 -52
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
@@ -688,26 +712,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 +2361,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 +2575,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) {
@@ -2658,16 +2662,16 @@ BinaryDecode64(
Tcl_Obj *const objv[])
{
Tcl_Obj *resultObj = NULL;
unsigned char *data, *datastart, *dataend, c;
unsigned char *data, *datastart, *dataend, c = '\0';
unsigned char *begin = NULL;
unsigned char *cursor = NULL;
int strict = 0;
int i, index, size, cut = 0, count = 0;
enum {OPT_STRICT };
enum { OPT_STRICT };
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) {
@@ -2691,43 +2695,85 @@ BinaryDecode64(
while (data < dataend) {
unsigned long value = 0;
for (i=0 ; i<4 ; i++) {
/*
* Decode the current block. Each base64 block consists of four input
* characters A-Z, a-z, 0-9, +, or /. Each character supplies six bits
* of output data, so each block's output is 24 bits (three bytes) in
* length. The final block can be shorter by one or two bytes, denoted
* by the input ending with one or two ='s, respectively.
*/
for (i = 0; i < 4; i++) {
/*
* Get the next input character. At end of input, pad with at most
* two ='s. If more than two ='s would be needed, instead discard
* the block read thus far.
*/
if (data < dataend) {
c = *data++;
if (c >= 'A' && c <= 'Z') {
value = (value << 6) | ((c - 'A') & 0x3f);
} else if (c >= 'a' && c <= 'z') {
value = (value << 6) | ((c - 'a' + 26) & 0x3f);
} else if (c >= '0' && c <= '9') {
value = (value << 6) | ((c - '0' + 52) & 0x3f);
} else if (c == '+') {
value = (value << 6) | 0x3e;
} else if (c == '/') {
value = (value << 6) | 0x3f;
} else if (c == '=') {
value <<= 6;
if (cut < 2) {
cut++;
}
} else {
if (strict || !isspace(c)) {
goto bad64;
}
i--;
continue;
}
} else if (i > 1) {
c = '=';
} else {
cut += 3;
break;
}
/*
* Load the character into the block value. Handle ='s specially
* because they're only valid as the last character or two of the
* final block of input. Unless strict mode is enabled, skip any
* input whitespace characters.
*/
if (cut) {
if (c == '=' && i > 1) {
value <<= 6;
cut++;
} else if (!strict && isspace(c)) {
i--;
} else {
goto bad64;
}
} else if (c >= 'A' && c <= 'Z') {
value = (value << 6) | ((c - 'A') & 0x3f);
} else if (c >= 'a' && c <= 'z') {
value = (value << 6) | ((c - 'a' + 26) & 0x3f);
} else if (c >= '0' && c <= '9') {
value = (value << 6) | ((c - '0' + 52) & 0x3f);
} else if (c == '+') {
value = (value << 6) | 0x3e;
} else if (c == '/') {
value = (value << 6) | 0x3f;
} else if (c == '=') {
value <<= 6;
cut++;
} else if (strict || !isspace(c)) {
goto bad64;
} else {
i--;
}
}
*cursor++ = UCHAR((value >> 16) & 0xff);
*cursor++ = UCHAR((value >> 8) & 0xff);
*cursor++ = UCHAR(value & 0xff);
}
if (cut > size) {
cut = size;
/*
* Since = is only valid within the final block, if it was encountered
* but there are still more input characters, confirm that strict mode
* is off and all subsequent characters are whitespace.
*/
if (cut && data < dataend) {
if (strict) {
goto bad64;
}
for (; data < dataend; data++) {
if (!isspace(*data)) {
goto bad64;
}
}
}
}
Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
Tcl_SetObjResult(interp, resultObj);
+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);
+54 -31
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},
{"commands", InfoCommandsCmd, NULL, NULL, NULL, 0},
{"complete", InfoCompleteCmd, NULL, NULL, NULL, 0},
{"coroutine", TclInfoCoroutineCmd, NULL, NULL, NULL, 0},
{"default", InfoDefaultCmd, NULL, NULL, NULL, 0},
{"errorstack", InfoErrorStackCmd, 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, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, 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},
{"level", InfoLevelCmd, NULL, 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},
{"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, 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}
};
@@ -1492,19 +1492,42 @@ InfoFunctionsCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *pattern;
Tcl_Obj *script;
int code;
if (objc == 1) {
pattern = NULL;
} else if (objc == 2) {
pattern = TclGetString(objv[1]);
} else {
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_ListMathFuncs(interp, pattern));
return TCL_OK;
script = Tcl_NewStringObj(
" ::apply [::list {{pattern *}} {\n"
" ::set cmds {}\n"
" ::foreach cmd [::info commands ::tcl::mathfunc::$pattern] {\n"
" ::lappend cmds [::namespace tail $cmd]\n"
" }\n"
" ::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n"
" ::set cmd [::namespace tail $cmd]\n"
" ::if {$cmd ni $cmds} {\n"
" ::lappend cmds $cmd\n"
" }\n"
" }\n"
" ::return $cmds\n"
" } [::namespace current]] ", -1);
if (objc == 2) {
Tcl_Obj *arg = Tcl_NewListObj(1, &(objv[1]));
Tcl_AppendObjToObj(script, arg);
Tcl_DecrRefCount(arg);
}
Tcl_IncrRefCount(script);
code = Tcl_EvalObjEx(interp, script, 0);
Tcl_DecrRefCount(script);
return code;
}
/*
+42 -19
View File
@@ -34,12 +34,35 @@ static int UniCharIsHexDigit(int character);
/*
* Default set of characters to trim in [string trim] and friends. This is a
* UTF-8 literal string containing space, tab, newline, carriage return,
* ethiopic wordspace (U+1361), ogham space mark (U+1680), and ideographic
* space (U+3000). [TIP #318]
* UTF-8 literal string containing all Unicode space characters [TIP #413]
*/
#define DEFAULT_TRIM_SET " \t\n\r\xe1\x8d\xa1\xe1\x9a\x80\xe3\x80\x80"
#define DEFAULT_TRIM_SET \
"\x09\x0a\x0b\x0c\x0d " /* ASCII */\
"\xc0\x80" /* nul (U+0000) */\
"\xc2\x85" /* next line (U+0085) */\
"\xc2\xa0" /* non-breaking space (U+00a0) */\
"\xe1\x9a\x80" /* ogham space mark (U+1680) */ \
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\
"\xe2\x80\x80" /* en quad (U+2000) */\
"\xe2\x80\x81" /* em quad (U+2001) */\
"\xe2\x80\x82" /* en space (U+2002) */\
"\xe2\x80\x83" /* em space (U+2003) */\
"\xe2\x80\x84" /* three-per-em space (U+2004) */\
"\xe2\x80\x85" /* four-per-em space (U+2005) */\
"\xe2\x80\x86" /* six-per-em space (U+2006) */\
"\xe2\x80\x87" /* figure space (U+2007) */\
"\xe2\x80\x88" /* punctuation space (U+2008) */\
"\xe2\x80\x89" /* thin space (U+2009) */\
"\xe2\x80\x8a" /* hair space (U+200a) */\
"\xe2\x80\x8b" /* zero width space (U+200b) */\
"\xe2\x80\xa8" /* line separator (U+2028) */\
"\xe2\x80\xa9" /* paragraph separator (U+2029) */\
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */\
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */\
"\xe2\x81\xa0" /* word joiner (U+2060) */\
"\xe3\x80\x80" /* ideographic space (U+3000) */\
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
/*
*----------------------------------------------------------------------
@@ -3301,28 +3324,28 @@ 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, NULL, NULL, NULL, 0},
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
{"index", StringIndexCmd, TclCompileStringIndexCmd, NULL, NULL, 0},
{"is", StringIsCmd, NULL, NULL, NULL, 0},
{"last", StringLastCmd, NULL, NULL, NULL, 0},
{"last", StringLastCmd, TclCompileStringLastCmd, NULL, NULL, 0},
{"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0},
{"map", StringMapCmd, NULL, NULL, NULL, 0},
{"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0},
{"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0},
{"range", StringRangeCmd, NULL, NULL, NULL, 0},
{"repeat", StringReptCmd, NULL, NULL, NULL, 0},
{"range", StringRangeCmd, TclCompileStringRangeCmd, 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}
};
+1416 -35
View File
File diff suppressed because it is too large Load Diff
+413 -158
View File
@@ -133,6 +133,8 @@ const AuxDataType tclJumptableInfoType = {
#define OP(name) TclEmitOpcode(INST_##name, envPtr)
#define OP1(name,val) TclEmitInstInt1(INST_##name,(val),envPtr)
#define OP4(name,val) TclEmitInstInt4(INST_##name,(val),envPtr)
#define OP14(name,val1,val2) \
TclEmitInstInt1(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
#define OP44(name,val1,val2) \
TclEmitInstInt4(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
#define BODY(token,index) \
@@ -249,18 +251,18 @@ TclCompileSetCmd(
/*
*----------------------------------------------------------------------
*
* TclCompileStringCmpCmd --
* TclCompileString*Cmd --
*
* Procedure called to compile the simplest and most common form of the
* "string compare" command.
* Procedures called to compile various subcommands of the "string"
* command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "string compare"
* command at runtime.
* Instructions are added to envPtr to execute the "string" command at
* runtime.
*
*----------------------------------------------------------------------
*/
@@ -296,25 +298,6 @@ TclCompileStringCmpCmd(
TclEmitOpcode(INST_STR_CMP, envPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclCompileStringEqualCmd --
*
* Procedure called to compile the simplest and most common form of the
* "string equal" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "string equal" command
* at runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileStringEqualCmd(
@@ -347,25 +330,70 @@ TclCompileStringEqualCmd(
TclEmitOpcode(INST_STR_EQ, envPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclCompileStringIndexCmd --
*
* Procedure called to compile the simplest and most common form of the
* "string index" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "string index" command
* at runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileStringFirstCmd(
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. */
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *tokenPtr;
/*
* We don't support any flags; the bytecode isn't that sophisticated.
*/
if (parsePtr->numWords != 3) {
return TCL_ERROR;
}
/*
* Push the two operands onto the stack and then the test.
*/
tokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 1);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 2);
OP(STR_FIND);
return TCL_OK;
}
int
TclCompileStringLastCmd(
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. */
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *tokenPtr;
/*
* We don't support any flags; the bytecode isn't that sophisticated.
*/
if (parsePtr->numWords != 3) {
return TCL_ERROR;
}
/*
* Push the two operands onto the stack and then the test.
*/
tokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 1);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 2);
OP(STR_FIND_LAST);
return TCL_OK;
}
int
TclCompileStringIndexCmd(
@@ -394,25 +422,6 @@ TclCompileStringIndexCmd(
TclEmitOpcode(INST_STR_INDEX, envPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclCompileStringMatchCmd --
*
* Procedure called to compile the simplest and most common form of the
* "string match" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "string match" command
* at runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileStringMatchCmd(
@@ -494,25 +503,6 @@ TclCompileStringMatchCmd(
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclCompileStringLenCmd --
*
* Procedure called to compile the simplest and most common form of the
* "string length" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "string length"
* command at runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileStringLenCmd(
@@ -553,6 +543,158 @@ TclCompileStringLenCmd(
TclDecrRefCount(objPtr);
return TCL_OK;
}
int
TclCompileStringMapCmd(
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. */
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *mapTokenPtr, *stringTokenPtr;
Tcl_Obj *mapObj, **objv;
char *bytes;
int len;
/*
* We only handle the case:
*
* string map {foo bar} $thing
*
* That is, a literal two-element list (doesn't need to be brace-quoted,
* but does need to be compile-time knowable) and any old argument (the
* thing to map).
*/
if (parsePtr->numWords != 3) {
return TCL_ERROR;
}
mapTokenPtr = TokenAfter(parsePtr->tokenPtr);
stringTokenPtr = TokenAfter(mapTokenPtr);
mapObj = Tcl_NewObj();
Tcl_IncrRefCount(mapObj);
if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) {
Tcl_DecrRefCount(mapObj);
return TCL_ERROR;
} else if (Tcl_ListObjGetElements(NULL, mapObj, &len, &objv) != TCL_OK) {
Tcl_DecrRefCount(mapObj);
return TCL_ERROR;
} else if (len != 2) {
Tcl_DecrRefCount(mapObj);
return TCL_ERROR;
}
/*
* Now issue the opcodes. Note that in the case that we know that the
* first word is an empty word, we don't issue the map at all. That is the
* correct semantics for mapping.
*/
bytes = Tcl_GetStringFromObj(objv[0], &len);
if (len == 0) {
CompileWord(envPtr, stringTokenPtr, interp, 2);
} else {
PushLiteral(envPtr, bytes, len);
bytes = Tcl_GetStringFromObj(objv[1], &len);
PushLiteral(envPtr, bytes, len);
CompileWord(envPtr, stringTokenPtr, interp, 2);
OP(STR_MAP);
}
Tcl_DecrRefCount(mapObj);
return TCL_OK;
}
int
TclCompileStringRangeCmd(
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. */
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr;
Tcl_Obj *tmpObj;
int idx1, idx2, result;
if (parsePtr->numWords != 4) {
return TCL_ERROR;
}
stringTokenPtr = TokenAfter(parsePtr->tokenPtr);
fromTokenPtr = TokenAfter(stringTokenPtr);
toTokenPtr = TokenAfter(fromTokenPtr);
/*
* Parse the first index. Will only compile if it is constant and not an
* _integer_ less than zero (since we reserve negative indices here for
* end-relative indexing).
*/
tmpObj = Tcl_NewObj();
result = TCL_ERROR;
if (TclWordKnownAtCompileTime(fromTokenPtr, tmpObj)) {
if (TclGetIntFromObj(NULL, tmpObj, &idx1) == TCL_OK) {
if (idx1 >= 0) {
result = TCL_OK;
}
} else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx1) == TCL_OK) {
if (idx1 <= -2) {
result = TCL_OK;
}
}
}
TclDecrRefCount(tmpObj);
if (result != TCL_OK) {
goto nonConstantIndices;
}
/*
* Parse the second index. Will only compile if it is constant and not an
* _integer_ less than zero (since we reserve negative indices here for
* end-relative indexing).
*/
tmpObj = Tcl_NewObj();
result = TCL_ERROR;
if (TclWordKnownAtCompileTime(toTokenPtr, tmpObj)) {
if (TclGetIntFromObj(NULL, tmpObj, &idx2) == TCL_OK) {
if (idx2 >= 0) {
result = TCL_OK;
}
} else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx2) == TCL_OK) {
if (idx2 <= -2) {
result = TCL_OK;
}
}
}
TclDecrRefCount(tmpObj);
if (result != TCL_OK) {
goto nonConstantIndices;
}
/*
* Push the operand onto the stack and then the substring operation.
*/
CompileWord(envPtr, stringTokenPtr, interp, 1);
OP44( STR_RANGE_IMM, idx1, idx2);
return TCL_OK;
/*
* Push the operands onto the stack and then the substring operation.
*/
nonConstantIndices:
CompileWord(envPtr, stringTokenPtr, interp, 1);
CompileWord(envPtr, fromTokenPtr, interp, 2);
CompileWord(envPtr, toTokenPtr, interp, 3);
OP( STR_RANGE);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
@@ -694,14 +836,42 @@ 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) {
TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
OP1( CONCAT1, 255);
count -= 254;
}
if (count > 1) {
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
OP1( CONCAT1, count);
count = 1;
}
@@ -722,7 +892,7 @@ TclSubstCompile(
envPtr->line = bline;
catchRange = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
TclEmitInstInt4(INST_BEGIN_CATCH4, catchRange, envPtr);
OP4( BEGIN_CATCH4, catchRange);
ExceptionRangeStarts(envPtr, catchRange);
switch (tokenPtr->type) {
@@ -743,20 +913,20 @@ TclSubstCompile(
ExceptionRangeEnds(envPtr, catchRange);
/* Substitution produced TCL_OK */
TclEmitOpcode(INST_END_CATCH, envPtr);
OP( END_CATCH);
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
/* Exceptional return codes processed here */
ExceptionRangeTarget(envPtr, catchRange, catchOffset);
TclEmitOpcode(INST_PUSH_RETURN_OPTIONS, envPtr);
TclEmitOpcode(INST_PUSH_RESULT, envPtr);
TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
TclEmitOpcode(INST_END_CATCH, envPtr);
TclEmitOpcode(INST_RETURN_CODE_BRANCH, envPtr);
OP( PUSH_RETURN_OPTIONS);
OP( PUSH_RESULT);
OP( PUSH_RETURN_CODE);
OP( END_CATCH);
OP( RETURN_CODE_BRANCH);
/* ERROR -> reraise it */
TclEmitOpcode(INST_RETURN_STK, envPtr);
TclEmitOpcode(INST_NOP, envPtr);
OP( RETURN_STK);
OP( NOP);
/* RETURN */
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
@@ -775,14 +945,14 @@ TclSubstCompile(
Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
(int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
}
TclEmitOpcode(INST_POP, envPtr);
TclEmitOpcode(INST_POP, envPtr);
OP( POP);
OP( POP);
breakJump = CurrentOffset(envPtr) - breakOffset;
if (breakJump > 127) {
TclEmitInstInt4(INST_JUMP4, -breakJump, envPtr);
OP4(JUMP4, -breakJump);
} else {
TclEmitInstInt1(INST_JUMP1, -breakJump, envPtr);
OP1(JUMP1, -breakJump);
}
/* CONTINUE destination */
@@ -790,8 +960,8 @@ TclSubstCompile(
Tcl_Panic("TclCompileSubstCmd: bad continue jump distance %d",
(int) (CurrentOffset(envPtr) - continueFixup.codeOffset));
}
TclEmitOpcode(INST_POP, envPtr);
TclEmitOpcode(INST_POP, envPtr);
OP( POP);
OP( POP);
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &endFixup);
/* RETURN + other destination */
@@ -808,8 +978,8 @@ TclSubstCompile(
* Pull the result to top of stack, discard options dict.
*/
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
TclEmitOpcode(INST_POP, envPtr);
OP4( REVERSE, 2);
OP( POP);
/*
* We've emitted several POP instructions, and the automatic
@@ -828,7 +998,7 @@ TclSubstCompile(
(int) (CurrentOffset(envPtr) - okFixup.codeOffset));
}
if (count > 1) {
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
OP1(CONCAT1, count);
count = 1;
}
@@ -840,13 +1010,12 @@ TclSubstCompile(
bline = envPtr->line;
}
while (count > 255) {
TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
OP1( CONCAT1, 255);
count -= 254;
}
if (count > 1) {
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
OP1( CONCAT1, count);
}
Tcl_FreeParse(&parse);
@@ -854,6 +1023,7 @@ TclSubstCompile(
if (state != NULL) {
Tcl_RestoreInterpState(interp, state);
TclCompileSyntaxError(interp, envPtr);
TclAdjustStackDepth(-1, envPtr);
}
/* Final target of the multi-jump from all BREAKs */
@@ -1082,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;
@@ -1112,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) {
/*
@@ -1277,14 +1447,14 @@ IssueSwitchChainedTests(
switch (mode) {
case Switch_Exact:
TclEmitOpcode(INST_DUP, envPtr);
OP( DUP);
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
TclEmitOpcode(INST_STR_EQ, envPtr);
OP( STR_EQ);
break;
case Switch_Glob:
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
TclEmitInstInt4(INST_OVER, 1, envPtr);
TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
OP4( OVER, 1);
OP1( STR_MATCH, noCase);
break;
case Switch_Regexp:
simple = exact = 0;
@@ -1323,7 +1493,7 @@ IssueSwitchChainedTests(
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
}
TclEmitInstInt4(INST_OVER, 1, envPtr);
OP4( OVER, 1);
if (!simple) {
/*
* Pass correct RE compile flags. We use only Int1
@@ -1335,11 +1505,11 @@ IssueSwitchChainedTests(
int cflags = TCL_REG_ADVANCED
| (noCase ? TCL_REG_NOCASE : 0);
TclEmitInstInt1(INST_REGEXP, cflags, envPtr);
OP1(REGEXP, cflags);
} else if (exact && !noCase) {
TclEmitOpcode(INST_STR_EQ, envPtr);
OP( STR_EQ);
} else {
TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
OP1(STR_MATCH, noCase);
}
break;
default:
@@ -1404,7 +1574,7 @@ IssueSwitchChainedTests(
* pattern.
*/
TclEmitOpcode(INST_POP, envPtr);
OP( POP);
envPtr->currStackDepth = savedStackDepth + 1;
envPtr->line = bodyLines[i+1]; /* TIP #280 */
envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */
@@ -1426,7 +1596,7 @@ IssueSwitchChainedTests(
*/
if (!foundDefault) {
TclEmitOpcode(INST_POP, envPtr);
OP( POP);
PushLiteral(envPtr, "", 0);
}
@@ -1498,6 +1668,7 @@ IssueSwitchJumpTable(
int **bodyContLines) /* Array of continuation line info. */
{
JumptableInfo *jtPtr;
int savedStackDepth = envPtr->currStackDepth;
int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
int mustGenerate, foundDefault, jumpToDefault, i;
Tcl_DString buffer;
@@ -1537,9 +1708,9 @@ IssueSwitchJumpTable(
*/
jumpLocation = CurrentOffset(envPtr);
TclEmitInstInt4(INST_JUMP_TABLE, infoIndex, envPtr);
OP4( JUMP_TABLE, infoIndex);
jumpToDefault = CurrentOffset(envPtr);
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
OP4( JUMP4, 0);
for (i=0 ; i<numBodyTokens ; i+=2) {
/*
@@ -1610,6 +1781,7 @@ IssueSwitchJumpTable(
* Compile the body of the arm.
*/
envPtr->currStackDepth = savedStackDepth;
envPtr->line = bodyLines[i+1]; /* TIP #280 */
envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */
TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
@@ -1630,7 +1802,7 @@ IssueSwitchJumpTable(
* rewriting when we fixed this all up.
*/
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
OP4( JUMP4, 0);
}
}
@@ -1641,6 +1813,7 @@ IssueSwitchJumpTable(
*/
if (!foundDefault) {
envPtr->currStackDepth = savedStackDepth;
TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
envPtr->codeStart+jumpToDefault+1);
PushLiteral(envPtr, "", 0);
@@ -1661,6 +1834,7 @@ IssueSwitchJumpTable(
*/
TclStackFree(interp, finalFixups);
envPtr->currStackDepth = savedStackDepth + 1;
}
/*
@@ -1743,6 +1917,52 @@ PrintJumptableInfo(
}
}
/*
*----------------------------------------------------------------------
*
* TclCompileTailcallCmd --
*
* Procedure called to compile the "tailcall" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "tailcall" command at
* runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileTailcallCmd(
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. */
{
DefineLineInformation; /* TIP #280 */
Tcl_Token *tokenPtr = parsePtr->tokenPtr;
int i;
if (parsePtr->numWords < 2 || parsePtr->numWords > 256
|| envPtr->procPtr == NULL) {
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, envPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
@@ -1772,6 +1992,7 @@ TclCompileThrowCmd(
{
DefineLineInformation; /* TIP #280 */
int numWords = parsePtr->numWords;
int savedStackDepth = envPtr->currStackDepth;
Tcl_Token *codeToken, *msgToken;
Tcl_Obj *objPtr;
@@ -1802,6 +2023,7 @@ TclCompileThrowCmd(
CompileWord(envPtr, msgToken, interp, 2);
TclCompileSyntaxError(interp, envPtr);
Tcl_DecrRefCount(objPtr);
envPtr->currStackDepth = savedStackDepth + 1;
return TCL_OK;
}
if (len == 0) {
@@ -1822,6 +2044,7 @@ TclCompileThrowCmd(
PushLiteral(envPtr, string, len);
TclDecrRefCount(dictPtr);
OP44( RETURN_IMM, 1, 0);
envPtr->currStackDepth = savedStackDepth + 1;
} else {
/*
* When the code token is not known at compilation time, we need to do
@@ -1850,6 +2073,7 @@ TclCompileThrowCmd(
PUSH( "");
OP44( RETURN_IMM, 1, 0);
}
envPtr->currStackDepth = savedStackDepth + 1;
TclDecrRefCount(objPtr);
return TCL_OK;
}
@@ -2117,6 +2341,7 @@ IssueTryInstructions(
{
DefineLineInformation; /* TIP #280 */
int range, resultVar, optionsVar;
int savedStackDepth = envPtr->currStackDepth;
int i, j, len, forwardsNeedFixing = 0;
int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
char buf[TCL_INTEGER_SPACE];
@@ -2178,6 +2403,7 @@ IssueTryInstructions(
LOAD( optionsVar);
PUSH( "-errorcode");
OP4( DICT_GET, 1);
TclAdjustStackDepth(-1, envPtr);
OP44( LIST_RANGE_IMM, 0, len-1);
PUSH( TclGetString(matchClauses[i]));
OP( STR_EQ);
@@ -2218,6 +2444,7 @@ IssueTryInstructions(
forwardsToFix[j] = -1;
}
}
envPtr->currStackDepth = savedStackDepth;
BODY( handlerTokens[i], 5+i*4);
}
@@ -2249,6 +2476,7 @@ IssueTryInstructions(
}
TclStackFree(interp, forwardsToFix);
TclStackFree(interp, addrsToFix);
envPtr->currStackDepth = savedStackDepth + 1;
return TCL_OK;
}
@@ -2285,6 +2513,7 @@ IssueTryFinallyInstructions(
range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
OP4( BEGIN_CATCH4, range);
ExceptionRangeStarts(envPtr, range);
envPtr->currStackDepth = savedStackDepth;
BODY( bodyToken, 1);
ExceptionRangeEnds(envPtr, range);
PUSH( "0");
@@ -2329,6 +2558,7 @@ IssueTryFinallyInstructions(
LOAD( optionsVar);
PUSH( "-errorcode");
OP4( DICT_GET, 1);
TclAdjustStackDepth(-1, envPtr);
OP44( LIST_RANGE_IMM, 0, len-1);
PUSH( TclGetString(matchClauses[i]));
OP( STR_EQ);
@@ -2401,6 +2631,7 @@ IssueTryFinallyInstructions(
}
OP4( BEGIN_CATCH4, range);
}
envPtr->currStackDepth = savedStackDepth;
BODY( handlerTokens[i], 5+i*4);
ExceptionRangeEnds(envPtr, range);
OP( PUSH_RETURN_OPTIONS);
@@ -2452,7 +2683,6 @@ IssueTryFinallyInstructions(
*/
OP( POP);
envPtr->currStackDepth = savedStackDepth;
/*
* Process the finally clause (at last!) Note that we do not wrap this in
@@ -2462,11 +2692,13 @@ IssueTryFinallyInstructions(
* next command (or some inter-command manipulation).
*/
envPtr->currStackDepth = savedStackDepth;
BODY( finallyToken, 3 + 4*numHandlers);
OP( POP);
LOAD( optionsVar);
LOAD( resultVar);
OP( RETURN_STK);
envPtr->currStackDepth = savedStackDepth + 1;
return TCL_OK;
}
@@ -2507,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);
@@ -2547,20 +2779,18 @@ TclCompileUnsetCmd(
*/
if (!simpleVarName) {
TclEmitInstInt1( INST_UNSET_STK, flags, envPtr);
OP1( UNSET_STK, flags);
} else if (isScalar) {
if (localIndex < 0) {
TclEmitInstInt1(INST_UNSET_STK, flags, envPtr);
OP1( UNSET_STK, flags);
} else {
TclEmitInstInt1(INST_UNSET_SCALAR, flags, envPtr);
TclEmitInt4( localIndex, envPtr);
OP14( UNSET_SCALAR, flags, localIndex);
}
} else {
if (localIndex < 0) {
TclEmitInstInt1(INST_UNSET_ARRAY_STK, flags, envPtr);
OP1( UNSET_ARRAY_STK, flags);
} else {
TclEmitInstInt1(INST_UNSET_ARRAY, flags, envPtr);
TclEmitInt4( localIndex, envPtr);
OP14( UNSET_ARRAY, flags, localIndex);
}
}
@@ -2697,7 +2927,7 @@ TclCompileWhileCmd(
CompileBody(envPtr, bodyTokenPtr, interp);
ExceptionRangeEnds(envPtr, range);
envPtr->currStackDepth = savedStackDepth + 1;
TclEmitOpcode(INST_POP, envPtr);
OP( POP);
/*
* Compile the test expression then emit the conditional jump that
@@ -2749,6 +2979,49 @@ TclCompileWhileCmd(
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclCompileYieldCmd --
*
* Procedure called to compile the "yield" command.
*
* Results:
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
* evaluation to runtime.
*
* Side effects:
* Instructions are added to envPtr to execute the "yield" command at
* runtime.
*
*----------------------------------------------------------------------
*/
int
TclCompileYieldCmd(
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. */
{
if (parsePtr->numWords < 1 || parsePtr->numWords > 2) {
return TCL_ERROR;
}
if (parsePtr->numWords == 1) {
PushLiteral(envPtr, "", 0);
} else {
DefineLineInformation; /* TIP #280 */
Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
CompileWord(envPtr, valueTokenPtr, interp, 1);
}
OP( YIELD);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
@@ -3074,7 +3347,7 @@ CompileAssociativeBinaryOpCmd(
* calcuations, including roundoff errors.
*/
TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
OP4( REVERSE, words-1);
}
while (--words > 1) {
TclEmitOpcode(instruction, envPtr);
@@ -3165,31 +3438,19 @@ CompileComparisonOpCmd(
CompileWord(envPtr, tokenPtr, interp, 1);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 2);
if (tmpIndex <= 255) {
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
} else {
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
}
STORE(tmpIndex);
TclEmitOpcode(instruction, envPtr);
for (words=3 ; words<parsePtr->numWords ;) {
if (tmpIndex <= 255) {
TclEmitInstInt1(INST_LOAD_SCALAR1, tmpIndex, envPtr);
} else {
TclEmitInstInt4(INST_LOAD_SCALAR4, tmpIndex, envPtr);
}
LOAD(tmpIndex);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, words);
if (++words < parsePtr->numWords) {
if (tmpIndex <= 255) {
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
} else {
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
}
STORE(tmpIndex);
}
TclEmitOpcode(instruction, envPtr);
}
for (; words>3 ; words--) {
TclEmitOpcode(INST_BITAND, envPtr);
OP( BITAND);
}
/*
@@ -3197,13 +3458,7 @@ CompileComparisonOpCmd(
* might be expensive elsewhere.
*/
PushLiteral(envPtr, "", 0);
if (tmpIndex <= 255) {
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
} else {
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
}
TclEmitOpcode(INST_POP, envPtr);
OP14( UNSET_SCALAR, 0, tmpIndex);
}
return TCL_OK;
}
+127 -7
View File
@@ -37,7 +37,7 @@ TCL_DECLARE_MUTEX(tableMutex)
int tclTraceCompile = 0;
static int traceInitialized = 0;
#endif
/*
* A table describing the Tcl bytecode instructions. Entries in this table
* must correspond to the instruction opcode definitions in tclCompile.h. The
@@ -372,13 +372,13 @@ InstructionDesc const tclInstructionTable[] = {
* Stack: ... value => ...
* Note that the jump table contains offsets relative to the PC when
* it points to this instruction; the code is relocatable. */
{"upvar", 5, 0, 1, {OPERAND_LVT4}},
{"upvar", 5, -1, 1, {OPERAND_LVT4}},
/* finds level and otherName in stack, links to local variable at
* index op1. Leaves the level on stack. */
{"nsupvar", 5, 0, 1, {OPERAND_LVT4}},
{"nsupvar", 5, -1, 1, {OPERAND_LVT4}},
/* finds namespace and otherName in stack, links to local variable at
* index op1. Leaves the namespace on stack. */
{"variable", 5, 0, 1, {OPERAND_LVT4}},
{"variable", 5, -1, 1, {OPERAND_LVT4}},
/* finds namespace and otherName in stack, links to local variable at
* index op1. Leaves the namespace on stack. */
{"syntax", 9, -1, 2, {OPERAND_INT4, OPERAND_UINT4}},
@@ -434,6 +434,105 @@ InstructionDesc const tclInstructionTable[] = {
/* Map variable contents back into a dictionary in the local variable
* indicated by the LVT index. Part of [dict with].
* Stack: ... path keyList => ... */
{"dictExists", 5, INT_MIN, 1, {OPERAND_UINT4}},
/* The top op4 words (min 1) are a key path into the dictionary just
* below the keys on the stack, and all those values are replaced by a
* boolean indicating whether it is possible to read out a value from
* that key-path (like [dict exists]).
* Stack: ... dict key1 ... keyN => ... boolean */
{"verifyDict", 1, -1, 0, {OPERAND_NONE}},
/* Verifies that the word on the top of the stack is a dictionary,
* popping it if it is and throwing an error if it is not.
* Stack: ... value => ... */
{"strmap", 1, -2, 0, {OPERAND_NONE}},
/* Simplified version of [string map] that only applies one change
* string, and only case-sensitively.
* Stack: ... from to string => ... changedString */
{"strfind", 1, -1, 0, {OPERAND_NONE}},
/* Find the first index of a needle string in a haystack string,
* producing the index (integer) or -1 if nothing found.
* Stack: ... needle haystack => ... index */
{"strrfind", 1, -1, 0, {OPERAND_NONE}},
/* Find the last index of a needle string in a haystack string,
* producing the index (integer) or -1 if nothing found.
* Stack: ... needle haystack => ... index */
{"strrangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}},
/* String Range: push (string range stktop op4 op4) */
{"strrange", 1, -2, 0, {OPERAND_NONE}},
/* String Range with non-constant arguments.
* Stack: ... string idxA idxB => ... substring */
{"yield", 1, 0, 0, {OPERAND_NONE}},
/* Makes the current coroutine yield the value at the top of the
* stack, and places the response back on top of the stack when it
* resumes.
* Stack: ... valueToYield => ... resumeValue */
{"coroName", 1, +1, 0, {OPERAND_NONE}},
/* Push the name of the interpreter's current coroutine as an object
* on the stack. */
{"tailcall", 2, INT_MIN, 1, {OPERAND_UINT1}},
/* Do a tailcall with the opnd items on the stack as the thing to
* tailcall to; opnd must be greater than 0 for the semantics to work
* right. */
{"currentNamespace", 1, +1, 0, {OPERAND_NONE}},
/* Push the name of the interpreter's current namespace as an object
* on the stack. */
{"infoLevelNumber", 1, +1, 0, {OPERAND_NONE}},
/* Push the stack depth (i.e., [info level]) of the interpreter as an
* object on the stack. */
{"infoLevelArgs", 1, 0, 0, {OPERAND_NONE}},
/* Push the argument words to a stack depth (i.e., [info level <n>])
* of the interpreter as an object on the stack.
* Stack: ... depth => ... argList */
{"resolveCmd", 1, 0, 0, {OPERAND_NONE}},
/* Resolves the command named on the top of the stack to its fully
* qualified version, or produces the empty string if no such command
* exists. Never generates errors.
* Stack: ... cmdName => ... fullCmdName */
{"tclooSelf", 1, +1, 0, {OPERAND_NONE}},
/* Push the identity of the current TclOO object (i.e., the name of
* its current public access command) on the stack. */
{"tclooClass", 1, 0, 0, {OPERAND_NONE}},
/* Push the class of the TclOO object named at the top of the stack
* onto the stack.
* Stack: ... object => ... class */
{"tclooNamespace", 1, 0, 0, {OPERAND_NONE}},
/* Push the namespace of the TclOO object named at the top of the
* stack onto the stack.
* Stack: ... object => ... namespace */
{"tclooIsObject", 1, 0, 0, {OPERAND_NONE}},
/* Push whether the value named at the top of the stack is a TclOO
* object (i.e., a boolean). Can corrupt the interpreter result
* despite not throwing, so not safe for use in a post-exception
* context.
* Stack: ... value => ... boolean */
{"arrayExistsStk", 1, 0, 0, {OPERAND_NONE}},
/* Looks up the element on the top of the stack and tests whether it
* is an array. Pushes a boolean describing whether this is the
* case. Also runs the whole-array trace on the named variable, so can
* throw anything.
* Stack: ... varName => ... boolean */
{"arrayExistsImm", 5, +1, 1, {OPERAND_UINT4}},
/* Looks up the variable indexed by opnd and tests whether it is an
* array. Pushes a boolean describing whether this is the case. Also
* runs the whole-array trace on the named variable, so can throw
* anything.
* Stack: ... => ... boolean */
{"arrayMakeStk", 1, -1, 0, {OPERAND_NONE}},
/* Forces the element on the top of the stack to be the name of an
* array.
* Stack: ... varName => ... */
{"arrayMakeImm", 5, 0, 1, {OPERAND_UINT4}},
/* 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}}
};
@@ -1673,10 +1772,13 @@ TclCompileScript(
&& !(cmdPtr->nsPtr->flags&NS_SUPPRESS_COMPILATION)
&& !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
&& !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
int savedNumCmds = envPtr->numCommands;
int code, savedNumCmds = envPtr->numCommands;
unsigned savedCodeNext =
envPtr->codeNext - envPtr->codeStart;
int update = 0, code;
int update = 0;
#ifdef TCL_COMPILE_DEBUG
int startStackDepth = envPtr->currStackDepth;
#endif
/*
* Mark the start of the command; the proper bytecode
@@ -1720,6 +1822,25 @@ TclCompileScript(
envPtr);
if (code == TCL_OK) {
/*
* Confirm that the command compiler generated a
* single value on the stack as its result. This
* is only done in debugging mode, as it *should*
* be correct and normal users have no reasonable
* way to fix it anyway.
*/
#ifdef TCL_COMPILE_DEBUG
int diff = envPtr->currStackDepth-startStackDepth;
if (diff != 1 && (diff != 0 ||
*(envPtr->codeNext-1) != INST_DONE)) {
Tcl_Panic("bad stack adjustment when compiling"
" %.*s (was %d instead of 1)",
parsePtr->tokenPtr->size,
parsePtr->tokenPtr->start, diff);
}
#endif
if (update) {
/*
* Fix the bytecode length.
@@ -4620,6 +4741,5 @@ RecordByteCodeStats(
* c-basic-offset: 4
* fill-column: 78
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/
+34 -2
View File
@@ -676,13 +676,45 @@ typedef struct ByteCode {
#define INST_UNSET_ARRAY_STK 136
#define INST_UNSET_STK 137
/* For [dict with] compilation */
/* For [dict with], [dict exists], [dict create] and [dict merge] */
#define INST_DICT_EXPAND 138
#define INST_DICT_RECOMBINE_STK 139
#define INST_DICT_RECOMBINE_IMM 140
#define INST_DICT_EXISTS 141
#define INST_DICT_VERIFY 142
/* For [string map] and [regsub] compilation */
#define INST_STR_MAP 143
#define INST_STR_FIND 144
#define INST_STR_FIND_LAST 145
#define INST_STR_RANGE_IMM 146
#define INST_STR_RANGE 147
/* For operations to do with coroutines and other NRE-manipulators */
#define INST_YIELD 148
#define INST_COROUTINE_NAME 149
#define INST_TAILCALL 150
/* For compilation of basic information operations */
#define INST_NS_CURRENT 151
#define INST_INFO_LEVEL_NUM 152
#define INST_INFO_LEVEL_ARGS 153
#define INST_RESOLVE_COMMAND 154
#define INST_TCLOO_SELF 155
#define INST_TCLOO_CLASS 156
#define INST_TCLOO_NS 157
#define INST_TCLOO_IS_OBJECT 158
/* For compilation of [array] subcommands */
#define INST_ARRAY_EXISTS_STK 159
#define INST_ARRAY_EXISTS_IMM 160
#define INST_ARRAY_MAKE_STK 161
#define INST_ARRAY_MAKE_IMM 162
#define INST_INVOKE_REPLACE 163
/* The last opcode */
#define LAST_INST_OPCODE 140
#define LAST_INST_OPCODE 163
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
+9 -2
View File
@@ -1807,8 +1807,12 @@ EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp,
/* 629 */
EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp,
Tcl_LoadHandle handlePtr);
/* 630 */
EXTERN void Tcl_ZlibStreamSetCompressionDictionary(
Tcl_ZlibStream zhandle,
Tcl_Obj *compressionDictionaryObj);
typedef struct TclStubHooks {
typedef struct {
const struct TclPlatStubs *tclPlatStubs;
const struct TclIntStubs *tclIntStubs;
const struct TclIntPlatStubs *tclIntPlatStubs;
@@ -1816,7 +1820,7 @@ typedef struct TclStubHooks {
typedef struct TclStubs {
int magic;
const struct TclStubHooks *hooks;
const TclStubHooks *hooks;
int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */
CONST84_RETURN char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
@@ -2472,6 +2476,7 @@ typedef struct TclStubs {
int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */
void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
} TclStubs;
#ifdef __cplusplus
@@ -3764,6 +3769,8 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tcl_FindSymbol) /* 628 */
#define Tcl_FSUnloadFile \
(tclStubsPtr->tcl_FSUnloadFile) /* 629 */
#define Tcl_ZlibStreamSetCompressionDictionary \
(tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */
#endif /* defined(USE_TCL_STUBS) */
+11 -10
View File
@@ -89,24 +89,24 @@ static int DictMapLoopCallback(ClientData data[],
static const EnsembleImplMap implementationMap[] = {
{"append", DictAppendCmd, TclCompileDictAppendCmd, NULL, NULL, 0 },
{"create", DictCreateCmd, NULL, NULL, NULL, 0 },
{"exists", DictExistsCmd, NULL, NULL, NULL, 0 },
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
{"create", DictCreateCmd, TclCompileDictCreateCmd, NULL, NULL, 0 },
{"exists", DictExistsCmd, TclCompileDictExistsCmd, 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, NULL, NULL, NULL, 0 },
{"remove", DictRemoveCmd, NULL, NULL, NULL, 0 },
{"merge", DictMergeCmd, TclCompileDictMergeCmd, 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 },
{"unset", DictUnsetCmd, 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}
};
@@ -975,6 +975,7 @@ Tcl_DictObjGet(
if (dictPtr->typePtr != &tclDictType) {
int result = SetDictFromAny(interp, dictPtr);
if (result != TCL_OK) {
*valuePtrPtr = NULL;
return result;
}
}
+581 -62
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;
}
@@ -1892,8 +1914,8 @@ NsEnsembleImplementationCmdNR(
* Hand off to the target command.
*/
iPtr->evalFlags |= TCL_EVAL_REDIRECT;
return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN);
return TclNREvalObjEx(interp, copyPtr,
(TCL_EVAL_INVOKE|TCL_EVAL_REDIRECT), NULL,INT_MIN);
}
unknownOrAmbiguousSubcommand:
@@ -2100,8 +2122,7 @@ EnsembleUnknownCallback(
*/
Tcl_Preserve(ensemblePtr);
((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT;
result = Tcl_EvalObjv(interp, paramc, paramv, 0);
result = Tcl_EvalObjv(interp, paramc, paramv, TCL_EVAL_REDIRECT);
if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) {
if (!Tcl_InterpDeleted(interp)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
@@ -2731,25 +2752,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 +2797,7 @@ TclCompileEnsemble(
* to proceed.
*/
return TCL_ERROR;
goto failed;
}
/*
@@ -2782,7 +2811,7 @@ TclCompileEnsemble(
* Figuring out how to compile this has become too much. Bail out.
*/
return TCL_ERROR;
goto failed;
}
/*
@@ -2805,7 +2834,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 +2845,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 +2863,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 +2887,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 +2903,7 @@ TclCompileEnsemble(
*/
if (!(flags & TCL_ENSEMBLE_PREFIX)) {
return TCL_ERROR;
goto failed;
}
/*
@@ -2881,6 +2913,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 +2924,7 @@ TclCompileEnsemble(
break;
}
replacement = subcmdObj;
targetCmdObj = tmpObj;
}
Tcl_DictObjNext(&s, &subcmdObj, &tmpObj, &done);
@@ -2903,7 +2937,8 @@ TclCompileEnsemble(
*/
if (matched != 1) {
return TCL_ERROR;
invokeAnyway = 1;
goto failed;
}
}
@@ -2917,75 +2952,154 @@ 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;
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);
}
/*
@@ -3001,6 +3115,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(
envPtr->literalArrayPtr[literal].objPtr,
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, envPtr->literalArrayPtr[cmdLit].objPtr, 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, envPtr->literalArrayPtr[literal].objPtr, 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:
+628 -21
View File
@@ -17,6 +17,7 @@
#include "tclInt.h"
#include "tclCompile.h"
#include "tclOOInt.h"
#include "tommath.h"
#include <math.h>
@@ -250,13 +251,24 @@ 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() \
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \
/*checkStack*/ auxObjList == NULL)
#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) { \
@@ -285,7 +297,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); \
@@ -684,7 +697,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);
@@ -858,6 +871,7 @@ TclCreateExecEnv(
TclNewBooleanObj(eePtr->constants[1], 1);
Tcl_IncrRefCount(eePtr->constants[1]);
eePtr->interp = interp;
eePtr->NRStack = NULL;
eePtr->callbackPtr = NULL;
eePtr->corPtr = NULL;
eePtr->rewind = 0;
@@ -876,6 +890,11 @@ TclCreateExecEnv(
}
Tcl_MutexUnlock(&execMutex);
/* Initialize the NRE stack */
((Interp *) interp)->execEnvPtr = eePtr;
eePtr->callbackPtr = TclNewCallback(interp);
eePtr->callbackPtr--;
return eePtr;
}
@@ -919,7 +938,7 @@ TclDeleteExecEnv(
{
ExecStack *esPtr = eePtr->execStackPtr, *tmpPtr;
cachedInExit = TclInExit();
cachedInExit = TclInExit();
/*
* Delete all stacks in this exec env.
@@ -1047,6 +1066,7 @@ GrowEvaluationStack(
return MEMSTART(markerPtr);
}
} else {
#ifndef PURIFY
Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
int offset = OFFSET(tmpMarkerPtr);
@@ -1063,6 +1083,7 @@ GrowEvaluationStack(
*esPtr->markerPtr = (Tcl_Obj *) markerPtr;
return memStart;
}
#endif
}
/*
@@ -1074,8 +1095,9 @@ GrowEvaluationStack(
if (move) {
moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1;
}
needed = growth + moveWords + WALLOCALIGN;
needed = growth + moveWords + WALLOCALIGN - 1;
/*
* Check if there is enough room in the next stack (if there is one, it
* should be both empty and the last one!)
@@ -1105,10 +1127,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;
@@ -1211,7 +1238,7 @@ TclStackFree(
Tcl_Obj **markerPtr, *marker;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
Tcl_Free((char *) freePtr);
ckfree((char *) freePtr);
return;
}
@@ -1257,6 +1284,10 @@ TclStackFree(
}
if (esPtr->prevPtr) {
eePtr->execStackPtr = esPtr->prevPtr;
#ifdef PURIFY
eePtr->execStackPtr->nextPtr = NULL;
DeleteExecStack(esPtr);
#endif
} else {
eePtr->execStackPtr = esPtr;
}
@@ -1271,7 +1302,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);
@@ -1290,7 +1321,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;
@@ -2230,8 +2261,7 @@ TEBCresume(
* Skip the stack depth check if an expansion is in progress.
*/
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, 0,
/*checkStack*/ auxObjList == NULL);
CHECK_STACK();
if (traceInstructions) {
fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH);
TclPrintInstruction(codePtr, pc);
@@ -2331,6 +2361,91 @@ TEBCresume(
cleanup = 1;
goto processExceptionReturn;
case INST_YIELD: {
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
TRACE(("%.30s => ", O2S(OBJ_AT_TOS)));
if (!corPtr) {
TRACE_APPEND(("ERROR: yield outside coroutine\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"yield can only be called in a coroutine", -1));
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
NULL);
goto gotError;
}
#ifdef TCL_COMPILE_DEBUG
TRACE_WITH_OBJ(("yield, result="), iPtr->objResultPtr);
if (traceInstructions) {
fprintf(stdout, "\n");
}
#endif
/* TIP #280: Record the last piece of info needed by
* 'TclGetSrcInfoForPc', and push the frame.
*/
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);
}
pc++;
cleanup = 1;
TEBC_YIELD();
Tcl_SetObjResult(interp, OBJ_AT_TOS);
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
INT2PTR(0), NULL, NULL);
return TCL_OK;
}
case INST_TAILCALL: {
Tcl_Obj *listPtr, *nsObjPtr;
opnd = TclGetUInt1AtPtr(pc+1);
if (!(iPtr->varFramePtr->isProcCallFrame & 1)) {
TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"tailcall can only be called from a proc or lambda", -1));
Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
goto gotError;
}
#ifdef TCL_COMPILE_DEBUG
{
register int i;
TRACE(("%d [", opnd));
for (i=opnd-1 ; i>=0 ; i--) {
TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_DEPTH(i))));
if (i > 0) {
TRACE_APPEND((" "));
}
}
TRACE_APPEND(("] => RETURN..."));
}
#endif
/*
* Push the evaluation of the called command into the NR callback
* stack.
*/
listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1);
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
iPtr->varFramePtr->tailcallPtr = listPtr;
result = TCL_RETURN;
cleanup = opnd;
goto processExceptionReturn;
}
case INST_DONE:
if (tosPtr > initTosPtr) {
/*
@@ -2876,6 +2991,69 @@ 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);
return TclNREvalObjEx(interp, objPtr, (TCL_EVAL_INVOKE|TCL_EVAL_REDIRECT),
NULL, INT_MIN);
/*
* -----------------------------------------------------------------
* Start of INST_LOAD instructions.
@@ -3785,6 +3963,104 @@ TEBCresume(
/*
* End of INST_UNSET instructions.
* -----------------------------------------------------------------
* Start of INST_ARRAY instructions.
*/
case INST_ARRAY_EXISTS_IMM:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
cleanup = 0;
part1Ptr = NULL;
arrayPtr = NULL;
TRACE(("%u => ", opnd));
varPtr = LOCAL(opnd);
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
}
goto doArrayExists;
case INST_ARRAY_EXISTS_STK:
opnd = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/0, /*createPart2*/0, &arrayPtr);
doArrayExists:
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
DECACHE_STACK_INFO();
result = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
NULL, (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|
TCL_GLOBAL_ONLY|TCL_TRACE_ARRAY), 1, opnd);
CACHE_STACK_INFO();
if (result == TCL_ERROR) {
TRACE_APPEND(("ERROR: %.30s\n",
O2S(Tcl_GetObjResult(interp))));
goto gotError;
}
}
if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
objResultPtr = TCONST(1);
} else {
objResultPtr = TCONST(0);
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_V(pcAdjustment, cleanup, 1);
case INST_ARRAY_MAKE_IMM:
opnd = TclGetUInt4AtPtr(pc+1);
pcAdjustment = 5;
cleanup = 0;
part1Ptr = NULL;
arrayPtr = NULL;
TRACE(("%u => ", opnd));
varPtr = LOCAL(opnd);
while (TclIsVarLink(varPtr)) {
varPtr = varPtr->value.linkPtr;
}
goto doArrayMake;
case INST_ARRAY_MAKE_STK:
opnd = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
"set", /*createPart1*/1, /*createPart2*/0, &arrayPtr);
if (varPtr == NULL) {
TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
goto gotError;
}
doArrayMake:
if (varPtr && !TclIsVarArray(varPtr)) {
if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
/*
* Either an array element, or a scalar: lose!
*/
TclObjVarErrMsg(interp, part1Ptr, NULL, "array set",
"variable isn't array", opnd);
Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
TRACE_APPEND(("ERROR: bad array ref: %.30s\n",
O2S(Tcl_GetObjResult(interp))));
goto gotError;
}
TclSetVarArray(varPtr);
varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
TclInitVarHashTable(varPtr->value.tablePtr,
TclGetVarNsPtr(varPtr));
#ifdef TCL_COMPILE_DEBUG
TRACE_APPEND(("done\n"));
} else {
TRACE_APPEND(("nothing to do\n"));
#endif
}
NEXT_INST_V(pcAdjustment, cleanup, 0);
/*
* End of INST_ARRAY instructions.
* -----------------------------------------------------------------
* Start of variable linking instructions.
*/
@@ -4043,6 +4319,136 @@ TEBCresume(
NEXT_INST_F(1, 2, 1);
}
/*
* -----------------------------------------------------------------
* Start of general introspector instructions.
*/
case INST_NS_CURRENT: {
Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
TclNewLiteralStringObj(objResultPtr, "::");
} else {
TclNewStringObj(objResultPtr, currNsPtr->fullName,
strlen(currNsPtr->fullName));
}
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
}
case INST_COROUTINE_NAME: {
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
TclNewObj(objResultPtr);
if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) {
Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr,
objResultPtr);
}
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
}
case INST_INFO_LEVEL_NUM:
TclNewIntObj(objResultPtr, iPtr->varFramePtr->level);
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
case INST_INFO_LEVEL_ARGS: {
int level;
register CallFrame *framePtr = iPtr->varFramePtr;
register CallFrame *rootFramePtr = iPtr->rootFramePtr;
valuePtr = OBJ_AT_TOS;
if (TclGetIntFromObj(interp, valuePtr, &level) != TCL_OK) {
TRACE_WITH_OBJ(("%.30s => ERROR: ", O2S(valuePtr)),
Tcl_GetObjResult(interp));
goto gotError;
}
TRACE(("%d => ", level));
if (level <= 0) {
level += framePtr->level;
}
for (; (framePtr->level!=level) && (framePtr!=rootFramePtr) ;
framePtr = framePtr->callerVarPtr) {
/* Empty loop body */
}
if (framePtr == rootFramePtr) {
Tcl_AppendResult(interp, "bad level \"", TclGetString(valuePtr),
"\"", NULL);
TRACE_APPEND(("ERROR: bad level\n"));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
TclGetString(valuePtr), NULL);
goto gotError;
}
objResultPtr = Tcl_NewListObj(framePtr->objc, framePtr->objv);
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
}
case INST_RESOLVE_COMMAND: {
Tcl_Command cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
TclNewObj(objResultPtr);
if (cmd != NULL) {
Tcl_GetCommandFullName(interp, cmd, objResultPtr);
}
TRACE_WITH_OBJ(("\"%.20s\" => ", O2S(OBJ_AT_TOS)), objResultPtr);
NEXT_INST_F(1, 1, 1);
}
case INST_TCLOO_SELF: {
CallFrame *framePtr = iPtr->varFramePtr;
CallContext *contextPtr;
if (framePtr == NULL ||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
TRACE(("=> ERROR: no TclOO call context\n"));
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"self may only be called from inside a method",
-1));
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
goto gotError;
}
contextPtr = framePtr->clientData;
/*
* Call out to get the name; it's expensive to compute but cached.
*/
objResultPtr = TclOOObjectName(interp, contextPtr->oPtr);
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
}
{
Object *oPtr;
case INST_TCLOO_IS_OBJECT:
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
objResultPtr = TCONST(oPtr != NULL ? 1 : 0);
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
NEXT_INST_F(1, 1, 1);
case INST_TCLOO_CLASS:
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
if (oPtr == NULL) {
TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
goto gotError;
}
objResultPtr = TclOOObjectName(interp, oPtr->selfCls->thisPtr);
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
NEXT_INST_F(1, 1, 1);
case INST_TCLOO_NS:
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
if (oPtr == NULL) {
TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
goto gotError;
}
/*
* TclOO objects *never* have the global namespace as their NS.
*/
TclNewStringObj(objResultPtr, oPtr->namespacePtr->fullName,
strlen(oPtr->namespacePtr->fullName));
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
NEXT_INST_F(1, 1, 1);
}
/*
* -----------------------------------------------------------------
* Start of INST_LIST and related instructions.
@@ -4592,6 +4998,176 @@ TEBCresume(
O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
case INST_STR_RANGE:
TRACE(("\"%.20s\" %s %s =>",
O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1;
if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
&fromIdx) != TCL_OK
|| TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
&toIdx) != TCL_OK) {
goto gotError;
}
if (fromIdx < 0) {
fromIdx = 0;
}
if (toIdx >= length) {
toIdx = length;
}
if (toIdx >= fromIdx) {
objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx);
} else {
TclNewObj(objResultPtr);
}
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
NEXT_INST_V(1, 3, 1);
case INST_STR_RANGE_IMM:
valuePtr = OBJ_AT_TOS;
fromIdx = TclGetInt4AtPtr(pc+1);
toIdx = TclGetInt4AtPtr(pc+5);
length = Tcl_GetCharLength(valuePtr);
TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx));
/*
* Adjust indices for end-based indexing.
*/
if (fromIdx < -1) {
fromIdx += 1 + length;
if (fromIdx < 0) {
fromIdx = 0;
}
} else if (fromIdx >= length) {
fromIdx = length;
}
if (toIdx < -1) {
toIdx += 1 + length;
} else if (toIdx >= length) {
toIdx = length - 1;
}
/*
* Check if we can do a sane substring.
*/
if (fromIdx <= toIdx) {
objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx);
} else {
TclNewObj(objResultPtr);
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_F(9, 1, 1);
{
Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p;
int length3;
Tcl_Obj *value3Ptr;
case INST_STR_MAP:
valuePtr = OBJ_AT_TOS; /* "Main" string. */
value3Ptr = OBJ_UNDER_TOS; /* "Target" string. */
value2Ptr = OBJ_AT_DEPTH(2); /* "Source" string. */
if (value3Ptr == value2Ptr) {
objResultPtr = valuePtr;
NEXT_INST_V(1, 3, 1);
} else if (valuePtr == value2Ptr) {
objResultPtr = value3Ptr;
NEXT_INST_V(1, 3, 1);
}
ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
if (length == 0) {
objResultPtr = valuePtr;
NEXT_INST_V(1, 3, 1);
}
ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2);
if (length2 > length || length2 == 0) {
objResultPtr = valuePtr;
NEXT_INST_V(1, 3, 1);
} else if (length2 == length) {
if (memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length)) {
objResultPtr = valuePtr;
} else {
objResultPtr = value3Ptr;
}
NEXT_INST_V(1, 3, 1);
}
ustring3 = Tcl_GetUnicodeFromObj(value3Ptr, &length3);
objResultPtr = Tcl_NewUnicodeObj(ustring1, 0);
p = ustring1;
end = ustring1 + length;
for (; ustring1 < end; ustring1++) {
if ((*ustring1 == *ustring2) && (length2==1 ||
memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2)
== 0)) {
if (p != ustring1) {
Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1-p);
p = ustring1 + length2;
} else {
p += length2;
}
ustring1 = p - 1;
Tcl_AppendUnicodeToObj(objResultPtr, ustring3, length3);
}
}
if (p != ustring1) {
/*
* Put the rest of the unmapped chars onto result.
*/
Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1 - p);
}
TRACE_WITH_OBJ(("%.20s %.20s %.20s => ",
O2S(value2Ptr), O2S(value3Ptr), O2S(valuePtr)), objResultPtr);
NEXT_INST_V(1, 3, 1);
case INST_STR_FIND:
ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
match = -1;
if (length2 > 0 && length2 <= length) {
end = ustring1 + length - length2 + 1;
for (p=ustring1 ; p<end ; p++) {
if ((*p == *ustring2) &&
memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
match = p - ustring1;
break;
}
}
}
TRACE(("%.20s %.20s => %d\n",
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
TclNewIntObj(objResultPtr, match);
NEXT_INST_F(1, 2, 1);
case INST_STR_FIND_LAST:
ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
match = -1;
if (length2 > 0 && length2 <= length) {
for (p=ustring1+length-length2 ; p>=ustring1 ; p--) {
if ((*p == *ustring2) &&
memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
match = p - ustring1;
break;
}
}
}
TRACE(("%.20s %.20s => %d\n",
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
TclNewIntObj(objResultPtr, match);
NEXT_INST_F(1, 2, 1);
}
case INST_STR_MATCH:
nocase = TclGetInt1AtPtr(pc+1);
valuePtr = OBJ_AT_TOS; /* String */
@@ -5648,23 +6224,48 @@ TEBCresume(
Tcl_DictSearch *searchPtr;
DictUpdateInfo *duiPtr;
case INST_DICT_VERIFY:
dictPtr = OBJ_AT_TOS;
TRACE(("=> "));
if (Tcl_DictObjSize(interp, dictPtr, &done) != TCL_OK) {
TRACE_APPEND(("ERROR verifying dictionary nature of \"%s\": %s\n",
O2S(OBJ_AT_DEPTH(opnd)), O2S(Tcl_GetObjResult(interp))));
goto gotError;
}
TRACE_APPEND(("OK\n"));
NEXT_INST_F(1, 1, 0);
case INST_DICT_GET:
case INST_DICT_EXISTS: {
register Tcl_Interp *interp2 = interp;
opnd = TclGetUInt4AtPtr(pc+1);
TRACE(("%u => ", opnd));
dictPtr = OBJ_AT_DEPTH(opnd);
if (*pc == INST_DICT_EXISTS) {
interp2 = NULL;
}
if (opnd > 1) {
dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1,
dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1,
&OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
if (dictPtr == NULL) {
if (*pc == INST_DICT_EXISTS) {
goto dictNotExists;
}
TRACE_WITH_OBJ((
"%u => ERROR tracing dictionary path into \"%s\": ",
opnd, O2S(OBJ_AT_DEPTH(opnd))),
"ERROR tracing dictionary path into \"%s\": ",
O2S(OBJ_AT_DEPTH(opnd))),
Tcl_GetObjResult(interp));
goto gotError;
}
}
if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS,
if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS,
&objResultPtr) == TCL_OK) {
if (*pc == INST_DICT_EXISTS) {
objResultPtr = TCONST(objResultPtr ? 1 : 0);
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_V(5, opnd+1, 1);
}
if (objResultPtr) {
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_V(5, opnd+1, 1);
@@ -5678,11 +6279,18 @@ TEBCresume(
CACHE_STACK_INFO();
TRACE_WITH_OBJ(("%u => ERROR ", opnd), Tcl_GetObjResult(interp));
} else {
if (*pc == INST_DICT_EXISTS) {
dictNotExists:
objResultPtr = TCONST(0);
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_V(5, opnd+1, 1);
}
TRACE_WITH_OBJ((
"%u => ERROR reading leaf dictionary key \"%s\": ",
opnd, O2S(dictPtr)), Tcl_GetObjResult(interp));
}
goto gotError;
}
case INST_DICT_SET:
case INST_DICT_UNSET:
@@ -7959,11 +8567,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;
@@ -7981,13 +8588,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;
+1 -1
View File
@@ -2472,7 +2472,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);
}
+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));
}
}
+7 -51
View File
@@ -182,8 +182,8 @@ const Tcl_Filesystem tclNativeFilesystem = {
TclpObjRenameFile,
TclpObjCopyDirectory,
TclpObjLstat,
TclpDlopen,
/* Needs a cast since we're using version_2. */
/* Needs casts since we're using version_2. */
(Tcl_FSLoadFileProc *) TclpDlopen,
(Tcl_FSGetCwdProc *) TclpGetNativeCwd,
TclpObjChdir
};
@@ -3120,7 +3120,7 @@ Tcl_LoadFile(
* code. */
const char *const symbols[],/* Names of functions to look up in the file's
* symbol table. */
int flags, /* Flags (unused) */
int flags, /* Flags */
void *procVPtrs, /* Where to return the addresses corresponding
* to symbols[]. */
Tcl_LoadHandle *handlePtr) /* Filled with token for shared library
@@ -3145,8 +3145,8 @@ Tcl_LoadFile(
}
if (fsPtr->loadFileProc != NULL) {
int retVal = fsPtr->loadFileProc(interp, pathPtr, handlePtr,
&unloadProcPtr);
int retVal = ((Tcl_FSLoadFileProc2 *)(fsPtr->loadFileProc))
(interp, pathPtr, handlePtr, &unloadProcPtr, flags);
if (retVal == TCL_OK) {
if (*handlePtr == NULL) {
@@ -3212,7 +3212,7 @@ Tcl_LoadFile(
ret = Tcl_Read(data, buffer, size);
Tcl_Close(interp, data);
ret = TclpLoadMemory(interp, buffer, size, ret, handlePtr,
&unloadProcPtr);
&unloadProcPtr, flags);
if (ret == TCL_OK && *handlePtr != NULL) {
goto resolveSymbols;
}
@@ -3283,7 +3283,7 @@ Tcl_LoadFile(
Tcl_ResetResult(interp);
retVal = Tcl_LoadFile(interp, copyToPtr, symbols, 0, procPtrs,
retVal = Tcl_LoadFile(interp, copyToPtr, symbols, flags, procPtrs,
&newLoadHandle);
if (retVal != TCL_OK) {
/*
@@ -3514,50 +3514,6 @@ DivertUnloadFile(
ckfree(loadHandle);
}
/*
* This function used to be in the platform specific directories, but it has
* now been made to work cross-platform.
*/
int
TclpLoadFile(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Obj *pathPtr, /* Name of the file containing the desired
* code (UTF-8). */
const char *sym1, const char *sym2,
/* Names of two functions to look up in the
* file's symbol table. */
Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr,
/* Where to return the addresses corresponding
* to sym1 and sym2. */
ClientData *clientDataPtr, /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr)
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
{
Tcl_LoadHandle handle = NULL;
int res;
res = TclpDlopen(interp, pathPtr, &handle, unloadProcPtr);
if (res != TCL_OK) {
return res;
}
if (handle == NULL) {
return TCL_ERROR;
}
*clientDataPtr = handle;
*proc1Ptr = (Tcl_PackageInitProc*) Tcl_FindSymbol(interp, handle, sym1);
*proc2Ptr = (Tcl_PackageInitProc*) Tcl_FindSymbol(interp, handle, sym2);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
+3 -7
View File
@@ -302,10 +302,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;
}
@@ -537,9 +533,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;
+9 -4
View File
@@ -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
@@ -1242,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
+186 -62
View File
@@ -1154,7 +1154,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;
@@ -1497,6 +1497,7 @@ typedef struct ExecEnv {
struct Tcl_Interp *interp;
struct NRE_callback *callbackPtr;
/* Top callback in NRE's stack. */
struct NRE_stack *NRStack;
struct CoroutineData *corPtr;
int rewind;
} ExecEnv;
@@ -2137,8 +2138,7 @@ typedef struct Interp {
* tclOOInt.h and tclOO.c for real definition
* and setup. */
struct NRE_callback *deferredCallbacks;
/* Callbacks that are set previous to a call
struct NRE_callback *deferredCallbacks; /* Callbacks that are set previous to a call
* to some Eval function but that actually
* belong to the command that is about to be
* called - i.e., they should be run *before*
@@ -2250,7 +2250,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:
@@ -2564,6 +2563,8 @@ typedef struct List {
#define TCL_FILESYSTEM_VERSION_2 ((Tcl_FSVersion) 0x2)
typedef ClientData (TclFSGetCwdProc2)(ClientData clientData);
typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
/*
* The following types are used for getting and storing platform-specific file
@@ -2795,14 +2796,19 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRUplevelObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRWhileObjCmd;
MODULE_SCOPE Tcl_NRPostProc TclNRForIterCallback;
MODULE_SCOPE Tcl_NRPostProc TclNRCoroutineActivateCallback;
MODULE_SCOPE Tcl_ObjCmdProc TclNRTailcallObjCmd;
MODULE_SCOPE Tcl_NRPostProc TclNRTailcallEval;
MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd;
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 TclDeferCallback(Tcl_Interp *interp,
Tcl_NRPostProc postProcPtr,
ClientData data0, ClientData data1,
ClientData data2, ClientData data3);
/*
* This structure holds the data for the various iteration callbacks used to
@@ -3082,12 +3088,6 @@ MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr,
MODULE_SCOPE void TclpInitLock(void);
MODULE_SCOPE void TclpInitPlatform(void);
MODULE_SCOPE void TclpInitUnlock(void);
MODULE_SCOPE int TclpLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
const char *sym1, const char *sym2,
Tcl_PackageInitProc **proc1Ptr,
Tcl_PackageInitProc **proc2Ptr,
ClientData *clientDataPtr,
Tcl_FSUnloadFileProc **unloadProcPtr);
MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void);
MODULE_SCOPE void TclpMasterLock(void);
MODULE_SCOPE void TclpMasterUnlock(void);
@@ -3166,13 +3166,13 @@ MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData);
MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr);
MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr,
Tcl_LoadHandle *loadHandle,
Tcl_FSUnloadFileProc **unloadProcPtr);
Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
MODULE_SCOPE int TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval);
#ifdef TCL_LOAD_FROM_MEMORY
MODULE_SCOPE void * TclpLoadMemoryGetBuffer(Tcl_Interp *interp, int size);
MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer,
int size, int codeSize, Tcl_LoadHandle *loadHandle,
Tcl_FSUnloadFileProc **unloadProcPtr);
Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
#endif
MODULE_SCOPE void TclInitThreadStorage(void);
MODULE_SCOPE void TclFinalizeThreadDataThread(void);
@@ -3493,6 +3493,15 @@ MODULE_SCOPE int Tcl_WhileObjCmd(ClientData clientData,
MODULE_SCOPE int TclCompileAppendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileArrayExistsCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileArraySetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileArrayUnsetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3505,10 +3514,13 @@ MODULE_SCOPE int TclCompileContinueCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileDictAppendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictForCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileDictCreateCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictMapCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileDictExistsCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictForCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictGetCmd(Tcl_Interp *interp,
@@ -3520,9 +3532,18 @@ MODULE_SCOPE int TclCompileDictIncrCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileDictLappendCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictMapCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictMergeCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictUnsetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3544,15 +3565,36 @@ MODULE_SCOPE int TclCompileForCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileForeachCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileFormatCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileGlobalCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileIfCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoCommandsCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoCoroutineCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoExistsCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoLevelCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoObjectClassCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoObjectIsACmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileInfoObjectNamespaceCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileIncrCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3583,15 +3625,36 @@ MODULE_SCOPE int TclCompileLreplaceCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileLsetCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceCodeCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceCurrentCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceTailCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceUpvarCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNamespaceWhichCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileNoOp(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileObjectSelfCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileRegexpCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileRegsubCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileReturnCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3604,21 +3667,36 @@ MODULE_SCOPE int TclCompileStringCmpCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileStringEqualCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringFirstCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringIndexCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringLastCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringLenCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringMapCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringMatchCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileStringRangeCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileSubstCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileSwitchCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileTailcallCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
MODULE_SCOPE int TclCompileThrowCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
@@ -3637,6 +3715,45 @@ MODULE_SCOPE int TclCompileVariableCmd(Tcl_Interp *interp,
MODULE_SCOPE int TclCompileWhileCmd(Tcl_Interp *interp,
Tcl_Parse *parsePtr, Command *cmdPtr,
struct CompileEnv *envPtr);
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,
@@ -3929,12 +4046,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)
/*
@@ -4658,7 +4776,6 @@ void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
*----------------------------------------------------------------
*/
#define NRE_USE_SMALL_ALLOC 1 /* Only turn off for debugging purposes. */
#define NRE_ENABLE_ASSERTS 1
/*
@@ -4673,64 +4790,71 @@ typedef struct NRE_callback {
struct NRE_callback *nextPtr;
} NRE_callback;
#define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr)
/*
* Inline version of Tcl_NRAddCallback.
* Inline versions of Tcl_NRAddCallback and friends
*/
#define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3) \
#define TclNRAddCallback(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 = TOP_CB(interp); \
TOP_CB(interp) = callbackPtr; \
NRE_callback *cbPtr; \
ALLOC_CB(interp, cbPtr); \
INIT_CB(cbPtr, postProcPtr,data0,data1,data2,data3); \
} while (0)
#define TclNRDeferCallback(interp,postProcPtr,data0,data1,data2,data3) \
#define INIT_CB(cbPtr, 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; \
cbPtr->procPtr = (postProcPtr); \
cbPtr->data[0] = (ClientData)(data0); \
cbPtr->data[1] = (ClientData)(data1); \
cbPtr->data[2] = (ClientData)(data2); \
cbPtr->data[3] = (ClientData)(data3); \
} 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; \
#define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr)
#define NRE_STACK_SIZE 100
MODULE_SCOPE NRE_callback *TclNewCallback(Tcl_Interp *interp);
MODULE_SCOPE NRE_callback *TclPopCallback(Tcl_Interp *interp);
MODULE_SCOPE Tcl_NRPostProc TclNRStackBottom;
#define NEW 0
#if NEW
#define POP_CB(interp, cbPtr) \
(cbPtr) = TclPopCallback(interp)
#define ALLOC_CB(interp, cbPtr) \
(cbPtr) = TclNewCallback(interp)
#define FREE_CB(cbPtr)
#else /* OLD */
#define POP_CB(interp, cbPtr) \
do {\
(cbPtr) = TOP_CB(interp); \
TOP_CB(interp) = (cbPtr)->nextPtr; \
} 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))
#define TCLNR_FREE(interp, ptr) TclSmallFreeEx((interp), (ptr))
#else
#define TCLNR_ALLOC(interp, ptr) \
(ptr = ((ClientData) ckalloc(sizeof(NRE_callback))))
#define TCLNR_FREE(interp, ptr) ckfree((char *) (ptr))
#define ALLOC_CB(interp, cbPtr) \
do { \
(cbPtr) = (NRE_callback *)ckalloc(sizeof(Tcl_Obj)); \
(cbPtr)->nextPtr = TOP_CB(interp); \
TOP_CB(interp) = (cbPtr); \
} while (0)
#define FREE_CB(cbPtr) \
ckfree(cbPtr)
#endif
typedef struct NRE_stack {
struct NRE_callback items[NRE_STACK_SIZE];
struct NRE_stack *next;
} NRE_stack;
#if NRE_ENABLE_ASSERTS
#define NRE_ASSERT(expr) assert((expr))
#else
+1 -1
View File
@@ -604,7 +604,7 @@ EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags,
typedef struct TclIntStubs {
int magic;
const struct TclIntStubHooks *hooks;
void *hooks;
void (*reserved0)(void);
void (*reserved1)(void);
+22 -1
View File
@@ -95,6 +95,10 @@ EXTERN int TclUnixCopyFile(const char *src, const char *dst,
/* 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 */
@@ -166,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 */
@@ -236,11 +244,15 @@ EXTERN void TclMacOSXNotifierAddRunLoopMode(
/* 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 {
int magic;
const struct TclIntPlatStubHooks *hooks;
void *hooks;
#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
@@ -273,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 */
@@ -305,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 */
@@ -337,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;
@@ -400,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 \
@@ -460,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 \
@@ -512,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) */
+2 -3
View File
@@ -1754,7 +1754,7 @@ AliasNRCmd(
int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
Tcl_Obj *listPtr;
List *listRep;
int flags = TCL_EVAL_INVOKE;
int flags = (TCL_EVAL_INVOKE|TCL_EVAL_REDIRECT);
/*
* Append the arguments to the command prefix and invoke the command in
@@ -1798,9 +1798,8 @@ AliasNRCmd(
*/
if (isRootEnsemble) {
TclNRDeferCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
TclDeferCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
}
iPtr->evalFlags |= TCL_EVAL_REDIRECT;
return Tcl_NREvalObj(interp, listPtr, flags);
}
+13 -4
View File
@@ -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]);
}
/*
+28 -3
View File
@@ -132,9 +132,34 @@ Tcl_LoadObjCmd(
Tcl_LoadHandle loadHandle;
Tcl_UniChar ch;
unsigned len;
int index, flags = 0;
Tcl_Obj *const *savedobjv = objv;
static const char *const options[] = {
"-global", "-lazy", "--", NULL
};
enum options {
LOAD_GLOBAL, LOAD_LAZY, LOAD_LAST
};
while (objc > 2) {
if (TclGetString(objv[1])[0] != '-') {
break;
}
if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
&index) != TCL_OK) {
return TCL_ERROR;
}
++objv; --objc;
if (LOAD_GLOBAL == (enum options) index) {
flags |= TCL_LOAD_GLOBAL;
} else if (LOAD_LAZY == (enum options) index) {
flags |= TCL_LOAD_LAZY;
} else {
break;
}
}
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "fileName ?packageName? ?interp?");
Tcl_WrongNumArgs(interp, 1, savedobjv, "?-global? ?-lazy? ?--? fileName ?packageName? ?interp?");
return TCL_ERROR;
}
if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
@@ -365,7 +390,7 @@ Tcl_LoadObjCmd(
symbols[1] = NULL;
Tcl_MutexLock(&packageMutex);
code = Tcl_LoadFile(interp, objv[1], symbols, 0, &initProc,
code = Tcl_LoadFile(interp, objv[1], symbols, flags, &initProc,
&loadHandle);
Tcl_MutexUnlock(&packageMutex);
if (code != TCL_OK) {
@@ -391,7 +416,7 @@ Tcl_LoadObjCmd(
pkgPtr->unloadProc = (Tcl_PackageUnloadProc *)
Tcl_FindSymbol(interp, loadHandle,
Tcl_DStringValue(&unloadName));
pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *)
pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *)
Tcl_FindSymbol(interp, loadHandle,
Tcl_DStringValue(&safeUnloadName));
pkgPtr->interpRefCount = 0;
+2 -1
View File
@@ -39,10 +39,11 @@ TclpDlopen(
Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr)
Tcl_FSUnloadFileProc **unloadProcPtr,
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
int flags)
{
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"dynamic loading is not currently available on this system",
+134 -135
View File
@@ -104,7 +104,7 @@ static int NamespaceDeleteCmd(ClientData dummy,Tcl_Interp *interp,
static int NamespaceEvalCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
static int NRNamespaceEvalCmd(ClientData dummy,
Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
static int NamespaceExistsCmd(ClientData dummy,Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
static int NamespaceExportCmd(ClientData dummy,Tcl_Interp *interp,
@@ -160,25 +160,25 @@ static const Tcl_ObjType nsNameType = {
*/
static const EnsembleImplMap defaultNamespaceMap[] = {
{"children", NamespaceChildrenCmd, NULL, NULL, NULL, 0},
{"code", NamespaceCodeCmd, NULL, NULL, NULL, 0},
{"current", NamespaceCurrentCmd, NULL, NULL, NULL, 0},
{"delete", NamespaceDeleteCmd, NULL, 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},
{"inscope", NamespaceInscopeCmd, NULL, NRNamespaceInscopeCmd, NULL, 0},
{"origin", NamespaceOriginCmd, NULL, NULL, NULL, 0},
{"parent", NamespaceParentCmd, NULL, NULL, NULL, 0},
{"path", NamespacePathCmd, NULL, NULL, NULL, 0},
{"qualifiers", NamespaceQualifiersCmd, NULL, NULL, NULL, 0},
{"tail", NamespaceTailCmd, NULL, NULL, NULL, 0},
{"unknown", NamespaceUnknownCmd, NULL, NULL, NULL, 0},
{"upvar", NamespaceUpvarCmd, TclCompileNamespaceUpvarCmd, NULL, NULL, 0},
{"which", NamespaceWhichCmd, NULL, NULL, NULL, 0},
{"children", NamespaceChildrenCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
{"code", NamespaceCodeCmd, TclCompileNamespaceCodeCmd, NULL, NULL, 0},
{"current", NamespaceCurrentCmd, TclCompileNamespaceCurrentCmd, NULL, NULL, 0},
{"delete", NamespaceDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
{"ensemble", TclNamespaceEnsembleCmd, NULL, NULL, NULL, 0},
{"eval", NamespaceEvalCmd, NULL, NRNamespaceEvalCmd, 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, 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, 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);
}
}
@@ -689,8 +689,8 @@ Tcl_CreateNamespace(
} else if (*name == '\0') {
Tcl_SetObjResult(interp, Tcl_NewStringObj("can't create namespace"
" \"\": only global namespace can have empty name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
"CREATEGLOBAL", NULL);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
"CREATEGLOBAL", NULL);
return NULL;
} else {
/*
@@ -726,8 +726,8 @@ Tcl_CreateNamespace(
) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create namespace \"%s\": already exists", name));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
"CREATEEXISTING", NULL);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
"CREATEEXISTING", NULL);
return NULL;
}
}
@@ -1337,7 +1337,7 @@ Tcl_Export(
if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid export pattern"
" \"%s\": pattern can't specify a namespace", pattern));
Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL);
Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL);
return TCL_ERROR;
}
@@ -1542,7 +1542,7 @@ Tcl_Import(
if (strlen(pattern) == 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("empty import pattern",-1));
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL);
return TCL_ERROR;
}
TclGetNamespaceForQualName(interp, pattern, nsPtr,
@@ -1560,12 +1560,12 @@ Tcl_Import(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no namespace specified in import pattern \"%s\"",
pattern));
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL);
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"import pattern \"%s\" tries to import from namespace"
" \"%s\" into itself", pattern, importNsPtr->name));
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL);
}
return TCL_ERROR;
}
@@ -1688,7 +1688,7 @@ DoImport(
" containing command \"%s\"",
pattern, Tcl_DStringValue(&ds)));
Tcl_DStringFree(&ds);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL);
return TCL_ERROR;
}
}
@@ -1728,7 +1728,7 @@ DoImport(
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't import command \"%s\": already exists", cmdName));
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL);
Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -1945,8 +1945,8 @@ InvokeImportedNRCmd(
ImportedCmdData *dataPtr = clientData;
Command *realCmdPtr = dataPtr->realCmdPtr;
((Interp *) interp)->evalFlags |= TCL_EVAL_REDIRECT;
return Tcl_NRCmdSwap(interp, (Tcl_Command) realCmdPtr, objc, objv, 0);
return Tcl_NRCmdSwap(interp, (Tcl_Command) realCmdPtr, objc, objv,
TCL_EVAL_REDIRECT);
}
static int
@@ -3285,12 +3285,12 @@ NRNamespaceEvalCmd(
}
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
framePtr->objc = objc;
framePtr->objv = objv;
framePtr->objc = objc;
framePtr->objv = objv;
} else {
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- iPtr->ensembleRewrite.numInsertedObjs;
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- iPtr->ensembleRewrite.numInsertedObjs;
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
}
if (objc == 3) {
@@ -3748,12 +3748,12 @@ NRNamespaceInscopeCmd(
}
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
framePtr->objc = objc;
framePtr->objv = objv;
framePtr->objc = objc;
framePtr->objv = objv;
} else {
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- iPtr->ensembleRewrite.numInsertedObjs;
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
- iPtr->ensembleRewrite.numInsertedObjs;
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
}
/*
@@ -3958,15 +3958,15 @@ NamespacePathCmd(
*/
if (objc == 1) {
Tcl_Obj *resultObj = Tcl_NewObj();
Tcl_Obj *resultObj = Tcl_NewObj();
for (i=0 ; i<nsPtr->commandPathLength ; i++) {
if (nsPtr->commandPathArray[i].nsPtr != NULL) {
Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
nsPtr->commandPathArray[i].nsPtr->fullName, -1));
Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
nsPtr->commandPathArray[i].nsPtr->fullName, -1));
}
}
Tcl_SetObjResult(interp, resultObj);
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
}
@@ -4843,8 +4843,8 @@ TclLogCommandInfo(
int length, /* Number of bytes in command (-1 means use
* all bytes up to first null byte). */
const unsigned char *pc, /* Current pc of bytecode execution context */
Tcl_Obj **tosPtr) /* Current stack of bytecode execution
* context */
Tcl_Obj **tosPtr) /* Current stack of bytecode execution
* context */
{
register const char *p;
Interp *iPtr = (Interp *) interp;
@@ -4861,55 +4861,55 @@ TclLogCommandInfo(
}
if (command != NULL) {
/*
* Compute the line number where the error occurred.
*/
/*
* Compute the line number where the error occurred.
*/
iPtr->errorLine = 1;
for (p = script; p != command; p++) {
if (*p == '\n') {
iPtr->errorLine++;
}
}
iPtr->errorLine = 1;
for (p = script; p != command; p++) {
if (*p == '\n') {
iPtr->errorLine++;
}
}
if (length < 0) {
length = strlen(command);
}
overflow = (length > limit);
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
if (length < 0) {
length = strlen(command);
}
overflow = (length > limit);
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL)
? "while executing" : "invoked from within"),
(overflow ? limit : length), command,
(overflow ? "..." : "")));
varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
NULL, 0, 0, &arrayPtr);
if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
/*
* Should not happen.
*/
if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
/*
* Should not happen.
*/
return;
} else {
Tcl_HashEntry *hPtr
return;
} else {
Tcl_HashEntry *hPtr
= Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
if (tracePtr->traceProc != EstablishErrorInfoTraces) {
/*
* The most recent trace set on ::errorInfo is not the one the
* core itself puts on last. This means some other code is
if (tracePtr->traceProc != EstablishErrorInfoTraces) {
/*
* The most recent trace set on ::errorInfo is not the one the
* core itself puts on last. This means some other code is
* tracing the variable, and the additional trace(s) might be
* write traces that expect the timing of writes to
* ::errorInfo that existed Tcl releases before 8.5. To
* satisfy that compatibility need, we write the current
* -errorinfo value to the ::errorInfo variable.
*/
*/
Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL, iPtr->errorInfo,
Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL, iPtr->errorInfo,
TCL_GLOBAL_ONLY);
}
}
}
}
}
/*
@@ -4917,60 +4917,60 @@ TclLogCommandInfo(
*/
if (Tcl_IsShared(iPtr->errorStack)) {
Tcl_Obj *newObj;
newObj = Tcl_DuplicateObj(iPtr->errorStack);
Tcl_DecrRefCount(iPtr->errorStack);
Tcl_IncrRefCount(newObj);
iPtr->errorStack = newObj;
Tcl_Obj *newObj;
newObj = Tcl_DuplicateObj(iPtr->errorStack);
Tcl_DecrRefCount(iPtr->errorStack);
Tcl_IncrRefCount(newObj);
iPtr->errorStack = newObj;
}
if (iPtr->resetErrorStack) {
int len;
iPtr->resetErrorStack = 0;
iPtr->resetErrorStack = 0;
Tcl_ListObjLength(interp, iPtr->errorStack, &len);
/*
* Reset while keeping the list intrep as much as possible.
*/
/*
* Reset while keeping the list intrep as much as possible.
*/
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
if (pc != NULL) {
Tcl_Obj *innerContext;
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
if (pc != NULL) {
Tcl_Obj *innerContext;
innerContext = TclGetInnerContext(interp, pc, tosPtr);
if (innerContext != NULL) {
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext);
}
} else if (command != NULL) {
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
Tcl_NewStringObj(command, length));
}
innerContext = TclGetInnerContext(interp, pc, tosPtr);
if (innerContext != NULL) {
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext);
}
} else if (command != NULL) {
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
Tcl_NewStringObj(command, length));
}
}
if (!iPtr->framePtr->objc) {
/*
* Special frame, nothing to report.
*/
/*
* Special frame, nothing to report.
*/
} else if (iPtr->varFramePtr != iPtr->framePtr) {
/*
* uplevel case, [lappend errorstack UP $relativelevel]
*/
/*
* uplevel case, [lappend errorstack UP $relativelevel]
*/
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj(
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj(
iPtr->framePtr->level - iPtr->varFramePtr->level));
} else if (iPtr->framePtr != iPtr->rootFramePtr) {
/*
* normal case, [lappend errorstack CALL [info level 0]]
*/
/*
* normal case, [lappend errorstack CALL [info level 0]]
*/
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj(
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj(
iPtr->framePtr->objc, iPtr->framePtr->objv));
}
}
@@ -4980,8 +4980,8 @@ TclLogCommandInfo(
*
* TclErrorStackResetIf --
*
* The TIP 348 reset/no-bc part of TLCI, for specific use by
* TclCompileSyntaxError.
* The TIP 348 reset/no-bc part of TLCI, for specific use by
* TclCompileSyntaxError.
*
* Results:
* None.
@@ -5002,27 +5002,27 @@ TclErrorStackResetIf(
Interp *iPtr = (Interp *) interp;
if (Tcl_IsShared(iPtr->errorStack)) {
Tcl_Obj *newObj;
newObj = Tcl_DuplicateObj(iPtr->errorStack);
Tcl_DecrRefCount(iPtr->errorStack);
Tcl_IncrRefCount(newObj);
iPtr->errorStack = newObj;
Tcl_Obj *newObj;
newObj = Tcl_DuplicateObj(iPtr->errorStack);
Tcl_DecrRefCount(iPtr->errorStack);
Tcl_IncrRefCount(newObj);
iPtr->errorStack = newObj;
}
if (iPtr->resetErrorStack) {
int len;
iPtr->resetErrorStack = 0;
iPtr->resetErrorStack = 0;
Tcl_ListObjLength(interp, iPtr->errorStack, &len);
/*
* Reset while keeping the list intrep as much as possible.
*/
/*
* Reset while keeping the list intrep as much as possible.
*/
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
Tcl_NewStringObj(msg, length));
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral);
Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
Tcl_NewStringObj(msg, length));
}
}
@@ -5065,6 +5065,5 @@ Tcl_LogCommandInfo(
* c-basic-offset: 4
* fill-column: 78
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/
+4 -2
View File
@@ -314,6 +314,7 @@ InitFoundation(
Foundation *fPtr = ckalloc(sizeof(Foundation));
Tcl_Obj *namePtr, *argsPtr, *bodyPtr;
Tcl_DString buffer;
Command *cmdPtr;
int i;
/*
@@ -440,8 +441,9 @@ InitFoundation(
NULL);
Tcl_CreateObjCommand(interp, "::oo::Helpers::nextto", TclOONextToObjCmd,
NULL, NULL);
Tcl_CreateObjCommand(interp, "::oo::Helpers::self", TclOOSelfObjCmd, NULL,
NULL);
cmdPtr = (Command *) Tcl_CreateObjCommand(interp, "::oo::Helpers::self",
TclOOSelfObjCmd, NULL, NULL);
cmdPtr->compileProc = TclCompileObjectSelfCmd;
Tcl_CreateObjCommand(interp, "::oo::define", TclOODefineObjCmd, NULL,
NULL);
Tcl_CreateObjCommand(interp, "::oo::objdefine", TclOOObjDefObjCmd, NULL,
+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
/*
+2 -2
View File
@@ -100,13 +100,13 @@ TCLOOAPI void Tcl_ClassSetDestructor(Tcl_Interp *interp,
TCLOOAPI Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp,
Tcl_Object object);
typedef struct TclOOStubHooks {
typedef struct {
const struct TclOOIntStubs *tclOOIntStubs;
} TclOOStubHooks;
typedef struct TclOOStubs {
int magic;
const struct TclOOStubHooks *hooks;
const TclOOStubHooks *hooks;
Tcl_Object (*tcl_CopyObjectInstance) (Tcl_Interp *interp, Tcl_Object sourceObject, const char *targetName, const char *targetNamespaceName); /* 0 */
Tcl_Object (*tcl_GetClassAsObject) (Tcl_Class clazz); /* 1 */
+39 -72
View File
@@ -43,47 +43,45 @@ static Tcl_ObjCmdProc InfoClassSubsCmd;
static Tcl_ObjCmdProc InfoClassSupersCmd;
static Tcl_ObjCmdProc InfoClassVariablesCmd;
struct NameProcMap { const char *name; Tcl_ObjCmdProc *proc; };
/*
* List of commands that are used to implement the [info object] subcommands.
*/
static const struct NameProcMap infoObjectCmds[] = {
{"::oo::InfoObject::call", InfoObjectCallCmd},
{"::oo::InfoObject::class", InfoObjectClassCmd},
{"::oo::InfoObject::definition", InfoObjectDefnCmd},
{"::oo::InfoObject::filters", InfoObjectFiltersCmd},
{"::oo::InfoObject::forward", InfoObjectForwardCmd},
{"::oo::InfoObject::isa", InfoObjectIsACmd},
{"::oo::InfoObject::methods", InfoObjectMethodsCmd},
{"::oo::InfoObject::methodtype", InfoObjectMethodTypeCmd},
{"::oo::InfoObject::mixins", InfoObjectMixinsCmd},
{"::oo::InfoObject::namespace", InfoObjectNsCmd},
{"::oo::InfoObject::variables", InfoObjectVariablesCmd},
{"::oo::InfoObject::vars", InfoObjectVarsCmd},
{NULL, NULL}
static const EnsembleImplMap infoObjectCmds[] = {
{"call", InfoObjectCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"class", InfoObjectClassCmd, TclCompileInfoObjectClassCmd, 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, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
{"methodtype", InfoObjectMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
{"mixins", InfoObjectMixinsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"namespace", InfoObjectNsCmd, TclCompileInfoObjectNamespaceCmd, NULL, NULL, 0},
{"variables", InfoObjectVariablesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
{"vars", InfoObjectVarsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
{NULL, NULL, NULL, NULL, NULL, 0}
};
/*
* List of commands that are used to implement the [info class] subcommands.
*/
static const struct NameProcMap infoClassCmds[] = {
{"::oo::InfoClass::call", InfoClassCallCmd},
{"::oo::InfoClass::constructor", InfoClassConstrCmd},
{"::oo::InfoClass::definition", InfoClassDefnCmd},
{"::oo::InfoClass::destructor", InfoClassDestrCmd},
{"::oo::InfoClass::filters", InfoClassFiltersCmd},
{"::oo::InfoClass::forward", InfoClassForwardCmd},
{"::oo::InfoClass::instances", InfoClassInstancesCmd},
{"::oo::InfoClass::methods", InfoClassMethodsCmd},
{"::oo::InfoClass::methodtype", InfoClassMethodTypeCmd},
{"::oo::InfoClass::mixins", InfoClassMixinsCmd},
{"::oo::InfoClass::subclasses", InfoClassSubsCmd},
{"::oo::InfoClass::superclasses", InfoClassSupersCmd},
{"::oo::InfoClass::variables", InfoClassVariablesCmd},
{NULL, NULL}
static const EnsembleImplMap infoClassCmds[] = {
{"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}
};
/*
@@ -101,58 +99,27 @@ void
TclOOInitInfo(
Tcl_Interp *interp)
{
Tcl_Namespace *nsPtr;
Tcl_Command infoCmd;
int i;
Tcl_Obj *mapDict;
/*
* Build the ensemble used to implement [info object].
* Build the ensembles used to implement [info object] and [info class].
*/
nsPtr = Tcl_CreateNamespace(interp, "::oo::InfoObject", NULL, NULL);
Tcl_CreateEnsemble(interp, nsPtr->fullName, nsPtr, TCL_ENSEMBLE_PREFIX);
Tcl_Export(interp, nsPtr, "[a-z]*", 1);
for (i=0 ; infoObjectCmds[i].name!=NULL ; i++) {
Tcl_CreateObjCommand(interp, infoObjectCmds[i].name,
infoObjectCmds[i].proc, NULL, NULL);
}
/*
* Build the ensemble used to implement [info class].
*/
nsPtr = Tcl_CreateNamespace(interp, "::oo::InfoClass", NULL, NULL);
Tcl_CreateEnsemble(interp, nsPtr->fullName, nsPtr, TCL_ENSEMBLE_PREFIX);
Tcl_Export(interp, nsPtr, "[a-z]*", 1);
for (i=0 ; infoClassCmds[i].name!=NULL ; i++) {
Tcl_CreateObjCommand(interp, infoClassCmds[i].name,
infoClassCmds[i].proc, NULL, NULL);
}
TclMakeEnsemble(interp, "::oo::InfoObject", infoObjectCmds);
TclMakeEnsemble(interp, "::oo::InfoClass", infoClassCmds);
/*
* Install into the master [info] ensemble.
*/
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
@@ -90,7 +90,7 @@ TCLOOAPI void TclOOClassSetMixins(Tcl_Interp *interp,
typedef struct TclOOIntStubs {
int magic;
const struct TclOOIntStubHooks *hooks;
void *hooks;
Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */
Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 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
View File
@@ -356,6 +356,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
+1 -1
View File
@@ -69,7 +69,7 @@ EXTERN int Tcl_MacOSXOpenVersionedBundleResources(
typedef struct TclPlatStubs {
int magic;
const struct TclPlatStubHooks *hooks;
void *hooks;
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */

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