Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd0bf3e350 | ||
|
|
7754effa64 | ||
|
|
0d214a0a14 | ||
|
|
4087d33e18 | ||
|
|
8533669f18 | ||
|
|
8a7422b2db | ||
|
|
524556581a | ||
|
|
c9152240b9 | ||
|
|
d6ec1e9bfc | ||
|
|
b49ab44beb | ||
|
|
a5d25d127e | ||
|
|
d22d1ef546 | ||
|
|
952dfe7d9a | ||
|
|
b2dabdc1eb | ||
|
|
bc33fd2059 | ||
|
|
a8a9d42601 | ||
|
|
d223d51178 | ||
|
|
7fbeaf9528 | ||
|
|
2c5cd34ebe | ||
|
|
13adf38211 | ||
|
|
88af143aea | ||
|
|
9b6ebeae02 | ||
|
|
5bce11a1c8 | ||
|
|
32cc5d8d3c | ||
|
|
679963704f | ||
|
|
32df42787e | ||
|
|
0cf062c388 | ||
|
|
207412c303 | ||
|
|
bf368d9079 | ||
|
|
45c7f36909 | ||
|
|
285dd19c62 | ||
|
|
240695b9f5 | ||
|
|
3aba154e26 | ||
|
|
1bef171761 | ||
|
|
a7affdff05 | ||
|
|
8ddb48c272 | ||
|
|
3ce1c8d98b | ||
|
|
ef5aee8d47 | ||
|
|
ca4329f20b | ||
|
|
8d4878fee6 | ||
|
|
b0465ff0e8 | ||
|
|
f9651e0da6 | ||
|
|
18ab8f43a0 | ||
|
|
77014e3f62 | ||
|
|
46821e04b6 | ||
|
|
51e5bda476 | ||
|
|
656b2b4f87 | ||
|
|
0fbd4e16a9 | ||
|
|
c0845253a0 | ||
|
|
38ba6bd5d4 | ||
|
|
0c64074372 | ||
|
|
53eb119d0b | ||
|
|
8751239349 | ||
|
|
bf14f11c63 | ||
|
|
d12ee9da30 | ||
|
|
78d91cb253 | ||
|
|
66c2909694 | ||
|
|
65013d771a | ||
|
|
4b67a9506b | ||
|
|
74cca07e35 | ||
|
|
e2e451e2e5 | ||
|
|
ed156a09fa | ||
|
|
8f40b2b313 | ||
|
|
21bd9cf5ad | ||
|
|
ebbf7144d2 | ||
|
|
fac8f9d0ae | ||
|
|
f3a3f7b9e8 | ||
|
|
a2afb09b3c | ||
|
|
81a67b9cf4 | ||
|
|
569360bf40 | ||
|
|
59e42de547 | ||
|
|
fa7a06447d | ||
|
|
b13b1c6020 | ||
|
|
d67ebaffd4 | ||
|
|
8890130ab8 | ||
|
|
093fb49d43 | ||
|
|
0ccb6618bd | ||
|
|
989c5bb9a4 | ||
|
|
94ada5d31f | ||
|
|
af92fc0c28 | ||
|
|
4557297b08 | ||
|
|
1d29f93257 | ||
|
|
9918a06afa | ||
|
|
e1c8f78ed0 | ||
|
|
b9a522a6bf | ||
|
|
eace9319cb | ||
|
|
eb7f17ba98 | ||
|
|
2f1b92ba12 | ||
|
|
6428006e92 | ||
|
|
78a3c34ca2 | ||
|
|
c13ee047c8 | ||
|
|
c1784e6b4c | ||
|
|
498562a0e5 | ||
|
|
15f02f424c | ||
|
|
c20c0a1e75 | ||
|
|
6d80a782d0 | ||
|
|
2fd9e3776b | ||
|
|
a8c55de8fc | ||
|
|
16df5aebc9 | ||
|
|
cebb11e97e | ||
|
|
8a282bbf9e | ||
|
|
5e55e0d280 | ||
|
|
bd8d73a7d5 | ||
|
|
b361c43c61 | ||
|
|
9f45d4d696 | ||
|
|
aa34213e75 | ||
|
|
b54c784f20 | ||
|
|
5af462da66 | ||
|
|
c46c79caa2 | ||
|
|
2adea0d04e | ||
|
|
7720b5d9df | ||
|
|
f894c98ebc | ||
|
|
1aa7610988 | ||
|
|
02929519ba | ||
|
|
49e8fc13b0 | ||
|
|
22f216f372 | ||
|
|
55563ee093 | ||
|
|
7442eb42a1 | ||
|
|
38ee3de94f | ||
|
|
c9c4a3ad02 | ||
|
|
43e62982f4 | ||
|
|
59aff80a90 | ||
|
|
5240308ed2 | ||
|
|
0dcab1bed4 | ||
|
|
85ca4a31a0 | ||
|
|
553348c5f3 | ||
|
|
658b4c0ee7 | ||
|
|
41d3318c10 | ||
|
|
8354804874 | ||
|
|
bf4c66a207 | ||
|
|
70d1d20609 | ||
|
|
b7ab8113fe | ||
|
|
80108bef0e | ||
|
|
e2ddd4a2fd | ||
|
|
96295b0151 | ||
|
|
7cd225ff30 | ||
|
|
fa84674fb9 | ||
|
|
a1beeadf6c | ||
|
|
fcf174f284 | ||
|
|
29dd55c971 | ||
|
|
52e06a03d8 | ||
|
|
8f22bd9be0 | ||
|
|
5d659010d2 | ||
|
|
8e1d78b43a | ||
|
|
db0645ad80 | ||
|
|
7e68d373c1 | ||
|
|
00451a175e | ||
|
|
6e2667d4d2 | ||
|
|
2ab23f6186 | ||
|
|
b670d49ae2 | ||
|
|
858c24761a | ||
|
|
70e9e19b64 | ||
|
|
cbfb51846d | ||
|
|
91d791cd85 | ||
|
|
adb756a95a | ||
|
|
491f1691e5 | ||
|
|
a24ce60075 | ||
|
|
134609fd57 | ||
|
|
f7a0d6fdbe | ||
|
|
b93728a301 | ||
|
|
c8318a69ff | ||
|
|
41ace1ce41 | ||
|
|
4c439c45ea | ||
|
|
5b9c4d9393 | ||
|
|
212fc8e012 | ||
|
|
a47366b842 | ||
|
|
1892e61aa6 | ||
|
|
daf66f3418 | ||
|
|
e1adc46245 | ||
|
|
192c0b4b69 | ||
|
|
0119f508e2 | ||
|
|
e2c63e97bc | ||
|
|
275cdefdd7 | ||
|
|
4a2c3d9ab9 | ||
|
|
59c308ebf0 | ||
|
|
920dfb2f56 | ||
|
|
f14b389544 | ||
|
|
0aeb86cee1 | ||
|
|
04b42c6d46 | ||
|
|
762f642867 | ||
|
|
e770d85db6 | ||
|
|
2e074de52a | ||
|
|
73cbb5ef6f | ||
|
|
2b18d7d019 | ||
|
|
63c50fda84 | ||
|
|
a61f0f3aa3 | ||
|
|
b8076815be | ||
|
|
cb3e2cac34 | ||
|
|
a8ea141350 | ||
|
|
3c4956ece0 | ||
|
|
cee0989147 | ||
|
|
20058bf813 | ||
|
|
c3bb46df16 | ||
|
|
1f0fc6d0b1 | ||
|
|
071105233b | ||
|
|
fcba3b601b | ||
|
|
5e8aae6bdc | ||
|
|
2354c488dc | ||
|
|
c06ccc92c0 | ||
|
|
c23935f0c4 | ||
|
|
a271a46238 | ||
|
|
1ff71889ea | ||
|
|
bcd546207d | ||
|
|
afe5dfc938 | ||
|
|
893f9c7cc6 | ||
|
|
6734623337 | ||
|
|
ea58b7b66f | ||
|
|
7635c56e5d | ||
|
|
1c5b833a43 | ||
|
|
5f3314ac7b | ||
|
|
4ffdb51e34 | ||
|
|
23cac7b42c | ||
|
|
24650f8e9d | ||
|
|
d8ae9915dd | ||
|
|
474d2cb11a | ||
|
|
57c33f7587 | ||
|
|
498d315304 | ||
|
|
a26191b7b2 | ||
|
|
051bf96db1 | ||
|
|
9aab4c1bac | ||
|
|
299d4abd03 | ||
|
|
5b64a7d24c | ||
|
|
efdc17a4d5 | ||
|
|
626e22c982 | ||
|
|
842e894ac5 | ||
|
|
9123f8f93e | ||
|
|
20ad704b92 | ||
|
|
ba7ee97d3a | ||
|
|
f679fe87ab | ||
|
|
3ba55d4c91 | ||
|
|
53690d2607 | ||
|
|
ad3ee62cd3 | ||
|
|
55d5fb55a2 | ||
|
|
335ddd20ca | ||
|
|
ca3ab36dfd | ||
|
|
96e7bb4e24 | ||
|
|
5c0961e758 | ||
|
|
109f50dfe1 | ||
|
|
398787d859 | ||
|
|
85167c88b6 | ||
|
|
b2e0789f6b | ||
|
|
9b474d56b9 | ||
|
|
ec58b631ce | ||
|
|
e55f7c6612 | ||
|
|
8a8dee7bde | ||
|
|
2bd81c6785 | ||
|
|
e219c6140a | ||
|
|
f6be9e19c2 | ||
|
|
688210c291 | ||
|
|
83d0e64e99 | ||
|
|
a3bc9d0e44 | ||
|
|
49dd27a4ea | ||
|
|
b9c17fff37 | ||
|
|
c74d12c2e0 | ||
|
|
ac3ebfbd49 | ||
|
|
02dd785b16 | ||
|
|
9ef6a75daf | ||
|
|
f17426d59e | ||
|
|
acd9d78458 | ||
|
|
d82d84f004 | ||
|
|
5c68347747 | ||
|
|
eeb982f501 | ||
|
|
ecec3a1a0b | ||
|
|
040b7a730e | ||
|
|
ee5f41d141 | ||
|
|
71560be819 | ||
|
|
05d8b59183 | ||
|
|
bedb57a468 | ||
|
|
0d71be4a7e | ||
|
|
d25cf46468 | ||
|
|
e1019374e0 | ||
|
|
1c889c0352 | ||
|
|
f7bae6ac60 | ||
|
|
8122cb706d | ||
|
|
41128611bf | ||
|
|
13ba95be10 | ||
|
|
734725f73e | ||
|
|
c705d5b937 | ||
|
|
225c3d3e5f | ||
|
|
706e42d83b | ||
|
|
8dfd4b7f02 | ||
|
|
ee55e87c47 | ||
|
|
d764a87552 | ||
|
|
129d93bc40 | ||
|
|
247a043a05 | ||
|
|
db601d75b9 | ||
|
|
8a9731657e | ||
|
|
966e9c3477 | ||
|
|
7927604b94 | ||
|
|
a584e5f052 | ||
|
|
54e225f382 | ||
|
|
e5c614fc2d | ||
|
|
aaac3316a4 | ||
|
|
0af0c0e973 | ||
|
|
532e6f0c8e | ||
|
|
6e458bffe0 | ||
|
|
6c99b4f545 | ||
|
|
7e90ca9d19 | ||
|
|
37f4435517 | ||
|
|
28f6f6deb5 | ||
|
|
8eb29f16f2 | ||
|
|
495bfd5d18 | ||
|
|
c02571fab0 | ||
|
|
e4c33dab06 | ||
|
|
43a3d8d594 | ||
|
|
40ea3f744a | ||
|
|
2481948f74 | ||
|
|
23612cace5 | ||
|
|
b38a57ebda | ||
|
|
9b4651ad57 | ||
|
|
43da7a5b40 | ||
|
|
56d71ce11b | ||
|
|
f7baa52775 | ||
|
|
b488ca3be7 | ||
|
|
0c7b5c9b40 | ||
|
|
161982db4e | ||
|
|
96b22f2bf9 | ||
|
|
3bb8b9504c | ||
|
|
2aaae6b3fe | ||
|
|
cbe9080dcf | ||
|
|
b63fcbf8cf | ||
|
|
a8d394eeaf | ||
|
|
66adad9c26 | ||
|
|
025299dede | ||
|
|
ee7e6c078d | ||
|
|
f0648d0658 | ||
|
|
d751107a26 | ||
|
|
d6600f4d5a | ||
|
|
c9e3b7680f | ||
|
|
e8273026f8 | ||
|
|
a3e13bdce2 | ||
|
|
1434262700 | ||
|
|
f0047f95e1 | ||
|
|
c0050dd5cd | ||
|
|
5d1214f529 | ||
|
|
4d5127aca4 | ||
|
|
b49f1ffb1b | ||
|
|
bba49ba498 | ||
|
|
2f46625fe9 | ||
|
|
0a40e59f2c | ||
|
|
e148310a7b | ||
|
|
2b24dada59 | ||
|
|
494a614936 | ||
|
|
c8e8e61fcc | ||
|
|
937f040a7f | ||
|
|
4a61476888 | ||
|
|
720fc8cc34 | ||
|
|
7b864a3d91 | ||
|
|
aae531d780 | ||
|
|
f2e45587d3 | ||
|
|
25cd849a61 | ||
|
|
884ea95c53 | ||
|
|
4cc68c3c06 | ||
|
|
4443d92ca2 | ||
|
|
34b81fea59 | ||
|
|
f0e80d448f | ||
|
|
2fffc3d3e9 | ||
|
|
bd225549d9 | ||
|
|
bfa17c4303 | ||
|
|
1c974eb626 | ||
|
|
b474131fd6 | ||
|
|
dab3544492 | ||
|
|
56756de072 | ||
|
|
03a345e867 | ||
|
|
3027444baf | ||
|
|
ad27974fb0 | ||
|
|
794c4bc874 | ||
|
|
129b4229f0 | ||
|
|
95eb3ddcaa | ||
|
|
aa40191938 | ||
|
|
0a41daed74 | ||
|
|
a4c60c3914 | ||
|
|
354910b5c5 | ||
|
|
d9cfa9ca3b | ||
|
|
e021bca54d | ||
|
|
17e289ab9d | ||
|
|
4683dce51c |
@@ -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
@@ -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
@@ -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
@@ -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,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.
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#ifndef _DIRENT
|
||||
#define _DIRENT
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
/*
|
||||
* Dirent structure, which holds information about a single
|
||||
* directory entry.
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#ifndef __dlfcn_h__
|
||||
#define __dlfcn_h__
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#ifndef _UNISTD
|
||||
#define _UNISTD
|
||||
|
||||
#include "tcl.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
|
||||
+4
-4
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+413
-158
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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[] = {
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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
@@ -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[];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user