Compare commits
365
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
790b302275 | ||
|
|
dc11ffbbdb | ||
|
|
1571dc01bb | ||
|
|
4dc2505e43 | ||
|
|
18a2ebc51d | ||
|
|
da3723c942 | ||
|
|
27ef344b9c | ||
|
|
885ced5608 | ||
|
|
b1fe66323b | ||
|
|
a188ceee21 | ||
|
|
eb87ed60f6 | ||
|
|
bc94a394c9 | ||
|
|
46d871617f | ||
|
|
d654ce6429 | ||
|
|
452f14ebb5 | ||
|
|
0a7d5ef6ed | ||
|
|
f785a01764 | ||
|
|
274f081025 | ||
|
|
76ed3d5b55 | ||
|
|
fba10e8615 | ||
|
|
1f0c1b800d | ||
|
|
a7e97de50a | ||
|
|
ea11870f5b | ||
|
|
95b511bac2 | ||
|
|
17e1ea228c | ||
|
|
53abdcc518 | ||
|
|
d963b1acb7 | ||
|
|
04432d4dd1 | ||
|
|
3e4f5907b6 | ||
|
|
4a159c5199 | ||
|
|
b53cf6d38c | ||
|
|
779b8dad76 | ||
|
|
cd428c1a44 | ||
|
|
16dbe3f5a2 | ||
|
|
7b989f0312 | ||
|
|
994e1d8062 | ||
|
|
de8e3be492 | ||
|
|
d44a63b65b | ||
|
|
423d995e0d | ||
|
|
5c37d95180 | ||
|
|
970922295a | ||
|
|
31690ce7fb | ||
|
|
630d4b9211 | ||
|
|
7faf4f27a4 | ||
|
|
dd1c28a788 | ||
|
|
afd6d5649f | ||
|
|
e9d7b07476 | ||
|
|
b8ffbb14c4 | ||
|
|
39dbbd57af | ||
|
|
bbfc83c86f | ||
|
|
d31beb3e7f | ||
|
|
aa3b157338 | ||
|
|
bf27b64405 | ||
|
|
76b6b03be7 | ||
|
|
c205f272f7 | ||
|
|
0551ecffd6 | ||
|
|
13967f965d | ||
|
|
79ff282b02 | ||
|
|
9afdf28497 | ||
|
|
bfae5bf492 | ||
|
|
925bd5794e | ||
|
|
ae54e070a1 | ||
|
|
8b894ab295 | ||
|
|
e35292f314 | ||
|
|
7f0e6652c7 | ||
|
|
7634bdaef2 | ||
|
|
9cb330963b | ||
|
|
4dc1a8a588 | ||
|
|
66f257a588 | ||
|
|
36825d23b9 | ||
|
|
326e0a8fdf | ||
|
|
29fdaa6dcd | ||
|
|
ae0ad313fd | ||
|
|
ec64cc0418 | ||
|
|
c482675d84 | ||
|
|
7dd13b72b6 | ||
|
|
54c0881e9d | ||
|
|
d81daf76bd | ||
|
|
11e9b6a9a5 | ||
|
|
8fe7f3fcdf | ||
|
|
f3e9f9caa3 | ||
|
|
28d5ff4eb5 | ||
|
|
71c2d1a883 | ||
|
|
c8597887e4 | ||
|
|
05009534ee | ||
|
|
f50a4eed54 | ||
|
|
90813dfce8 | ||
|
|
a16868a54c | ||
|
|
c4eac3e8eb | ||
|
|
7b78869343 | ||
|
|
ab8a39e6b9 | ||
|
|
870f61c05d | ||
|
|
6585306973 | ||
|
|
b1d510f1db | ||
|
|
111f52e7ed | ||
|
|
6548fc4ad1 | ||
|
|
a629b0ba31 | ||
|
|
8c066a970f | ||
|
|
29b9de871c | ||
|
|
a9dbadf46a | ||
|
|
02e79b9ec1 | ||
|
|
5aa514f49a | ||
|
|
2bc8d915a2 | ||
|
|
c4f7e08fc6 | ||
|
|
008c7038cb | ||
|
|
dfb2a3f2e2 | ||
|
|
e8aa220d08 | ||
|
|
8d3c0c2e81 | ||
|
|
3adfe07f74 | ||
|
|
7aae664d12 | ||
|
|
cdb1ef8aac | ||
|
|
e7e4c74b7f | ||
|
|
3d6c6683bb | ||
|
|
bf9e61ca6a | ||
|
|
db811061d4 | ||
|
|
63a316c43b | ||
|
|
3da8f74e75 | ||
|
|
3833c42f54 | ||
|
|
2bfb7b96c0 | ||
|
|
35141afcc9 | ||
|
|
6053836b97 | ||
|
|
e13460b1fb | ||
|
|
41512fe1fa | ||
|
|
4ef0c69aaa | ||
|
|
7660c04aff | ||
|
|
7ca470456b | ||
|
|
ab18c108f7 | ||
|
|
7ccdd3657b | ||
|
|
98dbefe2cc | ||
|
|
b748232291 | ||
|
|
d35a5023da | ||
|
|
c4b6cab579 | ||
|
|
cf8c1e7bdc | ||
|
|
6f860bc18d | ||
|
|
2bd794f7cc | ||
|
|
5b7e79f851 | ||
|
|
3b2cb79ab1 | ||
|
|
0cce018c67 | ||
|
|
f2115ca085 | ||
|
|
ac673f63d0 | ||
|
|
5001d7d18c | ||
|
|
a134b03eda | ||
|
|
d823d4a2d5 | ||
|
|
27696b490b | ||
|
|
b37c60fe43 | ||
|
|
d0af5aa92c | ||
|
|
d4eb48d90f | ||
|
|
9faead9d18 | ||
|
|
404eadfdaf | ||
|
|
722ba1aa44 | ||
|
|
4cead413c9 | ||
|
|
2501dbb8d0 | ||
|
|
0050652afb | ||
|
|
4704b442fb | ||
|
|
5b8d20e6de | ||
|
|
2151838b5b | ||
|
|
acb9c613f1 | ||
|
|
ee54cd02de | ||
|
|
ad4538af95 | ||
|
|
c2e7b1ce36 | ||
|
|
a8f05c5339 | ||
|
|
e26431e0f3 | ||
|
|
23a34a26fe | ||
|
|
3cd3541039 | ||
|
|
f846b3f965 | ||
|
|
a22b8736ec | ||
|
|
87a97e0609 | ||
|
|
f5bf1de995 | ||
|
|
6f9ac81ae9 | ||
|
|
c947326c4a | ||
|
|
9b1a5dc878 | ||
|
|
4bc50a0a12 | ||
|
|
26532df53f | ||
|
|
0b8d92332a | ||
|
|
0cf3369f9f | ||
|
|
8f28138f6e | ||
|
|
c0d0df8550 | ||
|
|
67a6300cc4 | ||
|
|
fd72878261 | ||
|
|
9df68a3879 | ||
|
|
bd8c790e2e | ||
|
|
5c3b0101a2 | ||
|
|
fed06f2292 | ||
|
|
2edc274601 | ||
|
|
f68e18d159 | ||
|
|
66a18f91c0 | ||
|
|
4c4629d5fd | ||
|
|
89796adf9c | ||
|
|
11b61660d2 | ||
|
|
d214692a28 | ||
|
|
eec270dc08 | ||
|
|
34d3a97939 | ||
|
|
1f93e78598 | ||
|
|
c3c52cf7b0 | ||
|
|
b11d2bb62d | ||
|
|
96d7deb99b | ||
|
|
e0a4741204 | ||
|
|
0ceae7a885 | ||
|
|
e19d125606 | ||
|
|
9b324cef64 | ||
|
|
68432b7ed1 | ||
|
|
f1f3820560 | ||
|
|
363cf0a6f1 | ||
|
|
508b6fc60d | ||
|
|
75f3cb9d07 | ||
|
|
31ec149e21 | ||
|
|
6076256c3f | ||
|
|
77e9a375ff | ||
|
|
25f7d3b86e | ||
|
|
464153fecd | ||
|
|
139a16f600 | ||
|
|
600487a9d6 | ||
|
|
a2962cc586 | ||
|
|
d6ae741f7f | ||
|
|
48e3873f19 | ||
|
|
57a42f683c | ||
|
|
b2e1bb03b1 | ||
|
|
d8785b8358 | ||
|
|
7de7029fa5 | ||
|
|
47620e4ba8 | ||
|
|
f290d19b27 | ||
|
|
1446838d71 | ||
|
|
8c8c1a6415 | ||
|
|
07f3d3e393 | ||
|
|
1e5db76cc1 | ||
|
|
85d1666247 | ||
|
|
bf0a1dc6c5 | ||
|
|
31e1e2a8c4 | ||
|
|
8f4ed81159 | ||
|
|
966906b7ae | ||
|
|
20e8eaedc8 | ||
|
|
d65776f03f | ||
|
|
7b6eaf23e9 | ||
|
|
bf33e5524b | ||
|
|
2ee0bbf7fb | ||
|
|
23c3438aee | ||
|
|
21124cf6ab | ||
|
|
1694cf05a6 | ||
|
|
8e39be1340 | ||
|
|
4110638cdd | ||
|
|
65bd912b77 | ||
|
|
dd879c794d | ||
|
|
e68b3d0183 | ||
|
|
1481e6f3da | ||
|
|
42c2792287 | ||
|
|
08826b79fe | ||
|
|
d5617720bb | ||
|
|
e95143affd | ||
|
|
a67b58390b | ||
|
|
ced0d271ff | ||
|
|
b6f5ea3c8f | ||
|
|
38e85a2dbe | ||
|
|
680d1a1513 | ||
|
|
f2718ded6d | ||
|
|
221b47806c | ||
|
|
286034431c | ||
|
|
c1ce97106f | ||
|
|
c8212c36e9 | ||
|
|
964477ea36 | ||
|
|
88fc841203 | ||
|
|
04633c731b | ||
|
|
75a582f357 | ||
|
|
b28ae0fbb5 | ||
|
|
6c2c1397ff | ||
|
|
73124928ba | ||
|
|
cc2f6f6a7d | ||
|
|
bf285438a2 | ||
|
|
844c8c3016 | ||
|
|
16dc425318 | ||
|
|
7a41668df0 | ||
|
|
9c058fa5d4 | ||
|
|
6c2f2fec8a | ||
|
|
0cb6ad07c6 | ||
|
|
ef99853da4 | ||
|
|
cb9a441bb9 | ||
|
|
bf46c5018d | ||
|
|
3619c13393 | ||
|
|
e577cd8cf8 | ||
|
|
f05e229780 | ||
|
|
ff29c56ea4 | ||
|
|
5cae882ff3 | ||
|
|
0592038cf9 | ||
|
|
5207d2fe71 | ||
|
|
fab681eb11 | ||
|
|
01e94e53ed | ||
|
|
7f038e4db7 | ||
|
|
e5320ae0d5 | ||
|
|
8290f077d2 | ||
|
|
eccf18644f | ||
|
|
e4b872fc07 | ||
|
|
df9f4ed74f | ||
|
|
8445a00210 | ||
|
|
345d7cf628 | ||
|
|
b300fecc27 | ||
|
|
482ab2e9dc | ||
|
|
751453253c | ||
|
|
7b7647f1ab | ||
|
|
fa88074963 | ||
|
|
d418226edb | ||
|
|
bdfafd3539 | ||
|
|
819b87f1df | ||
|
|
b36880503c | ||
|
|
3c2b67a4d3 | ||
|
|
08c3a9b76b | ||
|
|
dd519c7dac | ||
|
|
f67a341fce | ||
|
|
c755ef0815 | ||
|
|
be577d6027 | ||
|
|
99d3f3c9f3 | ||
|
|
0b3a8804eb | ||
|
|
92a9b04a12 | ||
|
|
a4532de5a0 | ||
|
|
710ec0ef20 | ||
|
|
b4024d86d1 | ||
|
|
58f5175075 | ||
|
|
0789d80b7a | ||
|
|
5aee84a3f3 | ||
|
|
e52789c557 | ||
|
|
c0e9c99a1c | ||
|
|
67cfc8e178 | ||
|
|
47115ff565 | ||
|
|
dca8fae05f | ||
|
|
5512629c55 | ||
|
|
cb6e9135f2 | ||
|
|
af7e16b8e4 | ||
|
|
63e94b434f | ||
|
|
41a668a515 | ||
|
|
20619d8334 | ||
|
|
d0a8ae5cf7 | ||
|
|
7f43feafd5 | ||
|
|
2b502a4b2b | ||
|
|
f95100b44a | ||
|
|
0d4e358f5e | ||
|
|
5f7157f3a2 | ||
|
|
7cde8a22a1 | ||
|
|
535895e577 | ||
|
|
366828918a | ||
|
|
7e85a50a46 | ||
|
|
0e5bc322f1 | ||
|
|
1195cdbd77 | ||
|
|
5330c4e5d3 | ||
|
|
52799e58d6 | ||
|
|
46d0e89d6e | ||
|
|
c9bd1f3334 | ||
|
|
6d990b9c83 | ||
|
|
84f95a3ef4 | ||
|
|
3a20c7912b | ||
|
|
008944a5c3 | ||
|
|
e0c7416333 | ||
|
|
7a4ad0872e | ||
|
|
7f12c0adfa | ||
|
|
885379e2cc | ||
|
|
76d0eb32fc | ||
|
|
76f6131b81 | ||
|
|
1438a1b7f7 | ||
|
|
5789574f89 | ||
|
|
f705798ed7 | ||
|
|
024bab4116 | ||
|
|
8e26969a34 | ||
|
|
ee742713d1 | ||
|
|
00f3aef9ac | ||
|
|
54a8b02774 | ||
|
|
d243959c21 | ||
|
|
dba0cd17dc | ||
|
|
f816bb2a60 |
@@ -17,8 +17,10 @@
|
||||
*/tclsh*
|
||||
*/tcltest*
|
||||
*/versions.vc
|
||||
unix/autoMkindex.tcl
|
||||
unix/dltest.marker
|
||||
unix/tcl.pc
|
||||
unix/tclIndex
|
||||
unix/pkgs/*
|
||||
win/pkgs/*
|
||||
win/tcl.hpj
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ retrieve the stack trace when script evaluation returns
|
||||
\fBTCL_ERROR\fR, like so:
|
||||
.PP
|
||||
.CS
|
||||
int code = Tcl_Eval(interp, script);
|
||||
int code = Tcl_EvalEx(interp, script, -1, 0);
|
||||
if (code == TCL_ERROR) {
|
||||
Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(interp, code);
|
||||
Tcl_Obj *key = Tcl_NewStringObj("-errorinfo", -1);
|
||||
|
||||
+23
-8
@@ -51,27 +51,42 @@ in the interpreter's result, and nothing is stored at *\fIintPtr\fR
|
||||
or *\fIdoublePtr\fR or *\fIboolPtr\fR.
|
||||
.PP
|
||||
\fBTcl_GetInt\fR expects \fIsrc\fR to consist of a collection
|
||||
of integer digits, optionally signed and optionally preceded by
|
||||
white space. If the first two characters of \fIsrc\fR
|
||||
of integer digits, optionally signed and optionally preceded and
|
||||
followed by white space. If the first two characters of \fIsrc\fR
|
||||
after the optional white space and sign are
|
||||
.QW 0x
|
||||
.QW \fB0x\fR
|
||||
then \fIsrc\fR is expected to be in hexadecimal form; otherwise,
|
||||
if the first such characters are
|
||||
.QW \fB0o\fR
|
||||
then \fIsrc\fR is expected to be in octal form; otherwise,
|
||||
if the first such characters are
|
||||
.QW \fB0b\fR
|
||||
then \fIsrc\fR is expected to be in binary form; otherwise,
|
||||
if the first such character is
|
||||
.QW 0
|
||||
.QW \fB0\fR
|
||||
then \fIsrc\fR
|
||||
is expected to be in octal form; otherwise, \fIsrc\fR is
|
||||
expected to be in decimal form.
|
||||
.PP
|
||||
\fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point
|
||||
number, which is: white space; a sign; a sequence of digits; a
|
||||
decimal point; a sequence of digits; the letter
|
||||
.QW e ;
|
||||
decimal point
|
||||
.QW \fB.\fR ;
|
||||
a sequence of digits; the letter
|
||||
.QW \fBe\fR ;
|
||||
a signed decimal exponent; and more white space.
|
||||
Any of the fields may be omitted, except that
|
||||
the digits either before or after the decimal point must be present
|
||||
and if the
|
||||
.QW e
|
||||
is present then it must be followed by the exponent number.
|
||||
.QW \fBe\fR
|
||||
is present then it must be followed by the exponent number. If there
|
||||
are no fields apart from the sign and initial sequence of digits
|
||||
(i.e., no decimal point or exponent indicator), that
|
||||
initial sequence of digits should take one of the forms that
|
||||
\fBTcl_GetInt\fR supports, described above. The use of
|
||||
.QW \fB,\fR
|
||||
as a decimal point is not supported nor should any other sort of
|
||||
inter-digit separator be present.
|
||||
.PP
|
||||
\fBTcl_GetBoolean\fR expects \fIsrc\fR to specify a boolean
|
||||
value. If \fIsrc\fR is any of \fB0\fR, \fBfalse\fR,
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ The \fIhashKeyProc\fR member contains the address of a function called to
|
||||
calculate a hash value for the key.
|
||||
.PP
|
||||
.CS
|
||||
typedef unsigned int \fBTcl_HashKeyProc\fR(
|
||||
typedef TCL_HASH_TYPE \fBTcl_HashKeyProc\fR(
|
||||
Tcl_HashTable *\fItablePtr\fR,
|
||||
void *\fIkeyPtr\fR);
|
||||
.CE
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ The source interpreter will have its result reset by this operation.
|
||||
.SH "DEPRECATED INTERFACES"
|
||||
.SS "OLD STRING PROCEDURES"
|
||||
.PP
|
||||
Use of the following procedures (is deprecated
|
||||
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 a value
|
||||
|
||||
+20
-6
@@ -287,12 +287,14 @@ slow destinations like network sockets.
|
||||
.RS
|
||||
.PP
|
||||
The \fBchan copy\fR command transfers data from \fIinputChan\fR until
|
||||
end of file or \fIsize\fR bytes have been transferred. If no
|
||||
\fB\-size\fR argument is given, then the copy goes until end of file.
|
||||
All the data read from \fIinputChan\fR is copied to \fIoutputChan\fR.
|
||||
Without the \fB\-command\fR option, \fBchan copy\fR blocks until the
|
||||
copy is complete and returns the number of bytes written to
|
||||
\fIoutputChan\fR.
|
||||
end of file or \fIsize\fR bytes or characters have been transferred;
|
||||
\fIsize\fR is in bytes if the two channels are using the same encoding,
|
||||
and is in characters otherwise. If no \fB\-size\fR argument is given,
|
||||
then the copy goes until end of file. All the data read from
|
||||
\fIinputChan\fR is copied to \fIoutputChan\fR. Without the
|
||||
\fB\-command\fR option, \fBchan copy\fR blocks until the copy is
|
||||
complete and returns the number of bytes or characters (using the same
|
||||
rules as for the \fB\-size\fR option) written to \fIoutputChan\fR.
|
||||
.PP
|
||||
The \fB\-command\fR argument makes \fBchan copy\fR work in the
|
||||
background. In this case it returns immediately and the
|
||||
@@ -547,6 +549,18 @@ this, spawn with "2>@" or
|
||||
">@" redirection operators onto the write side of a pipe, and then
|
||||
immediately close it in the parent. This is necessary to get an EOF on
|
||||
the read side once the child has exited or otherwise closed its output.
|
||||
.RS
|
||||
.PP
|
||||
Note that the pipe buffering semantics can vary at the operating system level
|
||||
substantially; it is not safe to assume that a write performed on the output
|
||||
side of the pipe will appear instantly to the input side. This is a
|
||||
fundamental difference and Tcl cannot conceal it. The overall stream semantics
|
||||
\fIare\fR compatible, so blocking reads and writes will not see most of the
|
||||
differences, but the details of what exactly gets written when are not. This
|
||||
is most likely to show up when using pipelines for testing; care should be
|
||||
taken to ensure that deadlocks do not occur and that potential short reads are
|
||||
allowed for.
|
||||
.RE
|
||||
.VE 8.6
|
||||
.TP
|
||||
\fBchan pop \fIchannelId\fR
|
||||
|
||||
@@ -20,6 +20,7 @@ This command joins each of its arguments together with spaces after
|
||||
trimming leading and trailing white-space from each of them. If all of the
|
||||
arguments are lists, this has the same effect as concatenating them
|
||||
into a single list.
|
||||
Arguments that are empty (after trimming) are ignored entirely.
|
||||
It permits any number of arguments;
|
||||
if no \fIarg\fRs are supplied, the result is an empty string.
|
||||
.SH EXAMPLES
|
||||
|
||||
+3
-2
@@ -271,8 +271,9 @@ limitation as \fBexec\fR wants to communicate over pipes. The Expect
|
||||
extension addresses this issue when communicating with a TUI application.
|
||||
.PP
|
||||
When attempting to execute an application, \fBexec\fR first searches for
|
||||
the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
|
||||
\fB.bat\fR are appended to the end of the specified name and it searches
|
||||
the name as it was specified. Then, in order,
|
||||
\fB.com\fR, \fB.exe\fR, \fB.bat\fR and \fB.cmd\fR
|
||||
are appended to the end of the specified name and it searches
|
||||
for the longer name. If a directory name was not specified as part of the
|
||||
application name, the following directories are automatically searched in
|
||||
order when attempting to locate the application:
|
||||
|
||||
+171
-214
@@ -17,14 +17,14 @@ expr \- Evaluate an expression
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Concatenates \fIarg\fRs (adding separator spaces between them),
|
||||
evaluates the result as a Tcl expression, and returns the value.
|
||||
The operators permitted in Tcl expressions include a subset of
|
||||
Concatenates \fIarg\fRs, separated by a space, into an expression, and evaluates
|
||||
that expression, returning its value.
|
||||
The operators permitted in an expression include a subset of
|
||||
the operators permitted in C expressions. For those operators
|
||||
common to both Tcl and C, Tcl applies the same meaning and precedence
|
||||
as the corresponding C operators.
|
||||
Expressions almost always yield numeric results
|
||||
(integer or floating-point values).
|
||||
The value of an expression is often a numeric result, either an integer or a
|
||||
floating-point value, but may also be a non-numeric value.
|
||||
For example, the expression
|
||||
.PP
|
||||
.CS
|
||||
@@ -32,78 +32,68 @@ For example, the expression
|
||||
.CE
|
||||
.PP
|
||||
evaluates to 14.2.
|
||||
Tcl expressions differ from C expressions in the way that
|
||||
operands are specified. Also, Tcl expressions support
|
||||
non-numeric operands and string comparisons, as well as some
|
||||
Expressions differ from C expressions in the way that
|
||||
operands are specified. Expressions also support
|
||||
non-numeric operands, string comparisons, and some
|
||||
additional operators not found in C.
|
||||
.PP
|
||||
When an expression evaluates to an integer, the value is the decimal form of
|
||||
the integer, and when an expression evaluates to a floating-point number, the
|
||||
value is the form produced by the \fB%g\fR format specifier of Tcl's
|
||||
\fBformat\fR command.
|
||||
.SS OPERANDS
|
||||
.PP
|
||||
A Tcl expression consists of a combination of operands, operators,
|
||||
parentheses and commas.
|
||||
White space may be used between the operands and operators and
|
||||
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
|
||||
(if the first two characters of the operand are \fB0o\fR), or in hexadecimal
|
||||
(if the first two characters of the operand are \fB0x\fR). For
|
||||
compatibility with older Tcl releases, an octal integer value is also
|
||||
indicated simply when the first character of the operand is \fB0\fR,
|
||||
whether or not the second character is also \fBo\fR.
|
||||
If an operand does not have one of the integer formats given
|
||||
above, then it is treated as a floating-point number if that is
|
||||
possible. Floating-point numbers may be specified in any of several
|
||||
common formats making use of the decimal digits, the decimal point \fB.\fR,
|
||||
the characters \fBe\fR or \fBE\fR indicating scientific notation, and
|
||||
the sign characters \fB+\fR or \fB\-\fR. For example, all of the
|
||||
following are valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16.
|
||||
Also recognized as floating point values are the strings \fBInf\fR
|
||||
and \fBNaN\fR making use of any case for each character.
|
||||
If no numeric interpretation is possible (note that all literal
|
||||
operands that are not numeric or boolean must be quoted with either
|
||||
braces or with double quotes), then an operand is left as a string
|
||||
(and only a limited set of operators may be applied to it).
|
||||
An expression consists of a combination of operands, operators, parentheses and
|
||||
commas, possibly with whitespace between any of these elements, which is
|
||||
ignored.
|
||||
An integer operand may be specified in decimal, binary
|
||||
(the first two characters are \fB0b\fR), octal
|
||||
(the first two characters are \fB0o\fR), or hexadecimal
|
||||
(the first two characters are \fB0x\fR) form. For
|
||||
compatibility with older Tcl releases, an operand that begins with \fB0\fR is
|
||||
interpreted as an octal integer even if the second character is not \fBo\fR.
|
||||
A floating-point number may be specified in any of several
|
||||
common decimal formats, and may use the decimal point \fB.\fR,
|
||||
\fBe\fR or \fBE\fR for scientific notation, and
|
||||
the sign characters \fB+\fR and \fB\-\fR. The
|
||||
following are all valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16.
|
||||
The strings \fBInf\fR
|
||||
and \fBNaN\fR, in any combination of case, are also recognized as floating point
|
||||
values. An operand that doesn't have a numeric interpretation must be quoted
|
||||
with either braces or with double quotes.
|
||||
.PP
|
||||
Operands may be specified in any of the following ways:
|
||||
An operand may be specified in any of the following ways:
|
||||
.IP [1]
|
||||
As a numeric value, either integer or floating-point.
|
||||
.IP [2]
|
||||
As a boolean value, using any form understood by \fBstring is\fR
|
||||
\fBboolean\fR.
|
||||
.IP [3]
|
||||
As a Tcl variable, using standard \fB$\fR notation.
|
||||
The variable's value will be used as the operand.
|
||||
As a variable, using standard \fB$\fR notation.
|
||||
The value of the variable is then the value of the operand.
|
||||
.IP [4]
|
||||
As a string enclosed in double-quotes.
|
||||
The expression parser will perform backslash, variable, and
|
||||
command substitutions on the information between the quotes,
|
||||
and use the resulting value as the operand
|
||||
Backslash, variable, and command substitution are performed as described in
|
||||
\fBTcl\fR.
|
||||
.IP [5]
|
||||
As a string enclosed in braces.
|
||||
The characters between the open brace and matching close brace
|
||||
will be used as the operand without any substitutions.
|
||||
The operand is treated as a braced value as described in \fBTcl\fR.
|
||||
.IP [6]
|
||||
As a Tcl command enclosed in brackets.
|
||||
The command will be executed and its result will be used as
|
||||
the operand.
|
||||
Command substitution is performed as described in \fBTcl\fR.
|
||||
.IP [7]
|
||||
As a mathematical function whose arguments have any of the above
|
||||
forms for operands, such as \fBsin($x)\fR. See \fBMATH FUNCTIONS\fR below for
|
||||
As a mathematical function such as \fBsin($x)\fR, whose arguments have any of the above
|
||||
forms for operands. See \fBMATH FUNCTIONS\fR below for
|
||||
a discussion of how mathematical functions are handled.
|
||||
.PP
|
||||
Where the above substitutions occur (e.g. inside quoted strings), they
|
||||
are performed by the expression's instructions.
|
||||
However, the command parser may already have performed one round of
|
||||
substitution before the expression processor was called.
|
||||
As discussed below, it is usually best to enclose expressions
|
||||
in braces to prevent the command parser from performing substitutions
|
||||
on the contents.
|
||||
Because \fBexpr\fR parses and performs substitutions on values that have
|
||||
already been parsed and substituted by \fBTcl\fR, it is usually best to enclose
|
||||
expressions in braces to avoid the first round of substitutions by
|
||||
\fBTcl\fR.
|
||||
.PP
|
||||
For some examples of simple expressions, suppose the variable
|
||||
\fBa\fR has the value 3 and
|
||||
the variable \fBb\fR has the value 6.
|
||||
Then the command on the left side of each of the lines below
|
||||
will produce the value on the right side of the line:
|
||||
Below are some examples of simple expressions where the value of \fBa\fR is 3
|
||||
and the value of \fBb\fR is 6. The command on the left side of each line
|
||||
produces the value on the right side.
|
||||
.PP
|
||||
.CS
|
||||
.ta 6c
|
||||
@@ -114,34 +104,41 @@ will produce the value on the right side of the line:
|
||||
.CE
|
||||
.SS OPERATORS
|
||||
.PP
|
||||
The valid operators (most of which are also available as commands in
|
||||
the \fBtcl::mathop\fR namespace; see the \fBmathop\fR(n) manual page
|
||||
for details) are listed below, grouped in decreasing order of precedence:
|
||||
For operators having both a numeric mode and a string mode, the numeric mode is
|
||||
chosen when all operands have a numeric interpretation. The integer
|
||||
interpretation of an operand is preferred over the floating-point
|
||||
interpretation. To ensure string operations on arbitrary values it is generally a
|
||||
good idea to use \fBeq\fR, \fBne\fR, or the \fBstring\fR command instead of
|
||||
more versatile operators such as \fB==\fR.
|
||||
.PP
|
||||
Unless otherwise specified, operators accept non-numeric operands. The value
|
||||
of a boolean operation is 1 if true, 0 otherwise. See also \fBstring is\fR
|
||||
\fBboolean\fR. The valid operators, most of which are also available as
|
||||
commands in the \fBtcl::mathop\fR namespace (see \fBmathop\fR(n)), are listed
|
||||
below, grouped in decreasing order of precedence:
|
||||
.TP 20
|
||||
\fB\-\0\0+\0\0~\0\0!\fR
|
||||
.
|
||||
Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operators
|
||||
may be applied to string operands, and bit-wise NOT may be
|
||||
applied only to integers.
|
||||
Unary minus, unary plus, bit-wise NOT, logical NOT. These operators
|
||||
may only be applied to numeric operands, and bit-wise NOT may only be
|
||||
applied to integers.
|
||||
.TP 20
|
||||
\fB**\fR
|
||||
.
|
||||
Exponentiation. Valid for any numeric operands.
|
||||
Exponentiation. Valid for numeric operands.
|
||||
.TP 20
|
||||
\fB*\0\0/\0\0%\fR
|
||||
.
|
||||
Multiply, divide, remainder. None of these operators may be
|
||||
applied to string operands, and remainder may be applied only
|
||||
to integers.
|
||||
The remainder will always have the same sign as the divisor and
|
||||
an absolute value smaller than the absolute value of the divisor.
|
||||
Multiply and divide, which are valid for numeric operands, and remainder, which
|
||||
is valid for integers. The remainder, an absolute value smaller than the
|
||||
absolute value of the divisor, has the same sign as the divisor.
|
||||
.RS
|
||||
.PP
|
||||
When applied to integers, the division and remainder operators can be
|
||||
considered to partition the number line into a sequence of equal-sized
|
||||
adjacent non-overlapping pieces where each piece is the size of the divisor;
|
||||
the division result identifies which piece the divisor lay within, and the
|
||||
remainder result identifies where within that piece the divisor lay. A
|
||||
When applied to integers, division and remainder can be
|
||||
considered to partition the number line into a sequence of
|
||||
adjacent non-overlapping pieces, where each piece is the size of the divisor;
|
||||
the quotient identifies which piece the dividend lies within, and the
|
||||
remainder identifies where within that piece the dividend lies. A
|
||||
consequence of this is that the result of
|
||||
.QW "-57 \fB/\fR 10"
|
||||
is always -6, and the result of
|
||||
@@ -151,177 +148,157 @@ is always 3.
|
||||
.TP 20
|
||||
\fB+\0\0\-\fR
|
||||
.
|
||||
Add and subtract. Valid for any numeric operands.
|
||||
Add and subtract. Valid for numeric operands.
|
||||
.TP 20
|
||||
\fB<<\0\0>>\fR
|
||||
.
|
||||
Left and right shift. Valid for integer operands only.
|
||||
Left and right shift. Valid for integers.
|
||||
A right shift always propagates the sign bit.
|
||||
.TP 20
|
||||
\fB<\0\0>\0\0<=\0\0>=\fR
|
||||
.
|
||||
Boolean less, greater, less than or equal, and greater than or equal.
|
||||
Each operator produces 1 if the condition is true, 0 otherwise.
|
||||
These operators may be applied to strings as well as numeric operands,
|
||||
in which case string comparison is used.
|
||||
Boolean less than, greater than, less than or equal, and greater than or equal.
|
||||
.TP 20
|
||||
\fB==\0\0!=\fR
|
||||
.
|
||||
Boolean equal and not equal. Each operator produces a zero/one result.
|
||||
Valid for all operand types.
|
||||
Boolean equal and not equal.
|
||||
.TP 20
|
||||
\fBeq\0\0ne\fR
|
||||
.
|
||||
Boolean string equal and string not equal. Each operator produces a
|
||||
zero/one result. The operand types are interpreted only as strings.
|
||||
Boolean string equal and string not equal.
|
||||
.TP 20
|
||||
\fBin\0\0ni\fR
|
||||
.
|
||||
List containment and negated list containment. Each operator produces
|
||||
a zero/one result and treats its first argument as a string and its
|
||||
second argument as a Tcl list. The \fBin\fR operator indicates
|
||||
whether the first argument is a member of the second argument list;
|
||||
the \fBni\fR operator inverts the sense of the result.
|
||||
List containment and negated list containment. The first argument is
|
||||
interpreted as a string, the second as a list. \fBin\fR tests for membership
|
||||
in the list, and \fBni\fR is the inverse.
|
||||
.TP 20
|
||||
\fB&\fR
|
||||
.
|
||||
Bit-wise AND. Valid for integer operands only.
|
||||
Bit-wise AND. Valid for integer operands.
|
||||
.TP 20
|
||||
\fB^\fR
|
||||
.
|
||||
Bit-wise exclusive OR. Valid for integer operands only.
|
||||
Bit-wise exclusive OR. Valid for integer operands.
|
||||
.TP 20
|
||||
\fB|\fR
|
||||
.
|
||||
Bit-wise OR. Valid for integer operands only.
|
||||
Bit-wise OR. Valid for integer operands.
|
||||
.TP 20
|
||||
\fB&&\fR
|
||||
.
|
||||
Logical AND. Produces a 1 result if both operands are non-zero,
|
||||
0 otherwise.
|
||||
Valid for boolean and numeric (integers or floating-point) operands only.
|
||||
Logical AND. If both operands are true, the result is 1, or 0 otherwise.
|
||||
|
||||
.TP 20
|
||||
\fB||\fR
|
||||
.
|
||||
Logical OR. Produces a 0 result if both operands are zero, 1 otherwise.
|
||||
Valid for boolean and numeric (integers or floating-point) operands only.
|
||||
Logical OR. If both operands are false, the result is 0, or 1 otherwise.
|
||||
.TP 20
|
||||
\fIx\fB?\fIy\fB:\fIz\fR
|
||||
.
|
||||
If-then-else, as in C. If \fIx\fR
|
||||
evaluates to non-zero, then the result is the value of \fIy\fR.
|
||||
Otherwise the result is the value of \fIz\fR.
|
||||
The \fIx\fR operand must have a boolean or numeric value.
|
||||
If-then-else, as in C. If \fIx\fR is false , the result is the value of
|
||||
\fIy\fR. Otherwise the result is the value of \fIz\fR.
|
||||
.PP
|
||||
See the C manual for more details on the results
|
||||
produced by each operator.
|
||||
The exponentiation operator promotes types like the multiply and
|
||||
divide operators, and produces a result that is the same as the output
|
||||
of the \fBpow\fR function (after any type conversions.)
|
||||
All of the binary operators but exponentiation group left-to-right
|
||||
within the same precedence level; exponentiation groups right-to-left. For example, the command
|
||||
The exponentiation operator promotes types in the same way that the multiply
|
||||
and divide operators do, and the result is is the same as the result of
|
||||
\fBpow\fR.
|
||||
Exponentiation groups right-to-left within a precedence level. Other binary
|
||||
operators group left-to-right. For example, the value of
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {4*2 < 7}
|
||||
.CE
|
||||
.PP
|
||||
returns 0, while
|
||||
is 0, while the value of
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {2**3**2}
|
||||
.CE
|
||||
.PP
|
||||
returns 512.
|
||||
is 512.
|
||||
.PP
|
||||
The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have
|
||||
As in C, \fB&&\fR, \fB||\fR, and \fB?:\fR feature
|
||||
.QW "lazy evaluation" ,
|
||||
just as in C, which means that operands are not evaluated if they are
|
||||
not needed to determine the outcome. For example, in the command
|
||||
which means that operands are not evaluated if they are
|
||||
not needed to determine the outcome. For example, in
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {$v ? [a] : [b]}
|
||||
.CE
|
||||
.PP
|
||||
only one of
|
||||
.QW \fB[a]\fR
|
||||
or
|
||||
.QW \fB[b]\fR
|
||||
will actually be evaluated,
|
||||
depending on the value of \fB$v\fR. Note, however, that this is
|
||||
only true if the entire expression is enclosed in braces; otherwise
|
||||
the Tcl parser will evaluate both
|
||||
.QW \fB[a]\fR
|
||||
and
|
||||
.QW \fB[b]\fR
|
||||
before invoking the \fBexpr\fR command.
|
||||
only one of \fB[a]\fR or \fB[b]\fR is evaluated,
|
||||
depending on the value of \fB$v\fR. This is not true of the normal Tcl parser,
|
||||
so it is normally recommended to enclose the arguments to \fBexpr\fR in braces.
|
||||
Without braces, as in
|
||||
\fBexpr\fR $v ? [a] : [b]
|
||||
both \fB[a]\fR and \fB[b]\fR are evaluated before \fBexpr\fR is even called.
|
||||
.PP
|
||||
For more details on the results
|
||||
produced by each operator, see the documentation for C.
|
||||
.SS "MATH FUNCTIONS"
|
||||
.PP
|
||||
When the expression parser encounters a mathematical function
|
||||
such as \fBsin($x)\fR, it replaces it with a call to an ordinary
|
||||
Tcl function in the \fBtcl::mathfunc\fR namespace. The processing
|
||||
of an expression such as:
|
||||
A mathematical function such as \fBsin($x)\fR is replaced with a call to an ordinary
|
||||
Tcl command in the \fBtcl::mathfunc\fR namespace. The evaluation
|
||||
of an expression such as
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {sin($x+$y)}
|
||||
.CE
|
||||
.PP
|
||||
is the same in every way as the processing of:
|
||||
is the same in every way as the evaluation of
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]}
|
||||
.CE
|
||||
.PP
|
||||
which in turn is the same as the processing of:
|
||||
which in turn is the same as the evaluation of
|
||||
.PP
|
||||
.CS
|
||||
tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]
|
||||
.CE
|
||||
.PP
|
||||
The executor will search for \fBtcl::mathfunc::sin\fR using the usual
|
||||
rules for resolving functions in namespaces. Either
|
||||
\fB::tcl::mathfunc::sin\fR or \fB[namespace
|
||||
current]::tcl::mathfunc::sin\fR will satisfy the request, and others
|
||||
may as well (depending on the current \fBnamespace path\fR setting).
|
||||
\fBtcl::mathfunc::sin\fR is resolved as described in
|
||||
\fBNAMESPACE RESOLUTION\fR in the \fBnamespace\fR(n) documentation. Given the
|
||||
default value of \fBnamespace path\fR, \fB[namespace
|
||||
current]::tcl::mathfunc::sin\fR or \fB::tcl::mathfunc::sin\fR are the typical
|
||||
resolutions.
|
||||
.PP
|
||||
Some mathematical functions have several arguments, separated by commas like in C. Thus:
|
||||
As in C, a mathematical function may accept multiple arguments separated by commas. Thus,
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {hypot($x,$y)}
|
||||
.CE
|
||||
.PP
|
||||
ends up as
|
||||
becomes
|
||||
.PP
|
||||
.CS
|
||||
tcl::mathfunc::hypot $x $y
|
||||
.CE
|
||||
.PP
|
||||
See the \fBmathfunc\fR(n) manual page for the math functions that are
|
||||
See the \fBmathfunc\fR(n) documentation for the math functions that are
|
||||
available by default.
|
||||
.SS "TYPES, OVERFLOW, AND PRECISION"
|
||||
.PP
|
||||
All internal computations involving integers are done calling on the
|
||||
LibTomMath multiple precision integer library as required so that all
|
||||
integer calculations are performed exactly. Note that in Tcl releases
|
||||
prior to 8.5, integer calculations were performed with one of the C types
|
||||
When needed to guarantee exact performance, internal computations involving
|
||||
integers use the LibTomMath multiple precision integer library. In Tcl releases
|
||||
prior to 8.5, integer calculations were performed using one of the C types
|
||||
\fIlong int\fR or \fITcl_WideInt\fR, causing implicit range truncation
|
||||
in those calculations where values overflowed the range of those types.
|
||||
Any code that relied on these implicit truncations will need to explicitly
|
||||
add \fBint()\fR or \fBwide()\fR function calls to expressions at the points
|
||||
where such truncation is required to take place.
|
||||
Any code that relied on these implicit truncations should instead call
|
||||
\fBint()\fR or \fBwide()\fR, which do truncate.
|
||||
.PP
|
||||
All internal computations involving floating-point are
|
||||
done with the C type \fIdouble\fR.
|
||||
When converting a string to floating-point, exponent overflow is
|
||||
Internal floating-point computations are
|
||||
performed using the \fIdouble\fR C type.
|
||||
When converting a string to floating-point value, exponent overflow is
|
||||
detected and results in the \fIdouble\fR value of \fBInf\fR or
|
||||
\fB\-Inf\fR as appropriate. Floating-point overflow and underflow
|
||||
are detected to the degree supported by the hardware, which is generally
|
||||
pretty reliable.
|
||||
fairly reliable.
|
||||
.PP
|
||||
Conversion among internal representations for integer, floating-point,
|
||||
and string operands is done automatically as needed.
|
||||
For arithmetic computations, integers are used until some
|
||||
floating-point number is introduced, after which floating-point is used.
|
||||
For example,
|
||||
Conversion among internal representations for integer, floating-point, and
|
||||
string operands is done automatically as needed. For arithmetic computations,
|
||||
integers are used until some floating-point number is introduced, after which
|
||||
floating-point values are used. For example,
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {5 / 4}
|
||||
@@ -335,82 +312,62 @@ returns 1, while
|
||||
.CE
|
||||
.PP
|
||||
both return 1.25.
|
||||
Floating-point values are always returned with a
|
||||
A floating-point result can be distinguished from an integer result by the
|
||||
presence of either
|
||||
.QW \fB.\fR
|
||||
or an
|
||||
or
|
||||
.QW \fBe\fR
|
||||
so that they will not look like integer values. For example,
|
||||
.PP
|
||||
. For example,
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {20.0/5.0}
|
||||
.CE
|
||||
.PP
|
||||
returns \fB4.0\fR, not \fB4\fR.
|
||||
.SS "STRING OPERATIONS"
|
||||
.PP
|
||||
String values may be used as operands of the comparison operators,
|
||||
although the expression evaluator tries to do comparisons as integer
|
||||
or floating-point when it can,
|
||||
i.e., when all arguments to the operator allow numeric interpretations,
|
||||
except in the case of the \fBeq\fR and \fBne\fR operators.
|
||||
If one of the operands of a comparison is a string and the other
|
||||
has a numeric value, a canonical string representation of the numeric
|
||||
operand value is generated to compare with the string operand.
|
||||
Canonical string representation for integer values is a decimal string
|
||||
format. Canonical string representation for floating-point values
|
||||
is that produced by the \fB%g\fR format specifier of Tcl's
|
||||
\fBformat\fR command. For example, the commands
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {"0x03" > "2"}
|
||||
\fBexpr\fR {"0y" > "0x12"}
|
||||
.CE
|
||||
.PP
|
||||
both return 1. The first comparison is done using integer
|
||||
comparison, and the second is done using string comparison.
|
||||
Because of Tcl's tendency to treat values as numbers whenever
|
||||
possible, it is not generally a good idea to use operators like \fB==\fR
|
||||
when you really want string comparison and the values of the
|
||||
operands could be arbitrary; it is better in these cases to use
|
||||
the \fBeq\fR or \fBne\fR operators, or the \fBstring\fR command instead.
|
||||
.SH "PERFORMANCE CONSIDERATIONS"
|
||||
.PP
|
||||
Enclose expressions in braces for the best speed and the smallest
|
||||
storage requirements.
|
||||
This allows the Tcl bytecode compiler to generate the best code.
|
||||
.PP
|
||||
As mentioned above, expressions are substituted twice:
|
||||
once by the Tcl parser and once by the \fBexpr\fR command.
|
||||
For example, the commands
|
||||
Where an expression contains syntax that Tcl would otherwise perform
|
||||
substitutions on, enclosing an expression in braces or otherwise quoting it
|
||||
so that it's a static value allows the Tcl compiler to generate bytecode for
|
||||
the expression, resulting in better speed and smaller storage requirements.
|
||||
This also avoids issues that can arise if Tcl is allowed to perform
|
||||
substitution on the value before \fBexpr\fR is called.
|
||||
.PP
|
||||
In the following example, the value of the expression is 11 because the Tcl parser first
|
||||
substitutes \fB$b\fR and \fBexpr\fR then substitutes \fB$a\fR. Enclosing the
|
||||
expression in braces would result in a syntax error.
|
||||
.CS
|
||||
set a 3
|
||||
set b {$a + 2}
|
||||
\fBexpr\fR $b*4
|
||||
.CE
|
||||
.PP
|
||||
return 11, not a multiple of 4.
|
||||
This is because the Tcl parser will first substitute \fB$a + 2\fR for
|
||||
the variable \fBb\fR,
|
||||
then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
|
||||
.PP
|
||||
Most expressions do not require a second round of substitutions.
|
||||
Either they are enclosed in braces or, if not,
|
||||
their variable and command substitutions yield numbers or strings
|
||||
that do not themselves require substitutions.
|
||||
However, because a few unbraced expressions
|
||||
need two rounds of substitutions,
|
||||
the bytecode compiler must emit
|
||||
additional instructions to handle this situation.
|
||||
The most expensive code is required for
|
||||
unbraced expressions that contain command substitutions.
|
||||
These expressions must be implemented by generating new code
|
||||
each time the expression is executed.
|
||||
When the expression is unbraced to allow the substitution of a function or
|
||||
operator, consider using the commands documented in the \fBmathfunc\fR(n) or
|
||||
\fBmathop\fR(n) manual pages directly instead.
|
||||
|
||||
When an expression is generated at runtime, like the one above is, the bytcode
|
||||
compiler must ensure that new code is generated each time the expression
|
||||
is evaluated. This is the most costly kind of expression from a performance
|
||||
perspective. In such cases, consider directly using the commands described in
|
||||
the \fBmathfunc\fR(n) or \fBmathop\fR(n) documentation instead of \fBexpr\fR.
|
||||
|
||||
Most expressions are not formed at runtime, but are literal strings or contain
|
||||
substitutions that don't introduce other substitutions. To allow the bytecode
|
||||
compiler to work with an expression as a string literal at compilation time,
|
||||
ensure that it contains no substitutions or that it is enclosed in braces or
|
||||
otherwise quoted to prevent Tcl from performing substitutions, allowing
|
||||
\fBexpr\fR to perform them instead.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
A numeric comparison whose result is 1:
|
||||
.CS
|
||||
\fBexpr\fR {"0x03" > "2"}
|
||||
.CE
|
||||
.PP
|
||||
A string comparison whose result is 1:
|
||||
.CS
|
||||
\fBexpr\fR {"0y" > "0x12"}
|
||||
.CE
|
||||
.PP
|
||||
Define a procedure that computes an
|
||||
.QW interesting
|
||||
mathematical function:
|
||||
@@ -444,8 +401,8 @@ each other:
|
||||
puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]"
|
||||
.CE
|
||||
.PP
|
||||
Set a variable to whether an environment variable is both defined at
|
||||
all and also set to a true boolean value:
|
||||
Set a variable indicating whether an environment variable is defined and has
|
||||
value of true:
|
||||
.PP
|
||||
.CS
|
||||
set isTrue [\fBexpr\fR {
|
||||
|
||||
+9
-3
@@ -25,12 +25,15 @@ network sockets.
|
||||
.PP
|
||||
The \fBfcopy\fR
|
||||
command transfers data from \fIinchan\fR until end of file
|
||||
or \fIsize\fR bytes have been
|
||||
transferred. If no \fB\-size\fR argument is given,
|
||||
or \fIsize\fR bytes or characters have been
|
||||
transferred; \fIsize\fR is in bytes if the two channels are using the
|
||||
same encoding, and is in characters otherwise.
|
||||
If no \fB\-size\fR argument is given,
|
||||
then the copy goes until end of file.
|
||||
All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
|
||||
Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
|
||||
and returns the number of bytes written to \fIoutchan\fR.
|
||||
and returns the number of bytes or characters (using the same rules as
|
||||
for the \fB\-size\fR option) written to \fIoutchan\fR.
|
||||
.PP
|
||||
The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
|
||||
In this case it returns immediately and the \fIcallback\fR is invoked
|
||||
@@ -174,3 +177,6 @@ vwait done
|
||||
eof(n), fblocked(n), fconfigure(n), file(n)
|
||||
.SH KEYWORDS
|
||||
blocking, channel, end of line, end of file, nonblocking, read, translation
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" End:
|
||||
|
||||
+6
-5
@@ -162,7 +162,9 @@ returns \fB/home\fR (or something similar).
|
||||
\fBfile executable \fIname\fR
|
||||
.
|
||||
Returns \fB1\fR if file \fIname\fR is executable by the current user,
|
||||
\fB0\fR otherwise.
|
||||
\fB0\fR otherwise. On Windows, which does not have an executable attribute,
|
||||
the command treats all directories and any files with extensions
|
||||
\fBexe\fR, \fBcom\fR, \fBcmd\fR or \fBbat\fR as executable.
|
||||
.TP
|
||||
\fBfile exists \fIname\fR
|
||||
.
|
||||
@@ -482,10 +484,9 @@ not the effective ones.
|
||||
.TP
|
||||
\fBWindows\fR\0\0\0\0
|
||||
.
|
||||
The \fBfile owned\fR subcommand currently always reports that the current user
|
||||
is the owner of the file, without regard for what the operating system
|
||||
believes to be true, making an ownership test useless. This issue (#3613671)
|
||||
may be fixed in a future release of Tcl.
|
||||
The \fBfile owned\fR subcommand uses the user identifier (SID) of
|
||||
the process token, not the thread token which may be impersonating
|
||||
some other user.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
This procedure shows how to search for C files in a given directory
|
||||
|
||||
+4
-1
@@ -418,7 +418,10 @@ set token [::http::geturl https://my.secure.site/]
|
||||
\fB::http::unregister\fR \fIproto\fR
|
||||
.
|
||||
This procedure unregisters a protocol handler that was previously
|
||||
registered via \fB::http::register\fR.
|
||||
registered via \fB::http::register\fR, returning a two-item list of
|
||||
the default port and handler command that was previously installed
|
||||
(via \fB::http::register\fR) if there was such a handler, and an error if
|
||||
there was no such handler.
|
||||
.SH ERRORS
|
||||
The \fB::http::geturl\fR procedure will raise errors in the following cases:
|
||||
invalid command line options,
|
||||
|
||||
+23
-5
@@ -34,8 +34,9 @@ one or two fields. If there is only a single field in the specifier
|
||||
then it is the name of the argument; if there are two fields, then
|
||||
the first is the argument name and the second is its default value.
|
||||
Arguments with default values that are followed by non-defaulted
|
||||
arguments become required arguments. In 8.6 this will be considered an
|
||||
error.
|
||||
arguments become required arguments; enough actual arguments must be
|
||||
supplied to allow all arguments up to and including the last required
|
||||
formal argument.
|
||||
.PP
|
||||
When \fIname\fR is invoked a local variable
|
||||
will be created for each of the formal arguments to the procedure; its
|
||||
@@ -48,11 +49,14 @@ actual arguments for all the
|
||||
formal arguments that do not have defaults, and there must not be any extra
|
||||
actual arguments.
|
||||
Arguments with default values that are followed by non-defaulted
|
||||
arguments become required arguments (in 8.6 it will be considered an
|
||||
error).
|
||||
arguments become de-facto required arguments, though this may change
|
||||
in a future version of Tcl; portable code should ensure that all
|
||||
optional arguments come after all required arguments.
|
||||
.PP
|
||||
There is one special case to permit procedures with
|
||||
variable numbers of arguments. If the last formal argument has the name
|
||||
\fBargs\fR, then a call to the procedure may contain more actual arguments
|
||||
.QW \fBargs\fR ,
|
||||
then a call to the procedure may contain more actual arguments
|
||||
than the procedure has formal arguments. In this case, all of the actual arguments
|
||||
starting at the one that would be assigned to \fBargs\fR are combined into
|
||||
a list (as if the \fBlist\fR command had been used); this combined value
|
||||
@@ -80,6 +84,20 @@ If an error occurs while executing the procedure
|
||||
body, then the procedure-as-a-whole will return that same error.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
This is a procedure that takes two arguments and prints both their sum
|
||||
and their product. It also returns the string
|
||||
.QW OK
|
||||
to the caller as an explicit result.
|
||||
.PP
|
||||
.CS
|
||||
\fBproc\fR printSumProduct {x y} {
|
||||
set sum [expr {$x + $y}]
|
||||
set prod [expr {$x * $y}]
|
||||
puts "sum is $sum, product is $prod"
|
||||
return "OK"
|
||||
}
|
||||
.CE
|
||||
.PP
|
||||
This is a procedure that accepts arbitrarily many arguments and prints
|
||||
them out, one by one.
|
||||
.PP
|
||||
|
||||
+1
-3
@@ -123,9 +123,7 @@ with conversion character \fBu\fR.
|
||||
.TP
|
||||
\fBi\fR
|
||||
.
|
||||
The input substring must be an integer. The base (i.e. decimal, binary,
|
||||
octal, or hexadecimal) is determined in the same fashion as described in
|
||||
\fBexpr\fR. The integer value is stored in the variable,
|
||||
The input substring must be an integer. The base (i.e. decimal, octal, or hexadecimal) is determined by the C convention (leading 0 for octal; prefix 0x for hexadecimal). The integer value is stored in the variable,
|
||||
truncated as required by the size modifier value.
|
||||
.TP
|
||||
\fBc\fR
|
||||
|
||||
+12
-2
@@ -872,8 +872,8 @@ harness are doing.
|
||||
.
|
||||
Sets the type of output verbosity desired to \fIlevel\fR,
|
||||
a list of zero or more of the elements \fBbody\fR, \fBpass\fR,
|
||||
\fBskip\fR, \fBstart\fR, \fBerror\fR and \fBline\fR. Default value
|
||||
is
|
||||
\fBskip\fR, \fBstart\fR, \fBerror\fR, \fBline\fR, \fBmsec\fR and \fBusec\fR.
|
||||
Default value is
|
||||
.QW "\fBbody error\fR" .
|
||||
Levels are defined as:
|
||||
.RS
|
||||
@@ -890,6 +890,16 @@ Print errorInfo and errorCode, if they exist, when a test return code
|
||||
does not match its expected return code
|
||||
.IP "line (\fBl\fR)"
|
||||
Print source file line information of failed tests
|
||||
.IP "msec (\fBm\fR)"
|
||||
Print each test's execution time in milliseconds
|
||||
.IP "usec (\fBu\fR)"
|
||||
Print each test's execution time in microseconds
|
||||
.PP
|
||||
Note that the \fBmsec\fR and \fBusec\fR verbosity levels are provided as
|
||||
indicative measures only. They do not tackle the problem of repeatibility which
|
||||
should be considered in performance tests or benchmarks. To use these verbosity
|
||||
levels to thoroughly track performance degradations, consider wrapping your
|
||||
test bodies with \fBtime\fR commands.
|
||||
.PP
|
||||
The single letter abbreviations noted above are also recognized
|
||||
so that
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ tell \- Return current access position for an open channel
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Returns an integer string giving the current access position in
|
||||
Returns an integer giving the current access position in
|
||||
\fIchannelId\fR. This value returned is a byte offset that can be passed to
|
||||
\fBseek\fR in order to set the channel to a particular position. Note
|
||||
that this value is in terms of bytes, not characters like \fBread\fR.
|
||||
|
||||
+6
-1
@@ -45,7 +45,8 @@ linked to the corresponding namespace variables (and therefore these
|
||||
variables are listed by \fBinfo vars\fR.)
|
||||
In this way the \fBvariable\fR command resembles the \fBglobal\fR command,
|
||||
although the \fBglobal\fR command
|
||||
only links to variables in the global namespace.
|
||||
resolves variable names with respect to the global namespace instead
|
||||
of the current namespace of the procedure.
|
||||
If any \fIvalue\fRs are given,
|
||||
they are used to modify the values of the associated namespace variables.
|
||||
If a namespace variable does not exist,
|
||||
@@ -98,3 +99,7 @@ namespace eval foo {
|
||||
global(n), namespace(n), upvar(n)
|
||||
.SH KEYWORDS
|
||||
global, namespace, procedure, variable
|
||||
.\" Local variables:
|
||||
.\" mode: nroff
|
||||
.\" fill-column: 78
|
||||
.\" End:
|
||||
|
||||
+12
-6
@@ -174,7 +174,11 @@ to the \fBzlib push\fR command:
|
||||
.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.
|
||||
work with gzip-format data. The dictionary should consist of strings (byte
|
||||
sequences) that are likely to be encountered later in the data to be compressed,
|
||||
with the most commonly used strings preferably put towards the end of the
|
||||
dictionary. Tcl provides no mechanism for choosing a good such dictionary for
|
||||
a particular data sequence.
|
||||
.VE
|
||||
.TP
|
||||
\fB\-header\fI dictionary\fR
|
||||
@@ -207,11 +211,13 @@ 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.
|
||||
This read-write options gets or sets the initial 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. Note that this cannot be used to get the
|
||||
current active compression dictionary mid-stream, as that information is not
|
||||
exposed by the underlying library.
|
||||
.VE
|
||||
.TP
|
||||
\fB\-flush\fI type\fR
|
||||
|
||||
+202
-191
@@ -140,35 +140,36 @@ static const crange alphaRangeTable[] = {
|
||||
{0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
|
||||
{0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x904, 0x939},
|
||||
{0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, {0x993, 0x9a8},
|
||||
{0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, {0xa05, 0xa0a},
|
||||
{0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, {0xa72, 0xa74},
|
||||
{0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
|
||||
{0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
|
||||
{0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, {0xb8e, 0xb90},
|
||||
{0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xc05, 0xc0c},
|
||||
{0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc58, 0xc5a},
|
||||
{0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
|
||||
{0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a},
|
||||
{0xd5f, 0xd61}, {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1},
|
||||
{0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46},
|
||||
{0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0},
|
||||
{0xec0, 0xec4}, {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c},
|
||||
{0xf88, 0xf8c}, {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d},
|
||||
{0x106e, 0x1070}, {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa},
|
||||
{0x10fc, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d},
|
||||
{0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5},
|
||||
{0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310},
|
||||
{0x1312, 0x1315}, {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5},
|
||||
{0x13f8, 0x13fd}, {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a},
|
||||
{0x16a0, 0x16ea}, {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711},
|
||||
{0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770},
|
||||
{0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8}, {0x18b0, 0x18f5},
|
||||
{0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
|
||||
{0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
|
||||
{0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
|
||||
{0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd},
|
||||
{0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
|
||||
{0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
|
||||
{0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
|
||||
{0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
|
||||
{0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
|
||||
{0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39},
|
||||
{0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
|
||||
{0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f},
|
||||
{0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
|
||||
{0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f},
|
||||
{0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
|
||||
{0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
|
||||
{0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
|
||||
{0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d},
|
||||
{0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
|
||||
{0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
|
||||
{0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
|
||||
{0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c},
|
||||
{0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8},
|
||||
{0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
|
||||
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
|
||||
{0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
|
||||
{0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
|
||||
{0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
|
||||
{0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
|
||||
{0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
|
||||
{0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
|
||||
{0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
|
||||
{0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
|
||||
@@ -183,7 +184,7 @@ static const crange alphaRangeTable[] = {
|
||||
{0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
|
||||
{0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c},
|
||||
{0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5},
|
||||
{0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ad}, {0xa7b0, 0xa7b7},
|
||||
{0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, {0xa7b0, 0xa7b7},
|
||||
{0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822},
|
||||
{0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925},
|
||||
{0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4},
|
||||
@@ -193,6 +194,8 @@ static const crange alphaRangeTable[] = {
|
||||
{0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
|
||||
{0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, {0xac00, 0xd7a3},
|
||||
{0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e},
|
||||
{0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e},
|
||||
{0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, {0xde40, 0xde7e},
|
||||
{0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e},
|
||||
{0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
|
||||
{0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36},
|
||||
@@ -205,36 +208,38 @@ static const crange alphaRangeTable[] = {
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
|
||||
{0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
|
||||
{0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
|
||||
{0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
|
||||
{0x10860, 0x10876}, {0x10880, 0x1089e}, {0x108e0, 0x108f2}, {0x10900, 0x10915},
|
||||
{0x10920, 0x10939}, {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17},
|
||||
{0x10a19, 0x10a33}, {0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7},
|
||||
{0x10ac9, 0x10ae4}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72},
|
||||
{0x10b80, 0x10b91}, {0x10c00, 0x10c48}, {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2},
|
||||
{0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8}, {0x11103, 0x11126},
|
||||
{0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, {0x11200, 0x11211},
|
||||
{0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
|
||||
{0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c}, {0x11313, 0x11328},
|
||||
{0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361}, {0x11480, 0x114af},
|
||||
{0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
|
||||
{0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
|
||||
{0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
|
||||
{0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
|
||||
{0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
|
||||
{0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
|
||||
{0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
|
||||
{0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
|
||||
{0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
|
||||
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
|
||||
{0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
|
||||
{0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
|
||||
{0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x12000, 0x12399},
|
||||
{0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
|
||||
{0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43},
|
||||
{0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
|
||||
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
|
||||
{0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
|
||||
{0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da},
|
||||
{0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
|
||||
{0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
|
||||
{0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f},
|
||||
{0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a},
|
||||
{0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89},
|
||||
{0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb},
|
||||
{0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1},
|
||||
{0x2f800, 0x2fa1d}
|
||||
{0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08},
|
||||
{0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x12000, 0x12399}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
|
||||
{0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, {0x17000, 0x187ec},
|
||||
{0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
|
||||
{0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
|
||||
{0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
|
||||
{0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943},
|
||||
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
|
||||
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
|
||||
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
|
||||
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -249,24 +254,24 @@ static const chr alphaCharTable[] = {
|
||||
0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9,
|
||||
0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83,
|
||||
0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d,
|
||||
0xc60, 0xc61, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2, 0xd3d,
|
||||
0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88,
|
||||
0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3, 0xebd,
|
||||
0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7, 0x10cd,
|
||||
0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf, 0x1cf5,
|
||||
0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102, 0x2107,
|
||||
0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2, 0x2cf3,
|
||||
0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c, 0xa62a,
|
||||
0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0,
|
||||
0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
|
||||
0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87,
|
||||
0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3,
|
||||
0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7,
|
||||
0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf,
|
||||
0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102,
|
||||
0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2,
|
||||
0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c,
|
||||
0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6,
|
||||
0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
|
||||
0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
|
||||
0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x16f50,
|
||||
0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546,
|
||||
0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49,
|
||||
0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f,
|
||||
0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11c40,
|
||||
0x16f50, 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
|
||||
0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
|
||||
0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
|
||||
0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -289,7 +294,7 @@ static const crange controlRangeTable[] = {
|
||||
#define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
|
||||
|
||||
static const chr controlCharTable[] = {
|
||||
0xad, 0x61c, 0x6dd, 0x70f, 0x180e, 0xfeff
|
||||
0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x110bd, 0xe0001
|
||||
#endif
|
||||
@@ -314,9 +319,10 @@ static const crange digitRangeTable[] = {
|
||||
{0xff10, 0xff19}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
|
||||
{0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x114d0, 0x114d9}, {0x11650, 0x11659},
|
||||
{0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69},
|
||||
{0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}
|
||||
{0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
|
||||
{0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
|
||||
{0x11c50, 0x11c59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff},
|
||||
{0x1e950, 0x1e959}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -339,7 +345,7 @@ static const crange punctRangeTable[] = {
|
||||
{0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
|
||||
{0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
|
||||
{0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e42},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e44},
|
||||
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
|
||||
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
|
||||
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
|
||||
@@ -348,9 +354,9 @@ static const crange punctRangeTable[] = {
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
|
||||
{0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
|
||||
{0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x115c1, 0x115d7},
|
||||
{0x11641, 0x11643}, {0x1173c, 0x1173e}, {0x12470, 0x12474}, {0x16b37, 0x16b3b},
|
||||
{0x1da87, 0x1da8b}
|
||||
{0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
|
||||
{0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
|
||||
{0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -371,8 +377,8 @@ static const chr punctCharTable[] = {
|
||||
0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5,
|
||||
0x16b44, 0x1bc9f
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
|
||||
0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -404,24 +410,24 @@ static const crange lowerRangeTable[] = {
|
||||
{0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
|
||||
{0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
|
||||
{0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
|
||||
{0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d},
|
||||
{0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37},
|
||||
{0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d},
|
||||
{0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4},
|
||||
{0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4},
|
||||
{0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25},
|
||||
{0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a},
|
||||
{0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xff41, 0xff5a}
|
||||
{0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a},
|
||||
{0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
|
||||
{0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
|
||||
{0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
|
||||
{0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
|
||||
{0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b},
|
||||
{0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795},
|
||||
{0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06},
|
||||
{0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10428, 0x1044f}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df}, {0x1d41a, 0x1d433},
|
||||
{0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9},
|
||||
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537},
|
||||
{0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607},
|
||||
{0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da},
|
||||
{0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e},
|
||||
{0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2},
|
||||
{0x1d7c4, 0x1d7c9}
|
||||
,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
|
||||
{0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b},
|
||||
{0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503},
|
||||
{0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3},
|
||||
{0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5},
|
||||
{0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b},
|
||||
{0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f},
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -513,15 +519,15 @@ static const crange upperRangeTable[] = {
|
||||
{0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb},
|
||||
{0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d},
|
||||
{0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70},
|
||||
{0x2c7e, 0x2c80}, {0xa7aa, 0xa7ad}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
|
||||
{0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10400, 0x10427}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf}, {0x1d400, 0x1d419},
|
||||
{0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5},
|
||||
{0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c},
|
||||
{0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d56c, 0x1d585},
|
||||
{0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, {0x1d63c, 0x1d655},
|
||||
{0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734},
|
||||
{0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}
|
||||
,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
|
||||
{0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
|
||||
{0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
|
||||
{0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621},
|
||||
{0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa},
|
||||
{0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -610,26 +616,26 @@ static const crange graphRangeTable[] = {
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
|
||||
{0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
|
||||
{0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4},
|
||||
{0x8e3, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0},
|
||||
{0x9b6, 0x9b9}, {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3},
|
||||
{0x9e6, 0x9fb}, {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28},
|
||||
{0xa2a, 0xa30}, {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c},
|
||||
{0xa66, 0xa75}, {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
|
||||
{0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5},
|
||||
{0xac7, 0xac9}, {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1},
|
||||
{0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
|
||||
{0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63},
|
||||
{0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95},
|
||||
{0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8},
|
||||
{0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c},
|
||||
{0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44},
|
||||
{0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63},
|
||||
{0xc66, 0xc6f}, {0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c},
|
||||
{0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
|
||||
{0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
|
||||
{0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e},
|
||||
{0xd5f, 0xd63}, {0xd66, 0xd75}, {0xd79, 0xd7f}, {0xd85, 0xd96},
|
||||
{0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
|
||||
{0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
|
||||
{0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
|
||||
{0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
|
||||
{0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
|
||||
{0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
|
||||
{0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
|
||||
{0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
|
||||
{0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
|
||||
{0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
|
||||
{0xc00, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
|
||||
{0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
|
||||
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc83},
|
||||
{0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
|
||||
{0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
|
||||
{0xce0, 0xce3}, {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c},
|
||||
{0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48},
|
||||
{0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, {0xd85, 0xd96},
|
||||
{0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
|
||||
{0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, {0xe01, 0xe3a},
|
||||
{0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3},
|
||||
@@ -650,25 +656,25 @@ static const crange graphRangeTable[] = {
|
||||
{0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
|
||||
{0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
|
||||
{0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
|
||||
{0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
|
||||
{0x1dfc, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
|
||||
{0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
|
||||
{0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
|
||||
{0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4},
|
||||
{0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4},
|
||||
{0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e},
|
||||
{0x2090, 0x209c}, {0x20a0, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b},
|
||||
{0x2190, 0x23fa}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
|
||||
{0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
|
||||
{0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1},
|
||||
{0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
|
||||
{0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
|
||||
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e42},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44},
|
||||
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d},
|
||||
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
|
||||
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c},
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ad},
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
|
||||
{0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
|
||||
{0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
|
||||
{0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
|
||||
{0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
|
||||
{0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
|
||||
{0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
|
||||
@@ -687,54 +693,59 @@ static const crange graphRangeTable[] = {
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
{0x10137, 0x1018c}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
{0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
{0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
|
||||
{0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
|
||||
{0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
|
||||
{0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af},
|
||||
{0x108e0, 0x108f2}, {0x108fb, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7},
|
||||
{0x109bc, 0x109cf}, {0x109d2, 0x10a03}, {0x10a0c, 0x10a13}, {0x10a15, 0x10a17},
|
||||
{0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, {0x10a3f, 0x10a47}, {0x10a50, 0x10a58},
|
||||
{0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, {0x10aeb, 0x10af6}, {0x10b00, 0x10b35},
|
||||
{0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b91}, {0x10b99, 0x10b9c},
|
||||
{0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2},
|
||||
{0x10cfa, 0x10cff}, {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f},
|
||||
{0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9},
|
||||
{0x11100, 0x11134}, {0x11136, 0x11143}, {0x11150, 0x11176}, {0x11180, 0x111cd},
|
||||
{0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211}, {0x11213, 0x1123d},
|
||||
{0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a9},
|
||||
{0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303}, {0x11305, 0x1130c},
|
||||
{0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1133c, 0x11344},
|
||||
{0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c}, {0x11370, 0x11374},
|
||||
{0x11480, 0x114c7}, {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd},
|
||||
{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
|
||||
{0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
|
||||
{0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
|
||||
{0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
|
||||
{0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
|
||||
{0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
|
||||
{0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
|
||||
{0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
|
||||
{0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e},
|
||||
{0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
|
||||
{0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
|
||||
{0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
|
||||
{0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
|
||||
{0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
|
||||
{0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
|
||||
{0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
|
||||
{0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
|
||||
{0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
|
||||
{0x11ac0, 0x11af8}, {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474},
|
||||
{0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
|
||||
{0x16a40, 0x16a5e}, {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5},
|
||||
{0x16b00, 0x16b45}, {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77},
|
||||
{0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
|
||||
{0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371},
|
||||
{0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
|
||||
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
|
||||
{0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
|
||||
{0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b},
|
||||
{0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6},
|
||||
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
|
||||
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
|
||||
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
|
||||
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
|
||||
{0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
|
||||
{0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f19a},
|
||||
{0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f579},
|
||||
{0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f6d0}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3},
|
||||
{0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
|
||||
{0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f910, 0x1f918},
|
||||
{0x1f980, 0x1f984}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
|
||||
{0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
{0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
|
||||
{0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
|
||||
{0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
|
||||
{0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
|
||||
{0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
|
||||
{0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
|
||||
{0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
|
||||
{0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356},
|
||||
{0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
|
||||
{0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
|
||||
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
|
||||
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03},
|
||||
{0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
|
||||
{0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
|
||||
{0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
|
||||
{0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae},
|
||||
{0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c},
|
||||
{0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
|
||||
{0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec},
|
||||
{0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b},
|
||||
{0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad},
|
||||
{0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b},
|
||||
{0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -747,20 +758,20 @@ static const chr graphCharTable[] = {
|
||||
0xad0, 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56,
|
||||
0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e,
|
||||
0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6,
|
||||
0xcde, 0xcf1, 0xcf2, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6,
|
||||
0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7,
|
||||
0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773,
|
||||
0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27,
|
||||
0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc,
|
||||
0xfffd
|
||||
0xcde, 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81,
|
||||
0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa,
|
||||
0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940,
|
||||
0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d,
|
||||
0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
|
||||
0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001,
|
||||
0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22,
|
||||
0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51,
|
||||
0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62,
|
||||
0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x16a6e, 0x16a6f,
|
||||
0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
|
||||
0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
|
||||
0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
|
||||
0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
|
||||
0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f930, 0x1f9c0
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+17
-11
@@ -144,6 +144,7 @@ extern "C" {
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
# define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
# define TCL_NORETURN __attribute__ ((noreturn))
|
||||
# define TCL_NOINLINE __attribute__ ((noinline))
|
||||
# if defined(BUILD_tcl) || defined(BUILD_tk)
|
||||
# define TCL_NORETURN1 __attribute__ ((noreturn))
|
||||
# else
|
||||
@@ -153,8 +154,10 @@ extern "C" {
|
||||
# define TCL_FORMAT_PRINTF(a,b)
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1310)
|
||||
# define TCL_NORETURN _declspec(noreturn)
|
||||
# define TCL_NOINLINE __declspec(noinline)
|
||||
# else
|
||||
# define TCL_NORETURN /* nothing */
|
||||
# define TCL_NOINLINE /* nothing */
|
||||
# endif
|
||||
# define TCL_NORETURN1 /* nothing */
|
||||
#endif
|
||||
@@ -1154,11 +1157,15 @@ typedef struct Tcl_DString {
|
||||
* Forward declarations of Tcl_HashTable and related types.
|
||||
*/
|
||||
|
||||
#ifndef TCL_HASH_TYPE
|
||||
# define TCL_HASH_TYPE unsigned
|
||||
#endif
|
||||
|
||||
typedef struct Tcl_HashKeyType Tcl_HashKeyType;
|
||||
typedef struct Tcl_HashTable Tcl_HashTable;
|
||||
typedef struct Tcl_HashEntry Tcl_HashEntry;
|
||||
|
||||
typedef unsigned (Tcl_HashKeyProc) (Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
typedef TCL_HASH_TYPE (Tcl_HashKeyProc) (Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
typedef int (Tcl_CompareHashKeysProc) (void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
typedef Tcl_HashEntry * (Tcl_AllocHashEntryProc) (Tcl_HashTable *tablePtr,
|
||||
void *keyPtr);
|
||||
@@ -2374,9 +2381,6 @@ typedef int (Tcl_NRPostProc) (ClientData data[], Tcl_Interp *interp,
|
||||
*----------------------------------------------------------------------------
|
||||
* The following constant is used to test for older versions of Tcl in the
|
||||
* stubs tables.
|
||||
*
|
||||
* Jan Nijtman's plus patch uses 0xFCA1BACF, so we need to pick a different
|
||||
* value since the stubs tables don't match.
|
||||
*/
|
||||
|
||||
#define TCL_STUB_MAGIC ((int) 0xFCA3BACF)
|
||||
@@ -2389,17 +2393,19 @@ typedef int (Tcl_NRPostProc) (ClientData data[], Tcl_Interp *interp,
|
||||
*/
|
||||
|
||||
const char * Tcl_InitStubs(Tcl_Interp *interp, const char *version,
|
||||
int exact);
|
||||
int exact, int magic);
|
||||
const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
|
||||
const char *version, int epoch, int revision);
|
||||
|
||||
/*
|
||||
* When not using stubs, make it a macro.
|
||||
*/
|
||||
|
||||
#ifndef USE_TCL_STUBS
|
||||
#ifdef USE_TCL_STUBS
|
||||
#define Tcl_InitStubs(interp, version, exact) \
|
||||
Tcl_PkgInitStubsCheck(interp, version, exact)
|
||||
(Tcl_InitStubs)(interp, version, \
|
||||
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
|
||||
TCL_STUB_MAGIC)
|
||||
#else
|
||||
#define Tcl_InitStubs(interp, version, exact) \
|
||||
Tcl_PkgInitStubsCheck(interp, version, \
|
||||
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
+12
-10
@@ -1299,8 +1299,8 @@ AssembleOneLine(
|
||||
if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
operand1 = Tcl_GetStringFromObj(operand1Obj, &operand1Len);
|
||||
litIndex = TclRegisterNewLiteral(envPtr, operand1, operand1Len);
|
||||
operand1 = TclGetStringFromObj(operand1Obj, &operand1Len);
|
||||
litIndex = TclRegisterLiteral(envPtr, operand1, operand1Len, 0);
|
||||
BBEmitInst1or4(assemEnvPtr, tblIdx, litIndex, 0);
|
||||
break;
|
||||
|
||||
@@ -1448,8 +1448,8 @@ AssembleOneLine(
|
||||
&operand1Obj) != TCL_OK) {
|
||||
goto cleanup;
|
||||
} else {
|
||||
operand1 = Tcl_GetStringFromObj(operand1Obj, &operand1Len);
|
||||
litIndex = TclRegisterNewLiteral(envPtr, operand1, operand1Len);
|
||||
operand1 = TclGetStringFromObj(operand1Obj, &operand1Len);
|
||||
litIndex = TclRegisterLiteral(envPtr, operand1, operand1Len, 0);
|
||||
|
||||
/*
|
||||
* Assumes that PUSH is the first slot!
|
||||
@@ -2288,7 +2288,7 @@ FindLocalVar(
|
||||
if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &varNameObj) != TCL_OK) {
|
||||
return -1;
|
||||
}
|
||||
varNameStr = Tcl_GetStringFromObj(varNameObj, &varNameLen);
|
||||
varNameStr = TclGetStringFromObj(varNameObj, &varNameLen);
|
||||
if (CheckNamespaceQualifiers(interp, varNameStr, varNameLen)) {
|
||||
Tcl_DecrRefCount(varNameObj);
|
||||
return -1;
|
||||
@@ -3541,7 +3541,7 @@ StackCheckExit(
|
||||
* Emit a 'push' of the empty literal.
|
||||
*/
|
||||
|
||||
litIndex = TclRegisterNewLiteral(envPtr, "", 0);
|
||||
litIndex = TclRegisterLiteral(envPtr, "", 0, 0);
|
||||
|
||||
/*
|
||||
* Assumes that 'push' is at slot 0 in TalInstructionTable.
|
||||
@@ -3982,10 +3982,12 @@ UnstackExpiredCatches(
|
||||
|
||||
while (catchDepth > bbPtr->catchDepth) {
|
||||
--catchDepth;
|
||||
range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
|
||||
range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
|
||||
catches[catchDepth] = NULL;
|
||||
catchIndices[catchDepth] = -1;
|
||||
if (catches[catchDepth] != NULL) {
|
||||
range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
|
||||
range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
|
||||
catches[catchDepth] = NULL;
|
||||
catchIndices[catchDepth] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+27
-22
@@ -128,7 +128,7 @@ static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
|
||||
int actual, Tcl_Obj *const *objv);
|
||||
static Tcl_NRPostProc NRCoroutineCallerCallback;
|
||||
static Tcl_NRPostProc NRCoroutineExitCallback;
|
||||
static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc NRCommand;
|
||||
|
||||
static Tcl_ObjCmdProc OldMathFuncProc;
|
||||
static void OldMathFuncDeleteProc(ClientData clientData);
|
||||
@@ -146,7 +146,6 @@ static int TEOV_RunEnterTraces(Tcl_Interp *interp,
|
||||
Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static Tcl_NRPostProc RewindCoroutineCallback;
|
||||
static Tcl_NRPostProc TailcallCleanup;
|
||||
static Tcl_NRPostProc TEOEx_ByteCodeCallback;
|
||||
static Tcl_NRPostProc TEOEx_ListCallback;
|
||||
static Tcl_NRPostProc TEOV_Error;
|
||||
@@ -724,9 +723,7 @@ Tcl_CreateInterp(void)
|
||||
* Initialize the ensemble error message rewriting support.
|
||||
*/
|
||||
|
||||
iPtr->ensembleRewrite.sourceObjs = NULL;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 0;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 0;
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
|
||||
/*
|
||||
* TIP#143: Initialise the resource limit support.
|
||||
@@ -943,8 +940,8 @@ Tcl_CreateInterp(void)
|
||||
* Set up other variables such as tcl_version and tcl_library
|
||||
*/
|
||||
|
||||
Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "tcl_patchLevel", NULL, TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "tcl_version", NULL, TCL_VERSION, TCL_GLOBAL_ONLY);
|
||||
Tcl_TraceVar2(interp, "tcl_precision", NULL,
|
||||
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
|
||||
TclPrecTraceProc, NULL);
|
||||
@@ -3946,7 +3943,7 @@ Tcl_Canceled(
|
||||
*/
|
||||
|
||||
if (iPtr->asyncCancelMsg != NULL) {
|
||||
message = Tcl_GetStringFromObj(iPtr->asyncCancelMsg, &length);
|
||||
message = TclGetStringFromObj(iPtr->asyncCancelMsg, &length);
|
||||
} else {
|
||||
length = 0;
|
||||
}
|
||||
@@ -4045,7 +4042,7 @@ Tcl_CancelEval(
|
||||
*/
|
||||
|
||||
if (resultObjPtr != NULL) {
|
||||
result = Tcl_GetStringFromObj(resultObjPtr, &cancelInfo->length);
|
||||
result = TclGetStringFromObj(resultObjPtr, &cancelInfo->length);
|
||||
cancelInfo->result = ckrealloc(cancelInfo->result,cancelInfo->length);
|
||||
memcpy(cancelInfo->result, result, (size_t) cancelInfo->length);
|
||||
TclDecrRefCount(resultObjPtr); /* Discard their result object. */
|
||||
@@ -4221,7 +4218,7 @@ EvalObjvCore(
|
||||
* TCL_EVAL_INVOKE was not set: clear rewrite rules
|
||||
*/
|
||||
|
||||
iPtr->ensembleRewrite.sourceObjs = NULL;
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
|
||||
if (flags & TCL_EVAL_GLOBAL) {
|
||||
TEOV_SwitchVarFrame(interp);
|
||||
@@ -4557,7 +4554,7 @@ TEOV_Error(
|
||||
*/
|
||||
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
cmdString = Tcl_GetStringFromObj(listPtr, &cmdLen);
|
||||
cmdString = TclGetStringFromObj(listPtr, &cmdLen);
|
||||
Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
|
||||
Tcl_DecrRefCount(listPtr);
|
||||
}
|
||||
@@ -4703,7 +4700,7 @@ TEOV_RunEnterTraces(
|
||||
Command *cmdPtr = *cmdPtrPtr;
|
||||
int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
|
||||
int length, traceCode = TCL_OK;
|
||||
const char *command = Tcl_GetStringFromObj(commandPtr, &length);
|
||||
const char *command = TclGetStringFromObj(commandPtr, &length);
|
||||
|
||||
/*
|
||||
* Call trace functions.
|
||||
@@ -4755,7 +4752,7 @@ TEOV_RunLeaveTraces(
|
||||
Command *cmdPtr = data[2];
|
||||
Tcl_Obj **objv = data[3];
|
||||
int length;
|
||||
const char *command = Tcl_GetStringFromObj(commandPtr, &length);
|
||||
const char *command = TclGetStringFromObj(commandPtr, &length);
|
||||
|
||||
if (!(cmdPtr->flags & CMD_IS_DELETED)) {
|
||||
if (cmdPtr->flags & CMD_HAS_EXEC_TRACES){
|
||||
@@ -6120,7 +6117,7 @@ TclNREvalObjEx(
|
||||
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
|
||||
script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
|
||||
script = TclGetStringFromObj(objPtr, &numSrcBytes);
|
||||
result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
|
||||
|
||||
TclDecrRefCount(objPtr);
|
||||
@@ -6151,7 +6148,7 @@ TEOEx_ByteCodeCallback(
|
||||
|
||||
ProcessUnexpectedResult(interp, result);
|
||||
result = TCL_ERROR;
|
||||
script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
|
||||
script = TclGetStringFromObj(objPtr, &numSrcBytes);
|
||||
Tcl_LogCommandInfo(interp, script, script, numSrcBytes);
|
||||
}
|
||||
|
||||
@@ -6850,7 +6847,7 @@ Tcl_VarEvalVA(
|
||||
Tcl_DStringAppend(&buf, string, -1);
|
||||
}
|
||||
|
||||
result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
|
||||
result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
|
||||
Tcl_DStringFree(&buf);
|
||||
return result;
|
||||
}
|
||||
@@ -6920,7 +6917,7 @@ Tcl_GlobalEval(
|
||||
|
||||
savedVarFramePtr = iPtr->varFramePtr;
|
||||
iPtr->varFramePtr = iPtr->rootFramePtr;
|
||||
result = Tcl_Eval(interp, command);
|
||||
result = Tcl_EvalEx(interp, command, -1, 0);
|
||||
iPtr->varFramePtr = savedVarFramePtr;
|
||||
return result;
|
||||
}
|
||||
@@ -8374,7 +8371,7 @@ TclNRTailcallEval(
|
||||
* a now-gone namespace: cleanup and return.
|
||||
*/
|
||||
|
||||
TailcallCleanup(data, interp, result);
|
||||
Tcl_DecrRefCount(listPtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -8383,18 +8380,26 @@ TclNRTailcallEval(
|
||||
*/
|
||||
|
||||
TclMarkTailcall(interp);
|
||||
TclNRAddCallback(interp, TailcallCleanup, listPtr, NULL, NULL,NULL);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
|
||||
iPtr->lookupNsPtr = (Namespace *) nsPtr;
|
||||
return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
TailcallCleanup(
|
||||
int
|
||||
TclNRReleaseValues(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Tcl_DecrRefCount((Tcl_Obj *) data[0]);
|
||||
int i = 0;
|
||||
while (i < 4) {
|
||||
if (data[i]) {
|
||||
Tcl_DecrRefCount((Tcl_Obj *) data[i]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2500,7 +2500,7 @@ BinaryEncode64(
|
||||
}
|
||||
break;
|
||||
case OPT_WRAPCHAR:
|
||||
wrapchar = Tcl_GetStringFromObj(objv[i+1], &wrapcharlen);
|
||||
wrapchar = TclGetStringFromObj(objv[i+1], &wrapcharlen);
|
||||
if (wrapcharlen == 0) {
|
||||
maxlen = 0;
|
||||
}
|
||||
|
||||
@@ -1499,7 +1499,19 @@ GetJulianDayFromEraYearMonthDay(
|
||||
* Try an initial conversion in the Gregorian calendar.
|
||||
*/
|
||||
|
||||
#if 0 /* BUG http://core.tcl.tk/tcl/tktview?name=da340d4f32 */
|
||||
ym1o4 = ym1 / 4;
|
||||
#else
|
||||
/*
|
||||
* Have to make sure quotient is truncated towards 0 when negative.
|
||||
* See above bug for details. The casts are necessary.
|
||||
*/
|
||||
if (ym1 >= 0)
|
||||
ym1o4 = ym1 / 4;
|
||||
else {
|
||||
ym1o4 = - (int) (((unsigned int) -ym1) / 4);
|
||||
}
|
||||
#endif
|
||||
if (ym1 % 4 < 0) {
|
||||
ym1o4--;
|
||||
}
|
||||
|
||||
+31
-12
@@ -12,6 +12,9 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#ifdef _WIN32
|
||||
# include "tclWinInt.h"
|
||||
#endif
|
||||
#include <locale.h>
|
||||
|
||||
/*
|
||||
@@ -1157,6 +1160,16 @@ FileAttrAccessTimeCmd(
|
||||
if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
/* We use a value of 0 to indicate the access time not available */
|
||||
if (buf.st_atime == 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not get access time for file \"%s\"",
|
||||
TclGetString(objv[1])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (objc == 3) {
|
||||
/*
|
||||
* Need separate variable for reading longs from an object on 64-bit
|
||||
@@ -1229,6 +1242,15 @@ FileAttrModifyTimeCmd(
|
||||
if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
/* We use a value of 0 to indicate the modification time not available */
|
||||
if (buf.st_mtime == 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not get modification time for file \"%s\"",
|
||||
TclGetString(objv[1])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#endif
|
||||
if (objc == 3) {
|
||||
/*
|
||||
* Need separate variable for reading longs from an object on 64-bit
|
||||
@@ -1574,28 +1596,25 @@ FileAttrIsOwnedCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
#define geteuid() (short)(geteuid)()
|
||||
#endif
|
||||
#if !defined(_WIN32)
|
||||
Tcl_StatBuf buf;
|
||||
#endif
|
||||
int value = 0;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
|
||||
/*
|
||||
* For Windows, there are no user ids associated with a file, so we
|
||||
* always return 1.
|
||||
*
|
||||
* TODO: use GetSecurityInfo to get the real owner of the file and
|
||||
* test for equivalence to the current user.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
value = 1;
|
||||
#if defined(_WIN32)
|
||||
value = TclWinFileOwned(objv[1]);
|
||||
#else
|
||||
if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
|
||||
value = (geteuid() == buf.st_uid);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+42
-15
@@ -105,8 +105,7 @@ typedef struct SortInfo {
|
||||
*/
|
||||
|
||||
static int DictionaryCompare(const char *left, const char *right);
|
||||
static int IfConditionCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc IfConditionCallback;
|
||||
static int InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
static int InfoBodyCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
@@ -1203,7 +1202,7 @@ InfoFrameCmd(
|
||||
levelError:
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad level \"%s\"", TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME",
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
|
||||
TclGetString(objv[1]), NULL);
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
@@ -1638,7 +1637,7 @@ InfoLevelCmd(
|
||||
levelError:
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad level \"%s\"", TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
|
||||
TclGetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1678,7 +1677,7 @@ InfoLibraryCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
|
||||
libDirName = Tcl_GetVar2(interp, "tcl_library", NULL, TCL_GLOBAL_ONLY);
|
||||
if (libDirName != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
|
||||
return TCL_OK;
|
||||
@@ -1804,7 +1803,7 @@ InfoPatchLevelCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
patchlevel = Tcl_GetVar(interp, "tcl_patchLevel",
|
||||
patchlevel = Tcl_GetVar2(interp, "tcl_patchLevel", NULL,
|
||||
(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
|
||||
if (patchlevel != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(patchlevel, -1));
|
||||
@@ -2156,8 +2155,8 @@ Tcl_JoinObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* The argument objects. */
|
||||
{
|
||||
int listLen, i;
|
||||
Tcl_Obj *resObjPtr, *joinObjPtr, **elemPtrs;
|
||||
int listLen;
|
||||
Tcl_Obj *resObjPtr = NULL, *joinObjPtr, **elemPtrs;
|
||||
|
||||
if ((objc < 2) || (objc > 3)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
|
||||
@@ -2174,19 +2173,47 @@ Tcl_JoinObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (listLen == 0) {
|
||||
/* No elements to join; default empty result is correct. */
|
||||
return TCL_OK;
|
||||
}
|
||||
if (listLen == 1) {
|
||||
/* One element; return it */
|
||||
Tcl_SetObjResult(interp, elemPtrs[0]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
|
||||
Tcl_IncrRefCount(joinObjPtr);
|
||||
|
||||
resObjPtr = Tcl_NewObj();
|
||||
for (i = 0; i < listLen; i++) {
|
||||
if (i > 0) {
|
||||
Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
|
||||
if (Tcl_GetCharLength(joinObjPtr) == 0) {
|
||||
TclStringCatObjv(interp, /* inPlace */ 0, listLen, elemPtrs,
|
||||
&resObjPtr);
|
||||
} else {
|
||||
int i;
|
||||
|
||||
resObjPtr = Tcl_NewObj();
|
||||
for (i = 0; i < listLen; i++) {
|
||||
if (i > 0) {
|
||||
|
||||
/*
|
||||
* NOTE: This code is relying on Tcl_AppendObjToObj() **NOT**
|
||||
* to shimmer joinObjPtr. If it did, then the case where
|
||||
* objv[1] and objv[2] are the same value would not be safe.
|
||||
* Accessing elemPtrs would crash.
|
||||
*/
|
||||
|
||||
Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
|
||||
}
|
||||
Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
|
||||
}
|
||||
Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
|
||||
}
|
||||
Tcl_DecrRefCount(joinObjPtr);
|
||||
Tcl_SetObjResult(interp, resObjPtr);
|
||||
return TCL_OK;
|
||||
if (resObjPtr) {
|
||||
Tcl_SetObjResult(interp, resObjPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+24
-88
@@ -22,14 +22,10 @@
|
||||
|
||||
static inline Tcl_Obj * During(Tcl_Interp *interp, int resultCode,
|
||||
Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
|
||||
static int SwitchPostProc(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int TryPostBody(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int TryPostFinal(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int TryPostHandler(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static Tcl_NRPostProc SwitchPostProc;
|
||||
static Tcl_NRPostProc TryPostBody;
|
||||
static Tcl_NRPostProc TryPostFinal;
|
||||
static Tcl_NRPostProc TryPostHandler;
|
||||
static int UniCharIsAscii(int character);
|
||||
static int UniCharIsHexDigit(int character);
|
||||
|
||||
@@ -1180,8 +1176,7 @@ StringFirstCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_UniChar *needleStr, *haystackStr;
|
||||
int match, start, needleLen, haystackLen;
|
||||
int start = 0;
|
||||
|
||||
if (objc < 3 || objc > 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
@@ -1189,82 +1184,23 @@ StringFirstCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are searching haystackStr for the sequence needleStr.
|
||||
*/
|
||||
|
||||
match = -1;
|
||||
start = 0;
|
||||
haystackLen = -1;
|
||||
|
||||
needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
|
||||
haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
|
||||
|
||||
if (objc == 4) {
|
||||
/*
|
||||
* If a startIndex is specified, we will need to fast forward to that
|
||||
* point in the string before we think about a match.
|
||||
*/
|
||||
int size = Tcl_GetCharLength(objv[2]);
|
||||
|
||||
if (TclGetIntForIndexM(interp, objv[3], haystackLen-1,
|
||||
&start) != TCL_OK){
|
||||
if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &start)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reread to prevent shimmering problems.
|
||||
*/
|
||||
|
||||
needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
|
||||
haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
|
||||
|
||||
if (start >= haystackLen) {
|
||||
goto str_first_done;
|
||||
} else if (start > 0) {
|
||||
haystackStr += start;
|
||||
haystackLen -= start;
|
||||
} else if (start < 0) {
|
||||
/*
|
||||
* Invalid start index mapped to string start; Bug #423581
|
||||
*/
|
||||
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the length of the needle is more than the length of the haystack, it
|
||||
* cannot be contained in there so we can avoid searching. [Bug 2960021]
|
||||
*/
|
||||
|
||||
if (needleLen > 0 && needleLen <= haystackLen) {
|
||||
register Tcl_UniChar *p, *end;
|
||||
|
||||
end = haystackStr + haystackLen - needleLen + 1;
|
||||
for (p = haystackStr; p < end; p++) {
|
||||
/*
|
||||
* Scan forward to find the first character.
|
||||
*/
|
||||
|
||||
if ((*p == *needleStr) && (TclUniCharNcmp(needleStr, p,
|
||||
(unsigned long) needleLen) == 0)) {
|
||||
match = p - haystackStr;
|
||||
break;
|
||||
}
|
||||
if (start >= size) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the character index of the matching string by counting the
|
||||
* number of characters before the match.
|
||||
*/
|
||||
|
||||
if ((match != -1) && (objc == 4)) {
|
||||
match += start;
|
||||
}
|
||||
|
||||
str_first_done:
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFind(objv[1],
|
||||
objv[2], start)));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1877,7 +1813,7 @@ StringMapCmd(
|
||||
|
||||
/*
|
||||
* This test is tricky, but has to be that way or you get other strange
|
||||
* inconsistencies (see test string-10.20 for illustration why!)
|
||||
* inconsistencies (see test string-10.20.1 for illustration why!)
|
||||
*/
|
||||
|
||||
if (objv[objc-2]->typePtr == &tclDictType && objv[objc-2]->bytes == NULL){
|
||||
@@ -2859,7 +2795,7 @@ StringCatCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int i;
|
||||
int code;
|
||||
Tcl_Obj *objResultPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
@@ -2876,16 +2812,16 @@ StringCatCmd(
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
objResultPtr = objv[1];
|
||||
if (Tcl_IsShared(objResultPtr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(objResultPtr);
|
||||
}
|
||||
for(i = 2;i < objc;i++) {
|
||||
Tcl_AppendObjToObj(objResultPtr, objv[i]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, objResultPtr);
|
||||
|
||||
return TCL_OK;
|
||||
code = TclStringCatObjv(interp, /* inPlace */ 1, objc-1, objv+1,
|
||||
&objResultPtr);
|
||||
|
||||
if (code == TCL_OK) {
|
||||
Tcl_SetObjResult(interp, objResultPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+6
-17
@@ -801,7 +801,7 @@ TclCompileConcatCmd(
|
||||
Tcl_ListObjGetElements(NULL, listObj, &len, &objs);
|
||||
objPtr = Tcl_ConcatObj(len, objs);
|
||||
Tcl_DecrRefCount(listObj);
|
||||
bytes = Tcl_GetStringFromObj(objPtr, &len);
|
||||
bytes = TclGetStringFromObj(objPtr, &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
return TCL_OK;
|
||||
@@ -1209,7 +1209,7 @@ TclCompileDictCreateCmd(
|
||||
* We did! Excellent. The "verifyDict" is to do type forcing.
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(dictObj, &len);
|
||||
bytes = TclGetStringFromObj(dictObj, &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_DICT_VERIFY, envPtr);
|
||||
@@ -2650,7 +2650,7 @@ CompileEachloopCmd(
|
||||
int numBytes, varIndex;
|
||||
|
||||
Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj);
|
||||
bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
|
||||
bytes = TclGetStringFromObj(varNameObj, &numBytes);
|
||||
varIndex = LocalScalar(bytes, numBytes, envPtr);
|
||||
if (varIndex < 0) {
|
||||
code = TCL_ERROR;
|
||||
@@ -3087,7 +3087,7 @@ TclCompileFormatCmd(
|
||||
* literal. Job done.
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(tmpObj, &len);
|
||||
bytes = TclGetStringFromObj(tmpObj, &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
return TCL_OK;
|
||||
@@ -3158,7 +3158,7 @@ TclCompileFormatCmd(
|
||||
if (*++bytes == '%') {
|
||||
Tcl_AppendToObj(tmpObj, "%", 1);
|
||||
} else {
|
||||
char *b = Tcl_GetStringFromObj(tmpObj, &len);
|
||||
char *b = TclGetStringFromObj(tmpObj, &len);
|
||||
|
||||
/*
|
||||
* If there is a non-empty literal from the format string,
|
||||
@@ -3192,7 +3192,7 @@ TclCompileFormatCmd(
|
||||
*/
|
||||
|
||||
Tcl_AppendToObj(tmpObj, start, bytes - start);
|
||||
bytes = Tcl_GetStringFromObj(tmpObj, &len);
|
||||
bytes = TclGetStringFromObj(tmpObj, &len);
|
||||
if (len > 0) {
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
i++;
|
||||
@@ -3206,17 +3206,6 @@ TclCompileFormatCmd(
|
||||
*/
|
||||
|
||||
TclEmitInstInt1(INST_STR_CONCAT1, i, envPtr);
|
||||
} else {
|
||||
/*
|
||||
* EVIL HACK! Force there to be a string representation in the case
|
||||
* where there's just a "%s" in the format; case covered by the test
|
||||
* format-20.1 (and it is horrible...)
|
||||
*/
|
||||
|
||||
TclEmitOpcode(INST_DUP, envPtr);
|
||||
PushStringLiteral(envPtr, "");
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2451,7 +2451,7 @@ TclCompileRegsubCmd(
|
||||
* replacement "simple"?
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(patternObj, &len);
|
||||
bytes = TclGetStringFromObj(patternObj, &len);
|
||||
if (TclReToGlob(NULL, bytes, len, &pattern, &exact, &quantified)
|
||||
!= TCL_OK || exact || quantified) {
|
||||
goto done;
|
||||
@@ -2499,7 +2499,7 @@ TclCompileRegsubCmd(
|
||||
result = TCL_OK;
|
||||
bytes = Tcl_DStringValue(&pattern) + 1;
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
bytes = Tcl_GetStringFromObj(replacementObj, &len);
|
||||
bytes = TclGetStringFromObj(replacementObj, &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
CompileWord(envPtr, stringTokenPtr, interp, parsePtr->numWords-2);
|
||||
TclEmitOpcode( INST_STR_MAP, envPtr);
|
||||
@@ -2761,7 +2761,7 @@ TclCompileSyntaxError(
|
||||
const char *bytes = TclGetStringFromObj(msg, &numBytes);
|
||||
|
||||
TclErrorStackResetIf(interp, bytes, numBytes);
|
||||
TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr);
|
||||
TclEmitPush(TclRegisterLiteral(envPtr, bytes, numBytes, 0), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0,
|
||||
TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR)));
|
||||
Tcl_ResetResult(interp);
|
||||
|
||||
+12
-12
@@ -312,7 +312,7 @@ TclCompileStringCatCmd(
|
||||
Tcl_DecrRefCount(obj);
|
||||
if (folded) {
|
||||
int len;
|
||||
const char *bytes = Tcl_GetStringFromObj(folded, &len);
|
||||
const char *bytes = TclGetStringFromObj(folded, &len);
|
||||
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(folded);
|
||||
@@ -330,7 +330,7 @@ TclCompileStringCatCmd(
|
||||
}
|
||||
if (folded) {
|
||||
int len;
|
||||
const char *bytes = Tcl_GetStringFromObj(folded, &len);
|
||||
const char *bytes = TclGetStringFromObj(folded, &len);
|
||||
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(folded);
|
||||
@@ -948,12 +948,12 @@ TclCompileStringMapCmd(
|
||||
* correct semantics for mapping.
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(objv[0], &len);
|
||||
bytes = TclGetStringFromObj(objv[0], &len);
|
||||
if (len == 0) {
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
bytes = Tcl_GetStringFromObj(objv[1], &len);
|
||||
bytes = TclGetStringFromObj(objv[1], &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 2);
|
||||
OP(STR_MAP);
|
||||
@@ -1456,8 +1456,8 @@ TclSubstCompile(
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
case TCL_TOKEN_TEXT:
|
||||
literal = TclRegisterNewLiteral(envPtr,
|
||||
tokenPtr->start, tokenPtr->size);
|
||||
literal = TclRegisterLiteral(envPtr,
|
||||
tokenPtr->start, tokenPtr->size, 0);
|
||||
TclEmitPush(literal, envPtr);
|
||||
TclAdvanceLines(&bline, tokenPtr->start,
|
||||
tokenPtr->start + tokenPtr->size);
|
||||
@@ -1466,7 +1466,7 @@ TclSubstCompile(
|
||||
case TCL_TOKEN_BS:
|
||||
length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
|
||||
NULL, buf);
|
||||
literal = TclRegisterNewLiteral(envPtr, buf, length);
|
||||
literal = TclRegisterLiteral(envPtr, buf, length, 0);
|
||||
TclEmitPush(literal, envPtr);
|
||||
count++;
|
||||
continue;
|
||||
@@ -2825,7 +2825,7 @@ TclCompileTryCmd(
|
||||
}
|
||||
if (objc > 0) {
|
||||
int len;
|
||||
const char *varname = Tcl_GetStringFromObj(objv[0], &len);
|
||||
const char *varname = TclGetStringFromObj(objv[0], &len);
|
||||
|
||||
resultVarIndices[i] = LocalScalar(varname, len, envPtr);
|
||||
if (resultVarIndices[i] < 0) {
|
||||
@@ -2837,7 +2837,7 @@ TclCompileTryCmd(
|
||||
}
|
||||
if (objc == 2) {
|
||||
int len;
|
||||
const char *varname = Tcl_GetStringFromObj(objv[1], &len);
|
||||
const char *varname = TclGetStringFromObj(objv[1], &len);
|
||||
|
||||
optionVarIndices[i] = LocalScalar(varname, len, envPtr);
|
||||
if (optionVarIndices[i] < 0) {
|
||||
@@ -3040,7 +3040,7 @@ IssueTryClausesInstructions(
|
||||
OP4( DICT_GET, 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
OP44( LIST_RANGE_IMM, 0, len-1);
|
||||
p = Tcl_GetStringFromObj(matchClauses[i], &len);
|
||||
p = TclGetStringFromObj(matchClauses[i], &len);
|
||||
PushLiteral(envPtr, p, len);
|
||||
OP( STR_EQ);
|
||||
JUMP4( JUMP_FALSE, notECJumpSource);
|
||||
@@ -3251,7 +3251,7 @@ IssueTryClausesFinallyInstructions(
|
||||
OP4( DICT_GET, 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
OP44( LIST_RANGE_IMM, 0, len-1);
|
||||
p = Tcl_GetStringFromObj(matchClauses[i], &len);
|
||||
p = TclGetStringFromObj(matchClauses[i], &len);
|
||||
PushLiteral(envPtr, p, len);
|
||||
OP( STR_EQ);
|
||||
JUMP4( JUMP_FALSE, notECJumpSource);
|
||||
@@ -3579,7 +3579,7 @@ TclCompileUnsetCmd(
|
||||
const char *bytes;
|
||||
int len;
|
||||
|
||||
bytes = Tcl_GetStringFromObj(leadingWord, &len);
|
||||
bytes = TclGetStringFromObj(leadingWord, &len);
|
||||
if (i == 1 && len == 11 && !strncmp("-nocomplain", bytes, 11)) {
|
||||
flags = 0;
|
||||
haveFlags++;
|
||||
|
||||
@@ -2267,9 +2267,9 @@ CompileExprTree(
|
||||
p = TclGetStringFromObj(*funcObjv, &length);
|
||||
funcObjv++;
|
||||
Tcl_DStringAppend(&cmdName, p, length);
|
||||
TclEmitPush(TclRegisterNewCmdLiteral(envPtr,
|
||||
TclEmitPush(TclRegisterLiteral(envPtr,
|
||||
Tcl_DStringValue(&cmdName),
|
||||
Tcl_DStringLength(&cmdName)), envPtr);
|
||||
Tcl_DStringLength(&cmdName), LITERAL_CMD_NAME), envPtr);
|
||||
Tcl_DStringFree(&cmdName);
|
||||
|
||||
/*
|
||||
@@ -2376,8 +2376,8 @@ CompileExprTree(
|
||||
pc1 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1((nodePtr->lexeme == AND) ? INST_JUMP_FALSE1
|
||||
: INST_JUMP_TRUE1, 0, envPtr);
|
||||
TclEmitPush(TclRegisterNewLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "1" : "0", 1), envPtr);
|
||||
TclEmitPush(TclRegisterLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "1" : "0", 1, 0), envPtr);
|
||||
pc2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1(INST_JUMP1, 0, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
@@ -2386,8 +2386,8 @@ CompileExprTree(
|
||||
if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
|
||||
pc2 += 3;
|
||||
}
|
||||
TclEmitPush(TclRegisterNewLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr);
|
||||
TclEmitPush(TclRegisterLiteral(envPtr,
|
||||
(nodePtr->lexeme == AND) ? "0" : "1", 1, 0), envPtr);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc2,
|
||||
envPtr->codeStart + pc2 + 1);
|
||||
convert = 0;
|
||||
@@ -2421,7 +2421,7 @@ CompileExprTree(
|
||||
if (optimize) {
|
||||
int length;
|
||||
const char *bytes = TclGetStringFromObj(literal, &length);
|
||||
int index = TclRegisterNewLiteral(envPtr, bytes, length);
|
||||
int index = TclRegisterLiteral(envPtr, bytes, length, 0);
|
||||
Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index);
|
||||
|
||||
if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) {
|
||||
@@ -2479,8 +2479,8 @@ CompileExprTree(
|
||||
if (objPtr->bytes) {
|
||||
Tcl_Obj *tableValue;
|
||||
|
||||
index = TclRegisterNewLiteral(envPtr, objPtr->bytes,
|
||||
objPtr->length);
|
||||
index = TclRegisterLiteral(envPtr, objPtr->bytes,
|
||||
objPtr->length, 0);
|
||||
tableValue = TclFetchLiteral(envPtr, index);
|
||||
if ((tableValue->typePtr == NULL) &&
|
||||
(objPtr->typePtr != NULL)) {
|
||||
|
||||
+22
-12
@@ -993,7 +993,7 @@ FreeByteCodeInternalRep(
|
||||
|
||||
void
|
||||
TclPreserveByteCode(
|
||||
register ByteCode *codePtr)
|
||||
register ByteCode *codePtr)
|
||||
{
|
||||
codePtr->refCount++;
|
||||
}
|
||||
@@ -1314,7 +1314,7 @@ CompileSubstObj(
|
||||
if (objPtr->typePtr != &substCodeType) {
|
||||
CompileEnv compEnv;
|
||||
int numBytes;
|
||||
const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
|
||||
const char *bytes = TclGetStringFromObj(objPtr, &numBytes);
|
||||
|
||||
/* TODO: Check for more TIP 280 */
|
||||
TclInitCompileEnv(interp, &compEnv, bytes, numBytes, NULL, 0);
|
||||
@@ -1792,9 +1792,17 @@ CompileCmdLiteral(
|
||||
CompileEnv *envPtr)
|
||||
{
|
||||
int numBytes;
|
||||
const char *bytes = Tcl_GetStringFromObj(cmdObj, &numBytes);
|
||||
int cmdLitIdx = TclRegisterNewCmdLiteral(envPtr, bytes, numBytes);
|
||||
Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
|
||||
const char *bytes;
|
||||
Command *cmdPtr;
|
||||
int cmdLitIdx, extraLiteralFlags = LITERAL_CMD_NAME;
|
||||
|
||||
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
|
||||
if ((cmdPtr != NULL) && (cmdPtr->flags & CMD_VIA_RESOLVER)) {
|
||||
extraLiteralFlags |= LITERAL_UNSHARED;
|
||||
}
|
||||
|
||||
bytes = Tcl_GetStringFromObj(cmdObj, &numBytes);
|
||||
cmdLitIdx = TclRegisterLiteral(envPtr, bytes, numBytes, extraLiteralFlags);
|
||||
|
||||
if (cmdPtr) {
|
||||
TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLitIdx), cmdPtr);
|
||||
@@ -1829,8 +1837,8 @@ TclCompileInvocation(
|
||||
continue;
|
||||
}
|
||||
|
||||
objIdx = TclRegisterNewLiteral(envPtr,
|
||||
tokenPtr[1].start, tokenPtr[1].size);
|
||||
objIdx = TclRegisterLiteral(envPtr,
|
||||
tokenPtr[1].start, tokenPtr[1].size, 0);
|
||||
if (envPtr->clNext) {
|
||||
TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
|
||||
tokenPtr[1].start - envPtr->source, envPtr->clNext);
|
||||
@@ -1879,8 +1887,8 @@ CompileExpanded(
|
||||
continue;
|
||||
}
|
||||
|
||||
objIdx = TclRegisterNewLiteral(envPtr,
|
||||
tokenPtr[1].start, tokenPtr[1].size);
|
||||
objIdx = TclRegisterLiteral(envPtr,
|
||||
tokenPtr[1].start, tokenPtr[1].size, 0);
|
||||
if (envPtr->clNext) {
|
||||
TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
|
||||
tokenPtr[1].start - envPtr->source, envPtr->clNext);
|
||||
@@ -2729,7 +2737,7 @@ PreventCycle(
|
||||
* the intrep.
|
||||
*/
|
||||
int numBytes;
|
||||
const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
|
||||
const char *bytes = TclGetStringFromObj(objPtr, &numBytes);
|
||||
Tcl_Obj *copyPtr = Tcl_NewStringObj(bytes, numBytes);
|
||||
|
||||
Tcl_IncrRefCount(copyPtr);
|
||||
@@ -2968,7 +2976,7 @@ TclFindCompiledLocal(
|
||||
varNamePtr = &cachePtr->varName0;
|
||||
for (i=0; i < cachePtr->numVars; varNamePtr++, i++) {
|
||||
if (*varNamePtr) {
|
||||
localName = Tcl_GetStringFromObj(*varNamePtr, &len);
|
||||
localName = TclGetStringFromObj(*varNamePtr, &len);
|
||||
if ((len == nameBytes) && !strncmp(name, localName, len)) {
|
||||
return i;
|
||||
}
|
||||
@@ -3276,8 +3284,10 @@ EnterCmdWordData(
|
||||
TclAdvanceLines(&wordLine, last, tokenPtr->start);
|
||||
TclAdvanceContinuations(&wordLine, &wordNext,
|
||||
tokenPtr->start - envPtr->source);
|
||||
/* See Ticket 4b61afd660 */
|
||||
wwlines[wordIdx] =
|
||||
(TclWordKnownAtCompileTime(tokenPtr, NULL) ? wordLine : -1);
|
||||
((wordIdx == 0) || TclWordKnownAtCompileTime(tokenPtr, NULL))
|
||||
? wordLine : -1;
|
||||
ePtr->line[wordIdx] = wordLine;
|
||||
ePtr->next[wordIdx] = wordNext;
|
||||
last = tokenPtr->start;
|
||||
|
||||
+4
-26
@@ -1095,7 +1095,7 @@ MODULE_SCOPE int TclCreateAuxData(ClientData clientData,
|
||||
MODULE_SCOPE int TclCreateExceptRange(ExceptionRangeType type,
|
||||
CompileEnv *envPtr);
|
||||
MODULE_SCOPE ExecEnv * TclCreateExecEnv(Tcl_Interp *interp, int size);
|
||||
MODULE_SCOPE Tcl_Obj * TclCreateLiteral(Interp *iPtr, char *bytes,
|
||||
MODULE_SCOPE Tcl_Obj * TclCreateLiteral(Interp *iPtr, const char *bytes,
|
||||
int length, unsigned int hash, int *newPtr,
|
||||
Namespace *nsPtr, int flags,
|
||||
LiteralEntry **globalPtrPtr);
|
||||
@@ -1210,29 +1210,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
|
||||
#define LITERAL_ON_HEAP 0x01
|
||||
#define LITERAL_CMD_NAME 0x02
|
||||
|
||||
/*
|
||||
* Form of TclRegisterLiteral with flags == 0. In that case, it is safe to
|
||||
* cast away constness, and it is cleanest to do that here, all in one place.
|
||||
*
|
||||
* int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes,
|
||||
* int length);
|
||||
*/
|
||||
|
||||
#define TclRegisterNewLiteral(envPtr, bytes, length) \
|
||||
TclRegisterLiteral(envPtr, (char *)(bytes), length, /*flags*/ 0)
|
||||
|
||||
/*
|
||||
* Form of TclRegisterLiteral with flags == LITERAL_CMD_NAME. In that case, it
|
||||
* is safe to cast away constness, and it is cleanest to do that here, all in
|
||||
* one place.
|
||||
*
|
||||
* int TclRegisterNewNSLiteral(CompileEnv *envPtr, const char *bytes,
|
||||
* int length);
|
||||
*/
|
||||
|
||||
#define TclRegisterNewCmdLiteral(envPtr, bytes, length) \
|
||||
TclRegisterLiteral(envPtr, (char *)(bytes), length, LITERAL_CMD_NAME)
|
||||
#define LITERAL_UNSHARED 0x04
|
||||
|
||||
/*
|
||||
* Macro used to manually adjust the stack requirements; used in cases where
|
||||
@@ -1549,9 +1527,9 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
*/
|
||||
|
||||
#define PushLiteral(envPtr, string, length) \
|
||||
TclEmitPush(TclRegisterNewLiteral((envPtr), (string), (length)), (envPtr))
|
||||
TclEmitPush(TclRegisterLiteral(envPtr, string, length, 0), (envPtr))
|
||||
#define PushStringLiteral(envPtr, string) \
|
||||
PushLiteral((envPtr), (string), (int) (sizeof(string "") - 1))
|
||||
PushLiteral(envPtr, string, (int) (sizeof(string "") - 1))
|
||||
|
||||
/*
|
||||
* Macro to advance to the next token; it is more mnemonic than the address
|
||||
|
||||
+1
-7
@@ -359,14 +359,8 @@ typedef short int yytype_int16;
|
||||
#ifndef YYSIZE_T
|
||||
# ifdef __SIZE_TYPE__
|
||||
# define YYSIZE_T __SIZE_TYPE__
|
||||
# elif defined size_t
|
||||
# define YYSIZE_T size_t
|
||||
# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
|
||||
|| defined __cplusplus || defined _MSC_VER)
|
||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# define YYSIZE_T size_t
|
||||
# else
|
||||
# define YYSIZE_T unsigned int
|
||||
# define YYSIZE_T size_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
+43
-22
@@ -70,18 +70,12 @@ static inline void DeleteChainTable(struct Dict *dict);
|
||||
static inline Tcl_HashEntry *CreateChainEntry(struct Dict *dict,
|
||||
Tcl_Obj *keyPtr, int *newPtr);
|
||||
static inline int DeleteChainEntry(struct Dict *dict, Tcl_Obj *keyPtr);
|
||||
static int FinalizeDictUpdate(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int FinalizeDictWith(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int DictForNRCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int DictMapNRCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int DictForLoopCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int DictMapLoopCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc FinalizeDictUpdate;
|
||||
static Tcl_NRPostProc FinalizeDictWith;
|
||||
static Tcl_ObjCmdProc DictForNRCmd;
|
||||
static Tcl_ObjCmdProc DictMapNRCmd;
|
||||
static Tcl_NRPostProc DictForLoopCallback;
|
||||
static Tcl_NRPostProc DictMapLoopCallback;
|
||||
|
||||
/*
|
||||
* Table of dict subcommand names and implementations.
|
||||
@@ -2288,7 +2282,7 @@ DictAppendCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Tcl_Obj *dictPtr, *valuePtr, *resultPtr;
|
||||
int i, allocatedDict = 0;
|
||||
int allocatedDict = 0;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
|
||||
@@ -2311,17 +2305,44 @@ DictAppendCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (valuePtr == NULL) {
|
||||
TclNewObj(valuePtr);
|
||||
} else if (Tcl_IsShared(valuePtr)) {
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
if ((objc > 3) || (valuePtr == NULL)) {
|
||||
/* Only go through append activites when something will change. */
|
||||
Tcl_Obj *appendObjPtr = NULL;
|
||||
|
||||
if (objc > 3) {
|
||||
/* Something to append */
|
||||
|
||||
if (objc == 4) {
|
||||
appendObjPtr = objv[3];
|
||||
} else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
|
||||
objc-3, objv+3, &appendObjPtr)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (appendObjPtr == NULL) {
|
||||
/* => (objc == 3) => (valuePtr == NULL) */
|
||||
TclNewObj(valuePtr);
|
||||
} else if (valuePtr == NULL) {
|
||||
valuePtr = appendObjPtr;
|
||||
appendObjPtr = NULL;
|
||||
}
|
||||
|
||||
if (appendObjPtr) {
|
||||
if (Tcl_IsShared(valuePtr)) {
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
}
|
||||
|
||||
Tcl_AppendObjToObj(valuePtr, appendObjPtr);
|
||||
}
|
||||
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
}
|
||||
|
||||
for (i=3 ; i<objc ; i++) {
|
||||
Tcl_AppendObjToObj(valuePtr, objv[i]);
|
||||
}
|
||||
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
/*
|
||||
* Even if nothing changed, we still overwrite so that variable
|
||||
* trace expectations are met.
|
||||
*/
|
||||
|
||||
resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
|
||||
TCL_LEAVE_ERR_MSG);
|
||||
|
||||
+136
-3
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 1996-1998 Sun Microsystems, Inc.
|
||||
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
|
||||
* Copyright (c) 2013 Donal K. Fellows.
|
||||
* Copyright (c) 2013-2016 Donal K. Fellows.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -193,7 +193,7 @@ TclPrintObject(
|
||||
char *bytes;
|
||||
int length;
|
||||
|
||||
bytes = Tcl_GetStringFromObj(objPtr, &length);
|
||||
bytes = TclGetStringFromObj(objPtr, &length);
|
||||
TclPrintSource(outFile, bytes, TclMin(length, maxChars));
|
||||
}
|
||||
|
||||
@@ -650,7 +650,7 @@ FormatInstruction(
|
||||
int length;
|
||||
|
||||
Tcl_AppendToObj(bufferObj, "\t# ", -1);
|
||||
bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length);
|
||||
bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length);
|
||||
PrintSourceToObj(bufferObj, bytes, TclMin(length, 40));
|
||||
} else if (suffixBuffer[0]) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer);
|
||||
@@ -1279,9 +1279,11 @@ Tcl_DisassembleObjCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
static const char *const types[] = {
|
||||
"constructor", "destructor",
|
||||
"lambda", "method", "objmethod", "proc", "script", NULL
|
||||
};
|
||||
enum Types {
|
||||
DISAS_CLASS_CONSTRUCTOR, DISAS_CLASS_DESTRUCTOR,
|
||||
DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC,
|
||||
DISAS_SCRIPT
|
||||
};
|
||||
@@ -1290,6 +1292,7 @@ Tcl_DisassembleObjCmd(
|
||||
Proc *procPtr = NULL;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Object *oPtr;
|
||||
Method *methodPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "type ...");
|
||||
@@ -1384,6 +1387,136 @@ Tcl_DisassembleObjCmd(
|
||||
codeObjPtr = objv[2];
|
||||
break;
|
||||
|
||||
case DISAS_CLASS_CONSTRUCTOR:
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "className");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the body of a constructor.
|
||||
*/
|
||||
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (oPtr->classPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" is not a class", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
|
||||
TclGetString(objv[2]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
methodPtr = oPtr->classPtr->constructorPtr;
|
||||
if (methodPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" has no defined constructor",
|
||||
TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"CONSRUCTOR", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
procPtr = TclOOGetProcFromMethod(methodPtr);
|
||||
if (procPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"body not available for this kind of constructor", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"METHODTYPE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile if necessary.
|
||||
*/
|
||||
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
* Yes, this is ugly, but we need to pass the namespace in to the
|
||||
* compiler in two places.
|
||||
*/
|
||||
|
||||
cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
|
||||
procPtr->cmdPtr = &cmd;
|
||||
result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
|
||||
(Namespace *) oPtr->namespacePtr, "body of constructor",
|
||||
TclGetString(objv[2]));
|
||||
procPtr->cmdPtr = NULL;
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
codeObjPtr = procPtr->bodyPtr;
|
||||
break;
|
||||
|
||||
case DISAS_CLASS_DESTRUCTOR:
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "className");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the body of a destructor.
|
||||
*/
|
||||
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (oPtr->classPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" is not a class", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
|
||||
TclGetString(objv[2]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
methodPtr = oPtr->classPtr->destructorPtr;
|
||||
if (methodPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" has no defined destructor",
|
||||
TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"DESRUCTOR", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
procPtr = TclOOGetProcFromMethod(methodPtr);
|
||||
if (procPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"body not available for this kind of destructor", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"METHODTYPE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile if necessary.
|
||||
*/
|
||||
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
* Yes, this is ugly, but we need to pass the namespace in to the
|
||||
* compiler in two places.
|
||||
*/
|
||||
|
||||
cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
|
||||
procPtr->cmdPtr = &cmd;
|
||||
result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
|
||||
(Namespace *) oPtr->namespacePtr, "body of destructor",
|
||||
TclGetString(objv[2]));
|
||||
procPtr->cmdPtr = NULL;
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
codeObjPtr = procPtr->bodyPtr;
|
||||
break;
|
||||
|
||||
case DISAS_CLASS_METHOD:
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "className methodName");
|
||||
|
||||
@@ -355,6 +355,7 @@ DupEncodingIntRep(
|
||||
Tcl_Obj *dupPtr)
|
||||
{
|
||||
dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes);
|
||||
dupPtr->typePtr = &encodingType;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3632,7 +3633,7 @@ InitializeEncodingSearchPath(
|
||||
if (*encodingPtr) {
|
||||
((Encoding *)(*encodingPtr))->refCount++;
|
||||
}
|
||||
bytes = Tcl_GetStringFromObj(searchPathObj, &numBytes);
|
||||
bytes = TclGetStringFromObj(searchPathObj, &numBytes);
|
||||
|
||||
*lengthPtr = numBytes;
|
||||
*valuePtr = ckalloc(numBytes + 1);
|
||||
|
||||
+254
-159
@@ -30,11 +30,10 @@ static int NsEnsembleStringOrder(const void *strPtr1,
|
||||
const void *strPtr2);
|
||||
static void DeleteEnsembleConfig(ClientData clientData);
|
||||
static void MakeCachedEnsembleCommand(Tcl_Obj *objPtr,
|
||||
EnsembleConfig *ensemblePtr,
|
||||
const char *subcmdName, Tcl_Obj *prefixObjPtr);
|
||||
EnsembleConfig *ensemblePtr, Tcl_HashEntry *hPtr,
|
||||
Tcl_Obj *fix);
|
||||
static void FreeEnsembleCmdRep(Tcl_Obj *objPtr);
|
||||
static void DupEnsembleCmdRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
|
||||
static void StringOfEnsembleCmdRep(Tcl_Obj *objPtr);
|
||||
static void CompileToInvokedCommand(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Tcl_Obj *replacements,
|
||||
Command *cmdPtr, CompileEnv *envPtr);
|
||||
@@ -42,6 +41,8 @@ static int CompileBasicNArgCommand(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
CompileEnv *envPtr);
|
||||
|
||||
static Tcl_NRPostProc FreeER;
|
||||
|
||||
/*
|
||||
* The lists of subcommands and options for the [namespace ensemble] command.
|
||||
*/
|
||||
@@ -77,14 +78,30 @@ enum EnsConfigOpts {
|
||||
* that implements it.
|
||||
*/
|
||||
|
||||
const Tcl_ObjType tclEnsembleCmdType = {
|
||||
static const Tcl_ObjType ensembleCmdType = {
|
||||
"ensembleCommand", /* the type's name */
|
||||
FreeEnsembleCmdRep, /* freeIntRepProc */
|
||||
DupEnsembleCmdRep, /* dupIntRepProc */
|
||||
StringOfEnsembleCmdRep, /* updateStringProc */
|
||||
NULL, /* updateStringProc */
|
||||
NULL /* setFromAnyProc */
|
||||
};
|
||||
|
||||
/*
|
||||
* The internal rep for caching ensemble subcommand lookups and
|
||||
* spell corrections.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int epoch; /* Used to confirm when the data in this
|
||||
* really structure matches up with the
|
||||
* ensemble. */
|
||||
Command *token; /* Reference to the command for which this
|
||||
* structure is a cache of the resolution. */
|
||||
Tcl_Obj *fix; /* Corrected spelling, if needed. */
|
||||
Tcl_HashEntry *hPtr; /* Direct link to entry in the subcommand
|
||||
* hash table. */
|
||||
} EnsembleCmdRep;
|
||||
|
||||
|
||||
static inline Tcl_Obj *
|
||||
NewNsObj(
|
||||
@@ -1643,6 +1660,8 @@ NsEnsembleImplementationCmdNR(
|
||||
* names. */
|
||||
int reparseCount = 0; /* Number of reparses. */
|
||||
Tcl_Obj *errorObj; /* Used for building error messages. */
|
||||
Tcl_Obj *subObj;
|
||||
int subIdx;
|
||||
|
||||
/*
|
||||
* Must recheck objc, since numParameters might have changed. Cf. test
|
||||
@@ -1650,24 +1669,18 @@ NsEnsembleImplementationCmdNR(
|
||||
*/
|
||||
|
||||
restartEnsembleParse:
|
||||
if (objc < 2 + ensemblePtr->numParameters) {
|
||||
subIdx = 1 + ensemblePtr->numParameters;
|
||||
if (objc < subIdx + 1) {
|
||||
/*
|
||||
* We don't have a subcommand argument. Make error message.
|
||||
*/
|
||||
|
||||
Tcl_DString buf; /* Message being built */
|
||||
Tcl_Obj **elemPtrs; /* Parameter names */
|
||||
int len; /* Number of parameters to append */
|
||||
|
||||
Tcl_DStringInit(&buf);
|
||||
if (ensemblePtr->parameterList == NULL) {
|
||||
len = 0;
|
||||
} else if (TclListObjGetElements(NULL, ensemblePtr->parameterList,
|
||||
&len, &elemPtrs) != TCL_OK) {
|
||||
Tcl_Panic("List of ensemble parameters is not a list");
|
||||
}
|
||||
for (; len>0; len--,elemPtrs++) {
|
||||
TclDStringAppendObj(&buf, *elemPtrs);
|
||||
if (ensemblePtr->parameterList) {
|
||||
Tcl_DStringAppend(&buf,
|
||||
TclGetString(ensemblePtr->parameterList), -1);
|
||||
TclDStringAppendLiteral(&buf, " ");
|
||||
}
|
||||
TclDStringAppendLiteral(&buf, "subcommand ?arg ...?");
|
||||
@@ -1695,6 +1708,8 @@ NsEnsembleImplementationCmdNR(
|
||||
* up in there and go straight to dispatch.
|
||||
*/
|
||||
|
||||
subObj = objv[subIdx];
|
||||
|
||||
if (ensemblePtr->epoch == ensemblePtr->nsPtr->exportLookupEpoch) {
|
||||
/*
|
||||
* Table of subcommands is still valid; therefore there might be a
|
||||
@@ -1703,15 +1718,16 @@ NsEnsembleImplementationCmdNR(
|
||||
* part where we do the invocation of the subcommand.
|
||||
*/
|
||||
|
||||
if (objv[1+ensemblePtr->numParameters]->typePtr==&tclEnsembleCmdType){
|
||||
EnsembleCmdRep *ensembleCmd = objv[1+ensemblePtr->numParameters]
|
||||
->internalRep.twoPtrValue.ptr1;
|
||||
if (subObj->typePtr==&ensembleCmdType){
|
||||
EnsembleCmdRep *ensembleCmd = subObj->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
if (ensembleCmd->nsPtr == ensemblePtr->nsPtr &&
|
||||
ensembleCmd->epoch == ensemblePtr->epoch &&
|
||||
ensembleCmd->token == ensemblePtr->token) {
|
||||
prefixObj = ensembleCmd->realPrefixObj;
|
||||
if (ensembleCmd->epoch == ensemblePtr->epoch &&
|
||||
ensembleCmd->token == (Command *)ensemblePtr->token) {
|
||||
prefixObj = Tcl_GetHashValue(ensembleCmd->hPtr);
|
||||
Tcl_IncrRefCount(prefixObj);
|
||||
if (ensembleCmd->fix) {
|
||||
TclSpellFix(interp, objv, objc, subIdx, subObj, ensembleCmd->fix);
|
||||
}
|
||||
goto runResultingSubcommand;
|
||||
}
|
||||
}
|
||||
@@ -1726,18 +1742,14 @@ NsEnsembleImplementationCmdNR(
|
||||
*/
|
||||
|
||||
hPtr = Tcl_FindHashEntry(&ensemblePtr->subcommandTable,
|
||||
TclGetString(objv[1 + ensemblePtr->numParameters]));
|
||||
TclGetString(subObj));
|
||||
if (hPtr != NULL) {
|
||||
char *fullName = Tcl_GetHashKey(&ensemblePtr->subcommandTable, hPtr);
|
||||
|
||||
prefixObj = Tcl_GetHashValue(hPtr);
|
||||
|
||||
/*
|
||||
* Cache for later in the subcommand object.
|
||||
*/
|
||||
|
||||
MakeCachedEnsembleCommand(objv[1 + ensemblePtr->numParameters],
|
||||
ensemblePtr, fullName, prefixObj);
|
||||
MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, NULL);
|
||||
} else if (!(ensemblePtr->flags & TCL_ENSEMBLE_PREFIX)) {
|
||||
/*
|
||||
* Could not map, no prefixing, go to unknown/error handling.
|
||||
@@ -1757,9 +1769,9 @@ NsEnsembleImplementationCmdNR(
|
||||
char *fullName = NULL; /* Full name of the subcommand. */
|
||||
int stringLength, i;
|
||||
int tableLength = ensemblePtr->subcommandTable.numEntries;
|
||||
Tcl_Obj *fix;
|
||||
|
||||
subcmdName = TclGetString(objv[1 + ensemblePtr->numParameters]);
|
||||
stringLength = objv[1 + ensemblePtr->numParameters]->length;
|
||||
subcmdName = TclGetStringFromObj(subObj, &stringLength);
|
||||
for (i=0 ; i<tableLength ; i++) {
|
||||
register int cmp = strncmp(subcmdName,
|
||||
ensemblePtr->subcommandArrayPtr[i],
|
||||
@@ -1799,16 +1811,22 @@ NsEnsembleImplementationCmdNR(
|
||||
Tcl_Panic("full name %s not found in supposedly synchronized hash",
|
||||
fullName);
|
||||
}
|
||||
prefixObj = Tcl_GetHashValue(hPtr);
|
||||
|
||||
/*
|
||||
* Record the spelling correction for usage message.
|
||||
*/
|
||||
|
||||
fix = Tcl_NewStringObj(fullName, -1);
|
||||
|
||||
/*
|
||||
* Cache for later in the subcommand object.
|
||||
*/
|
||||
|
||||
MakeCachedEnsembleCommand(objv[1 + ensemblePtr->numParameters],
|
||||
ensemblePtr, fullName, prefixObj);
|
||||
MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, fix);
|
||||
TclSpellFix(interp, objv, objc, subIdx, subObj, fix);
|
||||
}
|
||||
|
||||
prefixObj = Tcl_GetHashValue(hPtr);
|
||||
Tcl_IncrRefCount(prefixObj);
|
||||
runResultingSubcommand:
|
||||
|
||||
@@ -1827,47 +1845,26 @@ NsEnsembleImplementationCmdNR(
|
||||
*/
|
||||
|
||||
{
|
||||
Tcl_Obj **prefixObjv; /* The list of objects to substitute in as the
|
||||
* target command prefix. */
|
||||
Tcl_Obj *copyPtr; /* The actual list of words to dispatch to.
|
||||
* Will be freed by the dispatch engine. */
|
||||
int prefixObjc, copyObjc;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Obj **copyObjv;
|
||||
int copyObjc, prefixObjc;
|
||||
|
||||
/*
|
||||
* Get the prefix that we're rewriting to. To do this we need to
|
||||
* ensure that the internal representation of the list does not change
|
||||
* so that we can safely keep the internal representations of the
|
||||
* elements in the list.
|
||||
*
|
||||
* TODO: Use conventional list operations to make this code sane!
|
||||
*/
|
||||
Tcl_ListObjLength(NULL, prefixObj, &prefixObjc);
|
||||
|
||||
TclListObjGetElements(NULL, prefixObj, &prefixObjc, &prefixObjv);
|
||||
|
||||
copyObjc = objc - 2 + prefixObjc;
|
||||
copyPtr = Tcl_NewListObj(copyObjc, NULL);
|
||||
if (copyObjc > 0) {
|
||||
register Tcl_Obj **copyObjv;
|
||||
/* Space used to construct the list of
|
||||
* arguments to pass to the command that
|
||||
* implements the ensemble subcommand. */
|
||||
register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
|
||||
register int i;
|
||||
|
||||
listRepPtr->elemCount = copyObjc;
|
||||
copyObjv = &listRepPtr->elements;
|
||||
memcpy(copyObjv, prefixObjv, sizeof(Tcl_Obj *) * prefixObjc);
|
||||
memcpy(copyObjv+prefixObjc, objv+1,
|
||||
sizeof(Tcl_Obj *) * ensemblePtr->numParameters);
|
||||
memcpy(copyObjv+prefixObjc+ensemblePtr->numParameters,
|
||||
objv+ensemblePtr->numParameters+2,
|
||||
sizeof(Tcl_Obj *) * (objc-ensemblePtr->numParameters-2));
|
||||
|
||||
for (i=0; i < copyObjc; i++) {
|
||||
Tcl_IncrRefCount(copyObjv[i]);
|
||||
}
|
||||
if (objc == 2) {
|
||||
copyPtr = TclListObjCopy(NULL, prefixObj);
|
||||
} else {
|
||||
copyPtr = Tcl_NewListObj(objc - 2 + prefixObjc, NULL);
|
||||
Tcl_ListObjAppendList(NULL, copyPtr, prefixObj);
|
||||
Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
|
||||
ensemblePtr->numParameters, objv + 1);
|
||||
Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
|
||||
objc - 2 - ensemblePtr->numParameters,
|
||||
objv + 2 + ensemblePtr->numParameters);
|
||||
}
|
||||
Tcl_IncrRefCount(copyPtr);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, copyPtr, NULL, NULL, NULL);
|
||||
TclDecrRefCount(prefixObj);
|
||||
|
||||
/*
|
||||
@@ -1876,25 +1873,10 @@ NsEnsembleImplementationCmdNR(
|
||||
* count both as inserted and removed arguments.
|
||||
*/
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs =
|
||||
2 + ensemblePtr->numParameters;
|
||||
iPtr->ensembleRewrite.numInsertedObjs =
|
||||
prefixObjc + ensemblePtr->numParameters;
|
||||
if (TclInitRewriteEnsemble(interp, 2 + ensemblePtr->numParameters,
|
||||
prefixObjc + ensemblePtr->numParameters, objv)) {
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL,
|
||||
NULL);
|
||||
} else {
|
||||
register int ni = 2 + ensemblePtr->numParameters
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
/* Position in objv of new front of insertion
|
||||
* relative to old one. */
|
||||
if (ni > 0) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += ni;
|
||||
iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-1;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1902,7 +1884,8 @@ NsEnsembleImplementationCmdNR(
|
||||
*/
|
||||
|
||||
TclSkipTailcall(interp);
|
||||
return TclNREvalObjEx(interp, copyPtr, TCL_EVAL_INVOKE, NULL,INT_MIN);
|
||||
Tcl_ListObjGetElements(NULL, copyPtr, ©Objc, ©Objv);
|
||||
return TclNREvalObjv(interp, copyObjc, copyObjv, TCL_EVAL_INVOKE, NULL);
|
||||
}
|
||||
|
||||
unknownOrAmbiguousSubcommand:
|
||||
@@ -1934,20 +1917,17 @@ NsEnsembleImplementationCmdNR(
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
|
||||
TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
|
||||
TclGetString(subObj), NULL);
|
||||
if (ensemblePtr->subcommandTable.numEntries == 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unknown subcommand \"%s\": namespace %s does not"
|
||||
" export any commands",
|
||||
TclGetString(objv[1+ensemblePtr->numParameters]),
|
||||
" export any commands", TclGetString(subObj),
|
||||
ensemblePtr->nsPtr->fullName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
|
||||
TclGetString(objv[1+ensemblePtr->numParameters]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ",
|
||||
(ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""),
|
||||
TclGetString(objv[1+ensemblePtr->numParameters]));
|
||||
TclGetString(subObj));
|
||||
if (ensemblePtr->subcommandTable.numEntries == 1) {
|
||||
Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[0], -1);
|
||||
} else {
|
||||
@@ -2013,7 +1993,7 @@ TclInitRewriteEnsemble(
|
||||
|
||||
if (numIns < numRemoved) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += numRemoved - numIns;
|
||||
iPtr->ensembleRewrite.numInsertedObjs += numInserted - 1;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = numInserted;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs += numInserted - numRemoved;
|
||||
}
|
||||
@@ -2053,6 +2033,149 @@ TclResetRewriteEnsemble(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclSpellFix --
|
||||
*
|
||||
* Record a spelling correction that needs making in the
|
||||
* generation of the WrongNumArgs usage message.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Can create an alternative ensemble rewrite structure.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
FreeER(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Tcl_Obj **tmp = (Tcl_Obj **)data[0];
|
||||
|
||||
ckfree(tmp[2]);
|
||||
ckfree(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
TclSpellFix(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv,
|
||||
int objc,
|
||||
int badIdx,
|
||||
Tcl_Obj *bad,
|
||||
Tcl_Obj *fix)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Obj *const *search;
|
||||
Tcl_Obj **store;
|
||||
int idx;
|
||||
int size;
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 0;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 0;
|
||||
}
|
||||
|
||||
/* Compute the valid length of the ensemble root */
|
||||
|
||||
size = iPtr->ensembleRewrite.numRemovedObjs + objc
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
|
||||
search = iPtr->ensembleRewrite.sourceObjs;
|
||||
if (search[0] == NULL) {
|
||||
/* Awful casting abuse here */
|
||||
search = (Tcl_Obj *const *) search[1];
|
||||
}
|
||||
|
||||
if (badIdx < iPtr->ensembleRewrite.numInsertedObjs) {
|
||||
/*
|
||||
* Misspelled value was inserted. We cannot directly jump
|
||||
* to the bad value, but have to search.
|
||||
*/
|
||||
idx = 1;
|
||||
while (idx < size) {
|
||||
if (search[idx] == bad) {
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if (idx == size) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Jump to the misspelled value. */
|
||||
idx = iPtr->ensembleRewrite.numRemovedObjs + badIdx
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
|
||||
/* Verify */
|
||||
if (search[idx] != bad) {
|
||||
Tcl_Panic("SpellFix: programming error");
|
||||
}
|
||||
}
|
||||
|
||||
search = iPtr->ensembleRewrite.sourceObjs;
|
||||
if (search[0] == NULL) {
|
||||
store = (Tcl_Obj **)search[2];
|
||||
} else {
|
||||
Tcl_Obj **tmp = ckalloc(3 * sizeof(Tcl_Obj *));
|
||||
tmp[0] = NULL;
|
||||
tmp[1] = (Tcl_Obj *)iPtr->ensembleRewrite.sourceObjs;
|
||||
tmp[2] = (Tcl_Obj *)ckalloc(size * sizeof(Tcl_Obj *));
|
||||
memcpy(tmp[2], tmp[1], size*sizeof(Tcl_Obj *));
|
||||
|
||||
iPtr->ensembleRewrite.sourceObjs = (Tcl_Obj *const *) tmp;
|
||||
TclNRAddCallback(interp, FreeER, tmp, NULL, NULL, NULL);
|
||||
store = (Tcl_Obj **)tmp[2];
|
||||
}
|
||||
|
||||
store[idx] = fix;
|
||||
Tcl_IncrRefCount(fix);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, fix, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclFetchEnsembleRoot --
|
||||
*
|
||||
* Returns the root of ensemble rewriting, if any.
|
||||
* If no root exists, returns objv instead.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *const *
|
||||
TclFetchEnsembleRoot(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv,
|
||||
int objc,
|
||||
int *objcPtr)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs) {
|
||||
*objcPtr = objc + iPtr->ensembleRewrite.numRemovedObjs
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
return iPtr->ensembleRewrite.sourceObjs;
|
||||
}
|
||||
*objcPtr = objc;
|
||||
return objv;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -2218,17 +2341,17 @@ static void
|
||||
MakeCachedEnsembleCommand(
|
||||
Tcl_Obj *objPtr,
|
||||
EnsembleConfig *ensemblePtr,
|
||||
const char *subcommandName,
|
||||
Tcl_Obj *prefixObjPtr)
|
||||
Tcl_HashEntry *hPtr,
|
||||
Tcl_Obj *fix)
|
||||
{
|
||||
register EnsembleCmdRep *ensembleCmd;
|
||||
int length;
|
||||
|
||||
if (objPtr->typePtr == &tclEnsembleCmdType) {
|
||||
if (objPtr->typePtr == &ensembleCmdType) {
|
||||
ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
|
||||
TclNsDecrRefCount(ensembleCmd->nsPtr);
|
||||
ckfree(ensembleCmd->fullSubcmdName);
|
||||
TclCleanupCommandMacro(ensembleCmd->token);
|
||||
if (ensembleCmd->fix) {
|
||||
Tcl_DecrRefCount(ensembleCmd->fix);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Kill the old internal rep, and replace it with a brand new one of
|
||||
@@ -2238,22 +2361,21 @@ MakeCachedEnsembleCommand(
|
||||
TclFreeIntRep(objPtr);
|
||||
ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
|
||||
objPtr->typePtr = &tclEnsembleCmdType;
|
||||
objPtr->typePtr = &ensembleCmdType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the internal rep.
|
||||
*/
|
||||
|
||||
ensembleCmd->nsPtr = ensemblePtr->nsPtr;
|
||||
ensembleCmd->epoch = ensemblePtr->epoch;
|
||||
ensembleCmd->token = ensemblePtr->token;
|
||||
ensemblePtr->nsPtr->refCount++;
|
||||
ensembleCmd->realPrefixObj = prefixObjPtr;
|
||||
length = strlen(subcommandName)+1;
|
||||
ensembleCmd->fullSubcmdName = ckalloc(length);
|
||||
memcpy(ensembleCmd->fullSubcmdName, subcommandName, (unsigned) length);
|
||||
Tcl_IncrRefCount(ensembleCmd->realPrefixObj);
|
||||
ensembleCmd->token = (Command *) ensemblePtr->token;
|
||||
ensembleCmd->token->refCount++;
|
||||
if (fix) {
|
||||
Tcl_IncrRefCount(fix);
|
||||
}
|
||||
ensembleCmd->fix = fix;
|
||||
ensembleCmd->hPtr = hPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2634,9 +2756,10 @@ FreeEnsembleCmdRep(
|
||||
{
|
||||
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
Tcl_DecrRefCount(ensembleCmd->realPrefixObj);
|
||||
ckfree(ensembleCmd->fullSubcmdName);
|
||||
TclNsDecrRefCount(ensembleCmd->nsPtr);
|
||||
TclCleanupCommandMacro(ensembleCmd->token);
|
||||
if (ensembleCmd->fix) {
|
||||
Tcl_DecrRefCount(ensembleCmd->fix);
|
||||
}
|
||||
ckfree(ensembleCmd);
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
@@ -2666,48 +2789,17 @@ DupEnsembleCmdRep(
|
||||
{
|
||||
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep));
|
||||
int length = strlen(ensembleCmd->fullSubcmdName);
|
||||
|
||||
copyPtr->typePtr = &tclEnsembleCmdType;
|
||||
copyPtr->typePtr = &ensembleCmdType;
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
|
||||
ensembleCopy->nsPtr = ensembleCmd->nsPtr;
|
||||
ensembleCopy->epoch = ensembleCmd->epoch;
|
||||
ensembleCopy->token = ensembleCmd->token;
|
||||
ensembleCopy->nsPtr->refCount++;
|
||||
ensembleCopy->realPrefixObj = ensembleCmd->realPrefixObj;
|
||||
Tcl_IncrRefCount(ensembleCopy->realPrefixObj);
|
||||
ensembleCopy->fullSubcmdName = ckalloc(length + 1);
|
||||
memcpy(ensembleCopy->fullSubcmdName, ensembleCmd->fullSubcmdName,
|
||||
(unsigned) length+1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* StringOfEnsembleCmdRep --
|
||||
*
|
||||
* Creates a string representation of a Tcl_Obj that holds a subcommand
|
||||
* of an ensemble.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The object gains a string (UTF-8) representation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
StringOfEnsembleCmdRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
int length = strlen(ensembleCmd->fullSubcmdName);
|
||||
|
||||
objPtr->length = length;
|
||||
objPtr->bytes = ckalloc(length + 1);
|
||||
memcpy(objPtr->bytes, ensembleCmd->fullSubcmdName, (unsigned) length+1);
|
||||
ensembleCopy->token->refCount++;
|
||||
ensembleCopy->fix = ensembleCmd->fix;
|
||||
if (ensembleCopy->fix) {
|
||||
Tcl_IncrRefCount(ensembleCopy->fix);
|
||||
}
|
||||
ensembleCopy->hPtr = ensembleCmd->hPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2825,7 +2917,7 @@ TclCompileEnsemble(
|
||||
goto failed;
|
||||
}
|
||||
for (i=0 ; i<len ; i++) {
|
||||
str = Tcl_GetStringFromObj(elems[i], &sclen);
|
||||
str = TclGetStringFromObj(elems[i], &sclen);
|
||||
if ((sclen == (int) numBytes) && !memcmp(word, str, numBytes)) {
|
||||
/*
|
||||
* Exact match! Excellent!
|
||||
@@ -3043,7 +3135,7 @@ TclCompileEnsemble(
|
||||
* any extra elements that might have been appended by failing
|
||||
* pathways above.
|
||||
*/
|
||||
(void) Tcl_ListObjReplace(NULL, replaced, depth-1, INT_MAX, 0, NULL);
|
||||
(void) Tcl_ListObjReplace(NULL, replaced, depth-1, LIST_MAX, 0, NULL);
|
||||
|
||||
/*
|
||||
* TODO: Reconsider whether we ought to call CompileToInvokedCommand()
|
||||
@@ -3214,7 +3306,7 @@ CompileToInvokedCommand(
|
||||
Tcl_Token *tokPtr;
|
||||
Tcl_Obj *objPtr, **words;
|
||||
char *bytes;
|
||||
int length, i, numWords, cmdLit;
|
||||
int length, i, numWords, cmdLit, extraLiteralFlags = LITERAL_CMD_NAME;
|
||||
DefineLineInformation;
|
||||
|
||||
/*
|
||||
@@ -3227,15 +3319,15 @@ CompileToInvokedCommand(
|
||||
for (i = 0, tokPtr = parsePtr->tokenPtr; i < parsePtr->numWords;
|
||||
i++, tokPtr = TokenAfter(tokPtr)) {
|
||||
if (i > 0 && i < numWords+1) {
|
||||
bytes = Tcl_GetStringFromObj(words[i-1], &length);
|
||||
bytes = TclGetStringFromObj(words[i-1], &length);
|
||||
PushLiteral(envPtr, bytes, length);
|
||||
continue;
|
||||
}
|
||||
|
||||
SetLineInformation(i);
|
||||
if (tokPtr->type == TCL_TOKEN_SIMPLE_WORD) {
|
||||
int literal = TclRegisterNewLiteral(envPtr,
|
||||
tokPtr[1].start, tokPtr[1].size);
|
||||
int literal = TclRegisterLiteral(envPtr,
|
||||
tokPtr[1].start, tokPtr[1].size, 0);
|
||||
|
||||
if (envPtr->clNext) {
|
||||
TclContinuationsEnterDerived(
|
||||
@@ -3257,7 +3349,10 @@ CompileToInvokedCommand(
|
||||
objPtr = Tcl_NewObj();
|
||||
Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
|
||||
bytes = Tcl_GetStringFromObj(objPtr, &length);
|
||||
cmdLit = TclRegisterNewCmdLiteral(envPtr, bytes, length);
|
||||
if ((cmdPtr != NULL) && (cmdPtr->flags & CMD_VIA_RESOLVER)) {
|
||||
extraLiteralFlags |= LITERAL_UNSHARED;
|
||||
}
|
||||
cmdLit = TclRegisterLiteral(envPtr, bytes, length, extraLiteralFlags);
|
||||
TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLit), cmdPtr);
|
||||
TclEmitPush(cmdLit, envPtr);
|
||||
TclDecrRefCount(objPtr);
|
||||
|
||||
@@ -1465,6 +1465,8 @@ VwaitVarProc(
|
||||
int *donePtr = clientData;
|
||||
|
||||
*donePtr = 1;
|
||||
Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
|
||||
VwaitVarProc, clientData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+92
-277
@@ -19,7 +19,6 @@
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
#include "tommath.h"
|
||||
#include "tclStringRep.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
@@ -1554,7 +1553,7 @@ CompileExprObj(
|
||||
*/
|
||||
|
||||
if (compEnv.codeNext == compEnv.codeStart) {
|
||||
TclEmitPush(TclRegisterNewLiteral(&compEnv, "0", 1),
|
||||
TclEmitPush(TclRegisterLiteral(&compEnv, "0", 1, 0),
|
||||
&compEnv);
|
||||
}
|
||||
|
||||
@@ -2070,6 +2069,13 @@ TclNRExecuteByteCode(
|
||||
iPtr->stats.numExecutions++;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Test namespace-50.9 demonstrates the need for this call.
|
||||
* Use a --enable-symbols=mem bug to see.
|
||||
*/
|
||||
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
|
||||
/*
|
||||
* Push the callback for bytecode execution
|
||||
*/
|
||||
@@ -2678,154 +2684,18 @@ TEBCresume(
|
||||
NEXT_INST_F(5, 0, 0);
|
||||
}
|
||||
|
||||
case INST_STR_CONCAT1: {
|
||||
int appendLen = 0;
|
||||
char *bytes, *p;
|
||||
Tcl_Obj **currPtr;
|
||||
int onlyb = 1;
|
||||
case INST_STR_CONCAT1:
|
||||
|
||||
opnd = TclGetUInt1AtPtr(pc+1);
|
||||
|
||||
/*
|
||||
* Detect only-bytearray-or-null case.
|
||||
*/
|
||||
|
||||
for (currPtr=&OBJ_AT_DEPTH(opnd-1); currPtr<=&OBJ_AT_TOS; currPtr++) {
|
||||
if (((*currPtr)->typePtr != &tclByteArrayType)
|
||||
&& ((*currPtr)->bytes != tclEmptyStringRep)) {
|
||||
onlyb = 0;
|
||||
break;
|
||||
} else if (((*currPtr)->typePtr == &tclByteArrayType) &&
|
||||
((*currPtr)->bytes != NULL)) {
|
||||
onlyb = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the length to be appended.
|
||||
*/
|
||||
|
||||
if (onlyb) {
|
||||
for (currPtr = &OBJ_AT_DEPTH(opnd-2);
|
||||
appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
|
||||
if ((*currPtr)->bytes != tclEmptyStringRep) {
|
||||
Tcl_GetByteArrayFromObj(*currPtr, &length);
|
||||
appendLen += length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (currPtr = &OBJ_AT_DEPTH(opnd-2);
|
||||
appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
|
||||
bytes = TclGetStringFromObj(*currPtr, &length);
|
||||
if (bytes != NULL) {
|
||||
appendLen += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appendLen < 0) {
|
||||
/* TODO: convert panic to error ? */
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
/*
|
||||
* If nothing is to be appended, just return the first object by
|
||||
* dropping all the others from the stack; this saves both the
|
||||
* computation and copy of the string rep of the first object,
|
||||
* enabling the fast '$x[set x {}]' idiom for 'K $x [set x {}]'.
|
||||
*/
|
||||
|
||||
if (appendLen == 0) {
|
||||
TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
|
||||
NEXT_INST_V(2, (opnd-1), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the first object is shared, we need a new obj for the result;
|
||||
* otherwise, we can reuse the first object. In any case, make sure it
|
||||
* has enough room to accomodate all the concatenated bytes. Note that
|
||||
* if it is unshared its bytes are copied by ckrealloc, so that we set
|
||||
* the loop parameters to avoid copying them again: p points to the
|
||||
* end of the already copied bytes, currPtr to the second object.
|
||||
*/
|
||||
|
||||
objResultPtr = OBJ_AT_DEPTH(opnd-1);
|
||||
if (!onlyb) {
|
||||
bytes = TclGetStringFromObj(objResultPtr, &length);
|
||||
if (length + appendLen < 0) {
|
||||
/* TODO: convert panic to error ? */
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
|
||||
INT_MAX);
|
||||
}
|
||||
#ifndef TCL_COMPILE_DEBUG
|
||||
if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
|
||||
TclFreeIntRep(objResultPtr);
|
||||
objResultPtr->bytes = ckrealloc(bytes, length+appendLen+1);
|
||||
objResultPtr->length = length + appendLen;
|
||||
p = TclGetString(objResultPtr) + length;
|
||||
currPtr = &OBJ_AT_DEPTH(opnd - 2);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
p = ckalloc(length + appendLen + 1);
|
||||
TclNewObj(objResultPtr);
|
||||
objResultPtr->bytes = p;
|
||||
objResultPtr->length = length + appendLen;
|
||||
currPtr = &OBJ_AT_DEPTH(opnd - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the remaining characters.
|
||||
*/
|
||||
|
||||
for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
|
||||
bytes = TclGetStringFromObj(*currPtr, &length);
|
||||
if (bytes != NULL) {
|
||||
memcpy(p, bytes, (size_t) length);
|
||||
p += length;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
} else {
|
||||
bytes = (char *) Tcl_GetByteArrayFromObj(objResultPtr, &length);
|
||||
if (length + appendLen < 0) {
|
||||
/* TODO: convert panic to error ? */
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
|
||||
INT_MAX);
|
||||
}
|
||||
#ifndef TCL_COMPILE_DEBUG
|
||||
if (!Tcl_IsShared(objResultPtr)) {
|
||||
bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
|
||||
length + appendLen);
|
||||
p = bytes + length;
|
||||
currPtr = &OBJ_AT_DEPTH(opnd - 2);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
TclNewObj(objResultPtr);
|
||||
bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
|
||||
length + appendLen);
|
||||
p = bytes;
|
||||
currPtr = &OBJ_AT_DEPTH(opnd - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the remaining characters.
|
||||
*/
|
||||
|
||||
for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
|
||||
if ((*currPtr)->bytes != tclEmptyStringRep) {
|
||||
bytes = (char *) Tcl_GetByteArrayFromObj(*currPtr,&length);
|
||||
memcpy(p, bytes, (size_t) length);
|
||||
p += length;
|
||||
}
|
||||
}
|
||||
if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
|
||||
opnd, &OBJ_AT_DEPTH(opnd-1), &objResultPtr)) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
|
||||
NEXT_INST_V(2, opnd, 1);
|
||||
}
|
||||
|
||||
case INST_CONCAT_STK:
|
||||
/*
|
||||
@@ -3153,35 +3023,34 @@ TEBCresume(
|
||||
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) {
|
||||
ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
|
||||
}
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = opnd;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 1;
|
||||
|
||||
TclInitRewriteEnsemble(interp, opnd, 1, objv);
|
||||
|
||||
{
|
||||
Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
|
||||
|
||||
Tcl_ListObjAppendElement(NULL, copyPtr, objPtr);
|
||||
Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
|
||||
objc - opnd, objv + opnd);
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
objPtr = copyPtr;
|
||||
}
|
||||
|
||||
DECACHE_STACK_INFO();
|
||||
pc += 6;
|
||||
TEBC_YIELD();
|
||||
|
||||
TclMarkTailcall(interp);
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL);
|
||||
return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN);
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, objPtr, NULL, NULL, NULL);
|
||||
return TclNREvalObjv(interp, objc, objv, TCL_EVAL_INVOKE, NULL);
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------
|
||||
@@ -4414,8 +4283,8 @@ TEBCresume(
|
||||
savedNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
|
||||
otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
|
||||
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
|
||||
/*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
|
||||
(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
|
||||
"access", /*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
|
||||
iPtr->varFramePtr->nsPtr = savedNsPtr;
|
||||
if (!otherPtr) {
|
||||
TRACE_ERROR(interp);
|
||||
@@ -5277,23 +5146,10 @@ TEBCresume(
|
||||
toIdx = objc-1;
|
||||
}
|
||||
if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) {
|
||||
/*
|
||||
* BEWARE! This is looking inside the implementation of the
|
||||
* list type.
|
||||
*/
|
||||
|
||||
List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
if (listPtr->refCount == 1) {
|
||||
for (index=toIdx+1; index<objc ; index++) {
|
||||
TclDecrRefCount(objv[index]);
|
||||
}
|
||||
listPtr->elemCount = toIdx+1;
|
||||
listPtr->canonicalFlag = 1;
|
||||
TclInvalidateStringRep(valuePtr);
|
||||
TRACE_APPEND(("%.30s\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(9, 0, 0);
|
||||
}
|
||||
Tcl_ListObjReplace(interp, valuePtr,
|
||||
toIdx + 1, LIST_MAX, 0, NULL);
|
||||
TRACE_APPEND(("%.30s\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(9, 0, 0);
|
||||
}
|
||||
objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx);
|
||||
} else {
|
||||
@@ -5718,17 +5574,6 @@ TEBCresume(
|
||||
|
||||
length3 = Tcl_GetCharLength(value3Ptr);
|
||||
|
||||
/*
|
||||
* Remove substring. In-place.
|
||||
*/
|
||||
|
||||
if (length3 == 0 && !Tcl_IsShared(valuePtr) && toIdx == length) {
|
||||
TclDecrRefCount(value3Ptr);
|
||||
Tcl_SetObjLength(valuePtr, fromIdx);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we can splice in place. This happens when the number of
|
||||
* characters being replaced is the same as the number of characters
|
||||
@@ -5738,51 +5583,29 @@ TEBCresume(
|
||||
if (length3 - 1 == toIdx - fromIdx) {
|
||||
unsigned char *bytes1, *bytes2;
|
||||
|
||||
/*
|
||||
* Flush the info in the string internal rep that refers to the
|
||||
* about-to-be-invalidated UTF-8 rep. This indicates that a new
|
||||
* buffer needs to be allocated, and assumes that the value is
|
||||
* already of tclStringTypePtr type, which should be true provided
|
||||
* we call it after Tcl_GetUnicodeFromObj.
|
||||
*/
|
||||
#define MarkStringInternalRepForFlush(objPtr) \
|
||||
(GET_STRING(objPtr)->allocated = 0)
|
||||
|
||||
if (Tcl_IsShared(valuePtr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(valuePtr);
|
||||
if (TclIsPureByteArray(objResultPtr)
|
||||
&& TclIsPureByteArray(value3Ptr)) {
|
||||
bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
|
||||
bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
|
||||
memcpy(bytes1 + fromIdx, bytes2, length3);
|
||||
} else {
|
||||
ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
|
||||
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
|
||||
memcpy(ustring1 + fromIdx, ustring2,
|
||||
length3 * sizeof(Tcl_UniChar));
|
||||
MarkStringInternalRepForFlush(objResultPtr);
|
||||
}
|
||||
Tcl_InvalidateStringRep(objResultPtr);
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
} else {
|
||||
if (TclIsPureByteArray(valuePtr)
|
||||
&& TclIsPureByteArray(value3Ptr)) {
|
||||
bytes1 = Tcl_GetByteArrayFromObj(valuePtr, NULL);
|
||||
bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
|
||||
memcpy(bytes1 + fromIdx, bytes2, length3);
|
||||
} else {
|
||||
ustring1 = Tcl_GetUnicodeFromObj(valuePtr, NULL);
|
||||
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
|
||||
memcpy(ustring1 + fromIdx, ustring2,
|
||||
length3 * sizeof(Tcl_UniChar));
|
||||
MarkStringInternalRepForFlush(valuePtr);
|
||||
}
|
||||
Tcl_InvalidateStringRep(valuePtr);
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
|
||||
objResultPtr = valuePtr;
|
||||
}
|
||||
if (TclIsPureByteArray(objResultPtr)
|
||||
&& TclIsPureByteArray(value3Ptr)) {
|
||||
bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
|
||||
bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
|
||||
memcpy(bytes1 + fromIdx, bytes2, length3);
|
||||
} else {
|
||||
ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
|
||||
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
|
||||
memcpy(ustring1 + fromIdx, ustring2,
|
||||
length3 * sizeof(Tcl_UniChar));
|
||||
}
|
||||
Tcl_InvalidateStringRep(objResultPtr);
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
if (objResultPtr == valuePtr) {
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
} else {
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5798,54 +5621,38 @@ TEBCresume(
|
||||
* Remove substring using copying.
|
||||
*/
|
||||
|
||||
if (length3 == 0) {
|
||||
if (fromIdx > 0) {
|
||||
objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
|
||||
if (toIdx < length) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
objResultPtr = NULL;
|
||||
if (fromIdx > 0) {
|
||||
objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
|
||||
}
|
||||
if (length3 > 0) {
|
||||
if (objResultPtr) {
|
||||
Tcl_AppendObjToObj(objResultPtr, value3Ptr);
|
||||
} else if (Tcl_IsShared(value3Ptr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(value3Ptr);
|
||||
} else {
|
||||
objResultPtr = value3Ptr;
|
||||
}
|
||||
}
|
||||
if (toIdx < length) {
|
||||
if (objResultPtr) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
} else {
|
||||
objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Splice string pieces by full copying.
|
||||
*/
|
||||
|
||||
if (fromIdx > 0) {
|
||||
objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
|
||||
Tcl_AppendObjToObj(objResultPtr, value3Ptr);
|
||||
if (toIdx < length) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
} else if (Tcl_IsShared(value3Ptr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(value3Ptr);
|
||||
if (toIdx < length) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Be careful with splicing the stack in this case; we have a
|
||||
* refCount:1 object in value3Ptr and we want to append to it and
|
||||
* make it be the refCount:1 object at the top of the stack
|
||||
* afterwards. [Bug 82e7f67325]
|
||||
*/
|
||||
|
||||
if (toIdx < length) {
|
||||
Tcl_AppendUnicodeToObj(value3Ptr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
if (objResultPtr == NULL) {
|
||||
/* This has to be the case [string replace $s 0 end {}] */
|
||||
/* which has result {} which is same as value3Ptr. */
|
||||
objResultPtr = value3Ptr;
|
||||
}
|
||||
if (objResultPtr == value3Ptr) {
|
||||
/* See [Bug 82e7f67325] */
|
||||
TclDecrRefCount(OBJ_AT_TOS);
|
||||
OBJ_AT_TOS = value3Ptr;
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
|
||||
TclDecrRefCount(valuePtr);
|
||||
OBJ_AT_TOS = value3Ptr; /* Tricky! */
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
TclDecrRefCount(value3Ptr);
|
||||
@@ -5913,6 +5720,9 @@ TEBCresume(
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
|
||||
case INST_STR_FIND:
|
||||
#if 1
|
||||
match = TclStringFind(OBJ_UNDER_TOS, OBJ_AT_TOS, 0);
|
||||
#else
|
||||
ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
|
||||
ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
|
||||
|
||||
@@ -5927,6 +5737,7 @@ TEBCresume(
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE(("%.20s %.20s => %d\n",
|
||||
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
|
||||
@@ -7706,6 +7517,7 @@ TEBCresume(
|
||||
goto gotError;
|
||||
}
|
||||
}
|
||||
Tcl_IncrRefCount(dictPtr);
|
||||
if (TclListObjGetElements(interp, OBJ_AT_TOS, &length,
|
||||
&keyPtrPtr) != TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
@@ -7718,6 +7530,7 @@ TEBCresume(
|
||||
if (Tcl_DictObjGet(interp, dictPtr, keyPtrPtr[i],
|
||||
&valuePtr) != TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
Tcl_DecrRefCount(dictPtr);
|
||||
goto gotError;
|
||||
}
|
||||
varPtr = LOCAL(duiPtr->varIndices[i]);
|
||||
@@ -7734,10 +7547,12 @@ TEBCresume(
|
||||
duiPtr->varIndices[i]) == NULL) {
|
||||
CACHE_STACK_INFO();
|
||||
TRACE_ERROR(interp);
|
||||
Tcl_DecrRefCount(dictPtr);
|
||||
goto gotError;
|
||||
}
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
TclDecrRefCount(dictPtr);
|
||||
TRACE_APPEND(("OK\n"));
|
||||
NEXT_INST_F(9, 0, 0);
|
||||
|
||||
@@ -9823,7 +9638,7 @@ IllegalExprOperandType(
|
||||
|
||||
if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
|
||||
int numBytes;
|
||||
const char *bytes = Tcl_GetStringFromObj(opndPtr, &numBytes);
|
||||
const char *bytes = TclGetStringFromObj(opndPtr, &numBytes);
|
||||
|
||||
if (numBytes == 0) {
|
||||
description = "empty string";
|
||||
@@ -10452,7 +10267,7 @@ EvalStatsCmd(
|
||||
if (entryPtr->objPtr->typePtr == &tclByteCodeType) {
|
||||
numByteCodeLits++;
|
||||
}
|
||||
(void) Tcl_GetStringFromObj(entryPtr->objPtr, &length);
|
||||
(void) TclGetStringFromObj(entryPtr->objPtr, &length);
|
||||
refCountSum += entryPtr->refCount;
|
||||
objBytesIfUnshared += (entryPtr->refCount * sizeof(Tcl_Obj));
|
||||
strBytesIfUnshared += (entryPtr->refCount * (length+1));
|
||||
@@ -10674,7 +10489,7 @@ EvalStatsCmd(
|
||||
Tcl_SetObjResult(interp, objPtr);
|
||||
} else {
|
||||
Tcl_Channel outChan;
|
||||
char *str = Tcl_GetStringFromObj(objv[1], &length);
|
||||
char *str = TclGetStringFromObj(objv[1], &length);
|
||||
|
||||
if (length) {
|
||||
if (strcmp(str, "stdout") == 0) {
|
||||
|
||||
+2
-8
@@ -1079,12 +1079,9 @@ TclFileAttrsCmd(
|
||||
}
|
||||
|
||||
if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings,
|
||||
"option", 0, &index) != TCL_OK) {
|
||||
"option", INDEX_TEMP_TABLE, &index) != TCL_OK) {
|
||||
goto end;
|
||||
}
|
||||
if (attributeStringsAllocated != NULL) {
|
||||
TclFreeIntRep(objv[0]);
|
||||
}
|
||||
if (Tcl_FSFileAttrsGet(interp, index, filePtr,
|
||||
&objPtr) != TCL_OK) {
|
||||
goto end;
|
||||
@@ -1107,12 +1104,9 @@ TclFileAttrsCmd(
|
||||
|
||||
for (i = 0; i < objc ; i += 2) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings,
|
||||
"option", 0, &index) != TCL_OK) {
|
||||
"option", INDEX_TEMP_TABLE, &index) != TCL_OK) {
|
||||
goto end;
|
||||
}
|
||||
if (attributeStringsAllocated != NULL) {
|
||||
TclFreeIntRep(objv[i]);
|
||||
}
|
||||
if (i + 1 == objc) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"value for \"%s\" missing", TclGetString(objv[i])));
|
||||
|
||||
+18
-17
@@ -387,7 +387,7 @@ TclpGetNativePathType(
|
||||
{
|
||||
Tcl_PathType type = TCL_PATH_ABSOLUTE;
|
||||
int pathLen;
|
||||
const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);
|
||||
const char *path = TclGetStringFromObj(pathPtr, &pathLen);
|
||||
|
||||
if (path[0] == '~') {
|
||||
/*
|
||||
@@ -578,7 +578,7 @@ Tcl_SplitPath(
|
||||
size = 1;
|
||||
for (i = 0; i < *argcPtr; i++) {
|
||||
Tcl_ListObjIndex(NULL, resultPtr, i, &eltPtr);
|
||||
Tcl_GetStringFromObj(eltPtr, &len);
|
||||
TclGetStringFromObj(eltPtr, &len);
|
||||
size += len + 1;
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ Tcl_SplitPath(
|
||||
p = (char *) &(*argvPtr)[(*argcPtr) + 1];
|
||||
for (i = 0; i < *argcPtr; i++) {
|
||||
Tcl_ListObjIndex(NULL, resultPtr, i, &eltPtr);
|
||||
str = Tcl_GetStringFromObj(eltPtr, &len);
|
||||
str = TclGetStringFromObj(eltPtr, &len);
|
||||
memcpy(p, str, (size_t) len+1);
|
||||
p += len+1;
|
||||
}
|
||||
@@ -857,7 +857,7 @@ TclpNativeJoinPath(
|
||||
const char *p;
|
||||
const char *start;
|
||||
|
||||
start = Tcl_GetStringFromObj(prefix, &length);
|
||||
start = TclGetStringFromObj(prefix, &length);
|
||||
|
||||
/*
|
||||
* Remove the ./ from tilde prefixed elements, and drive-letter prefixed
|
||||
@@ -885,7 +885,7 @@ TclpNativeJoinPath(
|
||||
|
||||
if (length > 0 && (start[length-1] != '/')) {
|
||||
Tcl_AppendToObj(prefix, "/", 1);
|
||||
Tcl_GetStringFromObj(prefix, &length);
|
||||
TclGetStringFromObj(prefix, &length);
|
||||
}
|
||||
needsSep = 0;
|
||||
|
||||
@@ -921,7 +921,7 @@ TclpNativeJoinPath(
|
||||
if ((length > 0) &&
|
||||
(start[length-1] != '/') && (start[length-1] != ':')) {
|
||||
Tcl_AppendToObj(prefix, "/", 1);
|
||||
Tcl_GetStringFromObj(prefix, &length);
|
||||
TclGetStringFromObj(prefix, &length);
|
||||
}
|
||||
needsSep = 0;
|
||||
|
||||
@@ -1003,7 +1003,7 @@ Tcl_JoinPath(
|
||||
* Store the result.
|
||||
*/
|
||||
|
||||
resultStr = Tcl_GetStringFromObj(resultObj, &len);
|
||||
resultStr = TclGetStringFromObj(resultObj, &len);
|
||||
Tcl_DStringAppend(resultPtr, resultStr, len);
|
||||
Tcl_DecrRefCount(resultObj);
|
||||
|
||||
@@ -1249,7 +1249,7 @@ Tcl_GlobObjCmd(
|
||||
for (i = 1; i < objc; i++) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
string = Tcl_GetStringFromObj(objv[i], &length);
|
||||
string = TclGetStringFromObj(objv[i], &length);
|
||||
if (string[0] == '-') {
|
||||
/*
|
||||
* It looks like the command contains an option so signal an
|
||||
@@ -1357,7 +1357,7 @@ Tcl_GlobObjCmd(
|
||||
if (dir == PATH_GENERAL) {
|
||||
int pathlength;
|
||||
const char *last;
|
||||
const char *first = Tcl_GetStringFromObj(pathOrDir,&pathlength);
|
||||
const char *first = TclGetStringFromObj(pathOrDir,&pathlength);
|
||||
|
||||
/*
|
||||
* Find the last path separator in the path
|
||||
@@ -1460,7 +1460,7 @@ Tcl_GlobObjCmd(
|
||||
const char *str;
|
||||
|
||||
Tcl_ListObjIndex(interp, typePtr, length, &look);
|
||||
str = Tcl_GetStringFromObj(look, &len);
|
||||
str = TclGetStringFromObj(look, &len);
|
||||
if (strcmp("readonly", str) == 0) {
|
||||
globTypes->perm |= TCL_GLOB_PERM_RONLY;
|
||||
} else if (strcmp("hidden", str) == 0) {
|
||||
@@ -1595,8 +1595,9 @@ Tcl_GlobObjCmd(
|
||||
} else if (dir == PATH_GENERAL) {
|
||||
Tcl_DString str;
|
||||
|
||||
Tcl_DStringInit(&str);
|
||||
for (i = 0; i < objc; i++) {
|
||||
Tcl_DStringInit(&str);
|
||||
Tcl_DStringSetLength(&str, 0);
|
||||
if (dir == PATH_GENERAL) {
|
||||
TclDStringAppendDString(&str, &prefix);
|
||||
}
|
||||
@@ -1991,7 +1992,7 @@ TclGlob(
|
||||
Tcl_Panic("Called TclGlob with TCL_GLOBMODE_TAILS and pathPrefix==NULL");
|
||||
}
|
||||
|
||||
pre = Tcl_GetStringFromObj(pathPrefix, &prefixLen);
|
||||
pre = TclGetStringFromObj(pathPrefix, &prefixLen);
|
||||
if (prefixLen > 0
|
||||
&& (strchr(separators, pre[prefixLen-1]) == NULL)) {
|
||||
/*
|
||||
@@ -2009,7 +2010,7 @@ TclGlob(
|
||||
Tcl_ListObjGetElements(NULL, filenamesObj, &objc, &objv);
|
||||
for (i = 0; i< objc; i++) {
|
||||
int len;
|
||||
const char *oldStr = Tcl_GetStringFromObj(objv[i], &len);
|
||||
const char *oldStr = TclGetStringFromObj(objv[i], &len);
|
||||
Tcl_Obj *elem;
|
||||
|
||||
if (len == prefixLen) {
|
||||
@@ -2361,7 +2362,7 @@ DoGlob(
|
||||
Tcl_Obj *fixme, *newObj;
|
||||
|
||||
Tcl_ListObjIndex(NULL, matchesObj, repair, &fixme);
|
||||
bytes = Tcl_GetStringFromObj(fixme, &numBytes);
|
||||
bytes = TclGetStringFromObj(fixme, &numBytes);
|
||||
newObj = Tcl_NewStringObj(bytes+2, numBytes-2);
|
||||
Tcl_ListObjReplace(NULL, matchesObj, repair, 1,
|
||||
1, &newObj);
|
||||
@@ -2399,7 +2400,7 @@ DoGlob(
|
||||
Tcl_DStringAppend(&append, pattern, p-pattern);
|
||||
|
||||
if (pathPtr != NULL) {
|
||||
(void) Tcl_GetStringFromObj(pathPtr, &length);
|
||||
(void) TclGetStringFromObj(pathPtr, &length);
|
||||
} else {
|
||||
length = 0;
|
||||
}
|
||||
@@ -2445,7 +2446,7 @@ DoGlob(
|
||||
*/
|
||||
|
||||
int len;
|
||||
const char *joined = Tcl_GetStringFromObj(joinedPtr,&len);
|
||||
const char *joined = TclGetStringFromObj(joinedPtr,&len);
|
||||
|
||||
if (strchr(separators, joined[len-1]) == NULL) {
|
||||
Tcl_AppendToObj(joinedPtr, "/", 1);
|
||||
@@ -2482,7 +2483,7 @@ DoGlob(
|
||||
*/
|
||||
|
||||
int len;
|
||||
const char *joined = Tcl_GetStringFromObj(joinedPtr,&len);
|
||||
const char *joined = TclGetStringFromObj(joinedPtr,&len);
|
||||
|
||||
if (strchr(separators, joined[len-1]) == NULL) {
|
||||
if (Tcl_FSGetPathType(pathPtr) != TCL_PATH_VOLUME_RELATIVE) {
|
||||
|
||||
+6
-6
@@ -43,7 +43,7 @@
|
||||
|
||||
static Tcl_HashEntry * AllocArrayEntry(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
static int CompareArrayKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
static unsigned int HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
static TCL_HASH_TYPE HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
/*
|
||||
* Prototypes for the one word hash key methods. Not actually declared because
|
||||
@@ -65,7 +65,7 @@ static unsigned int HashOneWordKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
static Tcl_HashEntry * AllocStringEntry(Tcl_HashTable *tablePtr,
|
||||
void *keyPtr);
|
||||
static int CompareStringKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
static unsigned int HashStringKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
static TCL_HASH_TYPE HashStringKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
/*
|
||||
* Function prototypes for static functions in this file:
|
||||
@@ -774,7 +774,7 @@ CompareArrayKeys(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
static TCL_HASH_TYPE
|
||||
HashArrayKey(
|
||||
Tcl_HashTable *tablePtr, /* Hash table. */
|
||||
void *keyPtr) /* Key from which to compute hash value. */
|
||||
@@ -787,7 +787,7 @@ HashArrayKey(
|
||||
count--, array++) {
|
||||
result += *array;
|
||||
}
|
||||
return result;
|
||||
return (TCL_HASH_TYPE) result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -870,7 +870,7 @@ CompareStringKeys(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static unsigned
|
||||
static TCL_HASH_TYPE
|
||||
HashStringKey(
|
||||
Tcl_HashTable *tablePtr, /* Hash table. */
|
||||
void *keyPtr) /* Key from which to compute hash value. */
|
||||
@@ -916,7 +916,7 @@ HashStringKey(
|
||||
result += (result << 3) + UCHAR(c);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return (TCL_HASH_TYPE) result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+73
-86
@@ -313,15 +313,20 @@ static int WillRead(Channel *chanPtr);
|
||||
&& (strncmp(optionName, (nameString), len) == 0))
|
||||
|
||||
/*
|
||||
* The ChannelObjType type. We actually store the ChannelState structure
|
||||
* as that lives longest and we want to return the bottomChanPtr when
|
||||
* requested (consistent with Tcl_GetChannel). The setFromAny and
|
||||
* updateString can be NULL as they should not be called.
|
||||
* The ChannelObjType type. Used to store the result of looking up
|
||||
* a channel name in the context of an interp. Saves the lookup
|
||||
* result and values needed to check its continued validity.
|
||||
*/
|
||||
|
||||
typedef struct ResolvedChanName {
|
||||
ChannelState *statePtr; /* The saved lookup result */
|
||||
Tcl_Interp *interp; /* The interp in which the lookup was done. */
|
||||
int epoch; /* The epoch of the channel when the lookup
|
||||
* was done. Use to verify validity. */
|
||||
int refCount; /* Share this struct among many Tcl_Obj. */
|
||||
} ResolvedChanName;
|
||||
|
||||
static void DupChannelIntRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
|
||||
static int SetChannelFromAny(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static void FreeChannelIntRep(Tcl_Obj *objPtr);
|
||||
|
||||
static const Tcl_ObjType chanObjType = {
|
||||
@@ -329,18 +334,9 @@ static const Tcl_ObjType chanObjType = {
|
||||
FreeChannelIntRep, /* freeIntRepProc */
|
||||
DupChannelIntRep, /* dupIntRepProc */
|
||||
NULL, /* updateStringProc */
|
||||
NULL /* setFromAnyProc SetChannelFromAny */
|
||||
NULL /* setFromAnyProc */
|
||||
};
|
||||
|
||||
#define GET_CHANNELSTATE(objPtr) \
|
||||
((ChannelState *) (objPtr)->internalRep.twoPtrValue.ptr1)
|
||||
#define SET_CHANNELSTATE(objPtr, storePtr) \
|
||||
((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (storePtr))
|
||||
#define GET_CHANNELINTERP(objPtr) \
|
||||
((Tcl_Interp *) (objPtr)->internalRep.twoPtrValue.ptr2)
|
||||
#define SET_CHANNELINTERP(objPtr, storePtr) \
|
||||
((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (storePtr))
|
||||
|
||||
#define BUSY_STATE(st, fl) \
|
||||
((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
|
||||
(((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
|
||||
@@ -1021,7 +1017,7 @@ DeleteChannelTable(
|
||||
*/
|
||||
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
SetFlag(statePtr, CHANNEL_TAINTED);
|
||||
statePtr->epoch++;
|
||||
if (statePtr->refCount-- <= 1) {
|
||||
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
|
||||
(void) Tcl_Close(interp, (Tcl_Channel) chanPtr);
|
||||
@@ -1365,7 +1361,7 @@ DetachChannel(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
SetFlag(statePtr, CHANNEL_TAINTED);
|
||||
statePtr->epoch++;
|
||||
|
||||
/*
|
||||
* Remove channel handlers that refer to this interpreter, so that
|
||||
@@ -1498,12 +1494,57 @@ TclGetChannelFromObj(
|
||||
int flags)
|
||||
{
|
||||
ChannelState *statePtr;
|
||||
ResolvedChanName *resPtr = NULL;
|
||||
Tcl_Channel chan;
|
||||
|
||||
if (SetChannelFromAny(interp, objPtr) != TCL_OK) {
|
||||
if (interp == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
statePtr = GET_CHANNELSTATE(objPtr);
|
||||
if (objPtr->typePtr == &chanObjType) {
|
||||
/*
|
||||
* Confirm validity of saved lookup results.
|
||||
*/
|
||||
|
||||
resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1;
|
||||
statePtr = resPtr->statePtr;
|
||||
if ((resPtr->interp == interp) /* Same interp context */
|
||||
/* No epoch change in channel since lookup */
|
||||
&& (resPtr->epoch == statePtr->epoch)) {
|
||||
|
||||
/* Have a valid saved lookup. Jump to end to return it. */
|
||||
goto valid;
|
||||
}
|
||||
}
|
||||
|
||||
chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
|
||||
|
||||
if (chan == NULL) {
|
||||
if (resPtr) {
|
||||
FreeChannelIntRep(objPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (resPtr && resPtr->refCount == 1) {
|
||||
/* Re-use the ResolvedCmdName struct */
|
||||
Tcl_Release((ClientData) resPtr->statePtr);
|
||||
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
resPtr = (ResolvedChanName *) ckalloc(sizeof(ResolvedChanName));
|
||||
resPtr->refCount = 1;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = (ClientData) resPtr;
|
||||
objPtr->typePtr = &chanObjType;
|
||||
}
|
||||
statePtr = ((Channel *)chan)->state;
|
||||
resPtr->statePtr = statePtr;
|
||||
Tcl_Preserve((ClientData) statePtr);
|
||||
resPtr->interp = interp;
|
||||
resPtr->epoch = statePtr->epoch;
|
||||
|
||||
valid:
|
||||
*channelPtr = (Tcl_Channel) statePtr->bottomChanPtr;
|
||||
|
||||
if (modePtr != NULL) {
|
||||
@@ -1676,6 +1717,8 @@ Tcl_CreateChannel(
|
||||
statePtr->chanMsg = NULL;
|
||||
statePtr->unreportedMsg = NULL;
|
||||
|
||||
statePtr->epoch = 0;
|
||||
|
||||
/*
|
||||
* Link the channel into the list of all channels; create an on-exit
|
||||
* handler if there is not one already, to close off all the channels in
|
||||
@@ -11121,75 +11164,13 @@ DupChannelIntRep(
|
||||
register Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not
|
||||
* currently have an internal rep.*/
|
||||
{
|
||||
ChannelState *statePtr = GET_CHANNELSTATE(srcPtr);
|
||||
ResolvedChanName *resPtr = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
SET_CHANNELSTATE(copyPtr, statePtr);
|
||||
SET_CHANNELINTERP(copyPtr, GET_CHANNELINTERP(srcPtr));
|
||||
Tcl_Preserve(statePtr);
|
||||
resPtr->refCount++;
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
copyPtr->typePtr = srcPtr->typePtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* SetChannelFromAny --
|
||||
*
|
||||
* Create an internal representation of type "Channel" for an object.
|
||||
*
|
||||
* Results:
|
||||
* This operation always succeeds and returns TCL_OK.
|
||||
*
|
||||
* Side effects:
|
||||
* Any old internal reputation for objPtr is freed and the internal
|
||||
* representation is set to "Channel".
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
SetChannelFromAny(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
register Tcl_Obj *objPtr) /* The object to convert. */
|
||||
{
|
||||
ChannelState *statePtr;
|
||||
|
||||
if (interp == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr == &chanObjType) {
|
||||
/*
|
||||
* TODO: TAINT Flag and dup'd channel values?
|
||||
* The channel is valid until any call to DetachChannel occurs.
|
||||
* Ensure consistency checks are done.
|
||||
*/
|
||||
|
||||
statePtr = GET_CHANNELSTATE(objPtr);
|
||||
if (GotFlag(statePtr, CHANNEL_TAINTED|CHANNEL_CLOSED)) {
|
||||
ResetFlag(statePtr, CHANNEL_TAINTED);
|
||||
Tcl_Release(statePtr);
|
||||
objPtr->typePtr = NULL;
|
||||
} else if (interp != GET_CHANNELINTERP(objPtr)) {
|
||||
Tcl_Release(statePtr);
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
}
|
||||
if (objPtr->typePtr != &chanObjType) {
|
||||
Tcl_Channel chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
|
||||
|
||||
if (chan == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
statePtr = ((Channel *) chan)->state;
|
||||
Tcl_Preserve(statePtr);
|
||||
SET_CHANNELSTATE(objPtr, statePtr);
|
||||
SET_CHANNELINTERP(objPtr, interp);
|
||||
objPtr->typePtr = &chanObjType;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -11210,8 +11191,14 @@ static void
|
||||
FreeChannelIntRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
Tcl_Release(GET_CHANNELSTATE(objPtr));
|
||||
ResolvedChanName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
objPtr->typePtr = NULL;
|
||||
if (--resPtr->refCount) {
|
||||
return;
|
||||
}
|
||||
Tcl_Release(resPtr->statePtr);
|
||||
ckfree(resPtr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
+2
-4
@@ -214,6 +214,8 @@ typedef struct ChannelState {
|
||||
* because it happened in the background. The
|
||||
* value is the chanMg, if any. #219's
|
||||
* companion to 'unreportedError'. */
|
||||
int epoch; /* Used to test validity of stored channelname
|
||||
* lookup results. */
|
||||
} ChannelState;
|
||||
|
||||
/*
|
||||
@@ -275,10 +277,6 @@ typedef struct ChannelState {
|
||||
* usable, but it may not be closed
|
||||
* again from within the close
|
||||
* handler. */
|
||||
#define CHANNEL_TAINTED (1<<20) /* Channel stack structure has changed.
|
||||
* Used by Channel Tcl_Obj type to
|
||||
* determine if we have to revalidate
|
||||
* the channel. */
|
||||
#define CHANNEL_CLOSEDWRITE (1<<21) /* Channel write side has been closed.
|
||||
* No further Tcl-level write IO on
|
||||
* the channel is allowed. */
|
||||
|
||||
@@ -1946,7 +1946,7 @@ ReflectGetOption(
|
||||
goto error;
|
||||
} else {
|
||||
int len;
|
||||
const char *str = Tcl_GetStringFromObj(resObj, &len);
|
||||
const char *str = TclGetStringFromObj(resObj, &len);
|
||||
|
||||
if (len) {
|
||||
TclDStringAppendLiteral(dsPtr, " ");
|
||||
@@ -2319,7 +2319,7 @@ InvokeTclMethod(
|
||||
|
||||
if (result != TCL_ERROR) {
|
||||
int cmdLen;
|
||||
const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
|
||||
const char *cmdString = TclGetStringFromObj(cmd, &cmdLen);
|
||||
|
||||
Tcl_IncrRefCount(cmd);
|
||||
Tcl_ResetResult(rcPtr->interp);
|
||||
@@ -3174,7 +3174,7 @@ ForwardProc(
|
||||
ForwardSetDynamicError(paramPtr, buf);
|
||||
} else {
|
||||
int len;
|
||||
const char *str = Tcl_GetStringFromObj(resObj, &len);
|
||||
const char *str = TclGetStringFromObj(resObj, &len);
|
||||
|
||||
if (len) {
|
||||
TclDStringAppendLiteral(paramPtr->getOpt.value, " ");
|
||||
@@ -3273,7 +3273,7 @@ ForwardSetObjError(
|
||||
Tcl_Obj *obj)
|
||||
{
|
||||
int len;
|
||||
const char *msgStr = Tcl_GetStringFromObj(obj, &len);
|
||||
const char *msgStr = TclGetStringFromObj(obj, &len);
|
||||
|
||||
len++;
|
||||
ForwardSetDynamicError(paramPtr, ckalloc(len));
|
||||
|
||||
@@ -2043,7 +2043,7 @@ InvokeTclMethod(
|
||||
if (result != TCL_ERROR) {
|
||||
Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rtPtr->argv);
|
||||
int cmdLen;
|
||||
const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
|
||||
const char *cmdString = TclGetStringFromObj(cmd, &cmdLen);
|
||||
|
||||
Tcl_IncrRefCount(cmd);
|
||||
Tcl_ResetResult(rtPtr->interp);
|
||||
@@ -2807,7 +2807,7 @@ ForwardSetObjError(
|
||||
Tcl_Obj *obj)
|
||||
{
|
||||
int len;
|
||||
const char *msgStr = Tcl_GetStringFromObj(obj, &len);
|
||||
const char *msgStr = TclGetStringFromObj(obj, &len);
|
||||
|
||||
len++;
|
||||
ForwardSetDynamicError(paramPtr, ckalloc(len));
|
||||
|
||||
+1
-1
@@ -197,7 +197,7 @@ TclCreateSocketAddress(
|
||||
*/
|
||||
|
||||
if (interp != NULL) {
|
||||
family = Tcl_GetVar(interp, "::tcl::unsupported::socketAF", 0);
|
||||
family = Tcl_GetVar2(interp, "::tcl::unsupported::socketAF", NULL, 0);
|
||||
if (family != NULL) {
|
||||
if (strcmp(family, "inet") == 0) {
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
+15
-16
@@ -71,8 +71,7 @@ typedef struct ThreadSpecificData {
|
||||
* Prototypes for functions defined later in this file.
|
||||
*/
|
||||
|
||||
static int EvalFileCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc EvalFileCallback;
|
||||
static FilesystemRecord*FsGetFirstFilesystem(void);
|
||||
static void FsThrExitProc(ClientData cd);
|
||||
static Tcl_Obj * FsListMounts(Tcl_Obj *pathPtr, const char *pattern);
|
||||
@@ -545,8 +544,8 @@ TclFSCwdPointerEquals(
|
||||
int len1, len2;
|
||||
const char *str1, *str2;
|
||||
|
||||
str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1);
|
||||
str2 = Tcl_GetStringFromObj(*pathPtrPtr, &len2);
|
||||
str1 = TclGetStringFromObj(tsdPtr->cwdPathPtr, &len1);
|
||||
str2 = TclGetStringFromObj(*pathPtrPtr, &len2);
|
||||
if ((len1 == len2) && !memcmp(str1, str2, len1)) {
|
||||
/*
|
||||
* They are equal, but different objects. Update so they will be
|
||||
@@ -689,7 +688,7 @@ FsUpdateCwd(
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
|
||||
|
||||
if (cwdObj != NULL) {
|
||||
str = Tcl_GetStringFromObj(cwdObj, &len);
|
||||
str = TclGetStringFromObj(cwdObj, &len);
|
||||
}
|
||||
|
||||
Tcl_MutexLock(&cwdMutex);
|
||||
@@ -1225,8 +1224,8 @@ FsAddMountsToGlobResult(
|
||||
if (norm != NULL) {
|
||||
const char *path, *mount;
|
||||
|
||||
mount = Tcl_GetStringFromObj(mElt, &mlen);
|
||||
path = Tcl_GetStringFromObj(norm, &len);
|
||||
mount = TclGetStringFromObj(mElt, &mlen);
|
||||
path = TclGetStringFromObj(norm, &len);
|
||||
if (path[len-1] == '/') {
|
||||
/*
|
||||
* Deal with the root of the volume.
|
||||
@@ -1817,7 +1816,7 @@ Tcl_FSEvalFileEx(
|
||||
oldScriptFile = iPtr->scriptFile;
|
||||
iPtr->scriptFile = pathPtr;
|
||||
Tcl_IncrRefCount(iPtr->scriptFile);
|
||||
string = Tcl_GetStringFromObj(objPtr, &length);
|
||||
string = TclGetStringFromObj(objPtr, &length);
|
||||
|
||||
/*
|
||||
* TIP #280 Force the evaluator to open a frame for a sourced file.
|
||||
@@ -1844,7 +1843,7 @@ Tcl_FSEvalFileEx(
|
||||
* Record information telling where the error occurred.
|
||||
*/
|
||||
|
||||
const char *pathString = Tcl_GetStringFromObj(pathPtr, &length);
|
||||
const char *pathString = TclGetStringFromObj(pathPtr, &length);
|
||||
int limit = 150;
|
||||
int overflow = (length > limit);
|
||||
|
||||
@@ -1995,7 +1994,7 @@ EvalFileCallback(
|
||||
*/
|
||||
|
||||
int length;
|
||||
const char *pathString = Tcl_GetStringFromObj(pathPtr, &length);
|
||||
const char *pathString = TclGetStringFromObj(pathPtr, &length);
|
||||
const int limit = 150;
|
||||
int overflow = (length > limit);
|
||||
|
||||
@@ -2847,8 +2846,8 @@ Tcl_FSGetCwd(
|
||||
int len1, len2;
|
||||
const char *str1, *str2;
|
||||
|
||||
str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1);
|
||||
str2 = Tcl_GetStringFromObj(norm, &len2);
|
||||
str1 = TclGetStringFromObj(tsdPtr->cwdPathPtr, &len1);
|
||||
str2 = TclGetStringFromObj(norm, &len2);
|
||||
if ((len1 == len2) && (strcmp(str1, str2) == 0)) {
|
||||
/*
|
||||
* If the paths were equal, we can be more efficient and
|
||||
@@ -4116,7 +4115,7 @@ TclGetPathType(
|
||||
* caller. */
|
||||
{
|
||||
int pathLen;
|
||||
const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);
|
||||
const char *path = TclGetStringFromObj(pathPtr, &pathLen);
|
||||
Tcl_PathType type;
|
||||
|
||||
type = TclFSNonnativePathType(path, pathLen, filesystemPtrPtr,
|
||||
@@ -4228,7 +4227,7 @@ TclFSNonnativePathType(
|
||||
|
||||
numVolumes--;
|
||||
Tcl_ListObjIndex(NULL, thisFsVolumes, numVolumes, &vol);
|
||||
strVol = Tcl_GetStringFromObj(vol,&len);
|
||||
strVol = TclGetStringFromObj(vol,&len);
|
||||
if (pathLen < len) {
|
||||
continue;
|
||||
}
|
||||
@@ -4575,8 +4574,8 @@ Tcl_FSRemoveDirectory(
|
||||
Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathPtr);
|
||||
|
||||
if (normPath != NULL) {
|
||||
normPathStr = Tcl_GetStringFromObj(normPath, &normLen);
|
||||
cwdStr = Tcl_GetStringFromObj(cwdPtr, &cwdLen);
|
||||
normPathStr = TclGetStringFromObj(normPath, &normLen);
|
||||
cwdStr = TclGetStringFromObj(cwdPtr, &cwdLen);
|
||||
if ((cwdLen >= normLen) && (strncmp(normPathStr, cwdStr,
|
||||
(size_t) normLen) == 0)) {
|
||||
/*
|
||||
|
||||
+28
-35
@@ -114,14 +114,13 @@ Tcl_GetIndexFromObj(
|
||||
int flags, /* 0 or TCL_EXACT */
|
||||
int *indexPtr) /* Place to store resulting integer index. */
|
||||
{
|
||||
|
||||
/*
|
||||
* See if there is a valid cached result from a previous lookup (doing the
|
||||
* check here saves the overhead of calling Tcl_GetIndexFromObjStruct in
|
||||
* the common case where the result is cached).
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &indexType) {
|
||||
if (!(flags & INDEX_TEMP_TABLE) && objPtr->typePtr == &indexType) {
|
||||
IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
/*
|
||||
@@ -211,13 +210,8 @@ GetIndexFromObjList(
|
||||
tablePtr[objc] = NULL;
|
||||
|
||||
result = Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr,
|
||||
sizeof(char *), msg, flags, indexPtr);
|
||||
sizeof(char *), msg, flags | INDEX_TEMP_TABLE, indexPtr);
|
||||
|
||||
/*
|
||||
* The internal rep must be cleared since tablePtr will go away.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
ckfree(tablePtr);
|
||||
|
||||
return result;
|
||||
@@ -279,7 +273,7 @@ Tcl_GetIndexFromObjStruct(
|
||||
* See if there is a valid cached result from a previous lookup.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &indexType) {
|
||||
if (!(flags & INDEX_TEMP_TABLE) && objPtr->typePtr == &indexType) {
|
||||
indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) {
|
||||
*indexPtr = indexRep->index;
|
||||
@@ -340,17 +334,19 @@ Tcl_GetIndexFromObjStruct(
|
||||
* operation.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &indexType) {
|
||||
indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
indexRep = ckalloc(sizeof(IndexRep));
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = indexRep;
|
||||
objPtr->typePtr = &indexType;
|
||||
if (!(flags & INDEX_TEMP_TABLE)) {
|
||||
if (objPtr->typePtr == &indexType) {
|
||||
indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
indexRep = ckalloc(sizeof(IndexRep));
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = indexRep;
|
||||
objPtr->typePtr = &indexType;
|
||||
}
|
||||
indexRep->tablePtr = (void *) tablePtr;
|
||||
indexRep->offset = offset;
|
||||
indexRep->index = index;
|
||||
}
|
||||
indexRep->tablePtr = (void *) tablePtr;
|
||||
indexRep->offset = offset;
|
||||
indexRep->index = index;
|
||||
|
||||
*indexPtr = index;
|
||||
return TCL_OK;
|
||||
@@ -712,10 +708,10 @@ PrefixAllObjCmd(
|
||||
return result;
|
||||
}
|
||||
resultPtr = Tcl_NewListObj(0, NULL);
|
||||
string = Tcl_GetStringFromObj(objv[2], &length);
|
||||
string = TclGetStringFromObj(objv[2], &length);
|
||||
|
||||
for (t = 0; t < tableObjc; t++) {
|
||||
elemString = Tcl_GetStringFromObj(tableObjv[t], &elemLength);
|
||||
elemString = TclGetStringFromObj(tableObjv[t], &elemLength);
|
||||
|
||||
/*
|
||||
* A prefix cannot match if it is longest.
|
||||
@@ -768,13 +764,13 @@ PrefixLongestObjCmd(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
string = Tcl_GetStringFromObj(objv[2], &length);
|
||||
string = TclGetStringFromObj(objv[2], &length);
|
||||
|
||||
resultString = NULL;
|
||||
resultLength = 0;
|
||||
|
||||
for (t = 0; t < tableObjc; t++) {
|
||||
elemString = Tcl_GetStringFromObj(tableObjv[t], &elemLength);
|
||||
elemString = TclGetStringFromObj(tableObjv[t], &elemLength);
|
||||
|
||||
/*
|
||||
* First check if the prefix string matches the element. A prefix
|
||||
@@ -924,6 +920,14 @@ Tcl_WrongNumArgs(
|
||||
int toPrint = iPtr->ensembleRewrite.numRemovedObjs;
|
||||
Tcl_Obj *const *origObjv = iPtr->ensembleRewrite.sourceObjs;
|
||||
|
||||
/*
|
||||
* Check for spelling fixes, and substitute the fixed values.
|
||||
*/
|
||||
|
||||
if (origObjv[0] == NULL) {
|
||||
origObjv = (Tcl_Obj *const *)origObjv[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* We only know how to do rewriting if all the replaced objects are
|
||||
* actually arguments (in objv) to this function. Otherwise it just
|
||||
@@ -957,12 +961,6 @@ Tcl_WrongNumArgs(
|
||||
|
||||
elementStr = EXPAND_OF(indexRep);
|
||||
elemLen = strlen(elementStr);
|
||||
} else if (origObjv[i]->typePtr == &tclEnsembleCmdType) {
|
||||
register EnsembleCmdRep *ecrPtr =
|
||||
origObjv[i]->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
elementStr = ecrPtr->fullSubcmdName;
|
||||
elemLen = strlen(elementStr);
|
||||
} else {
|
||||
elementStr = TclGetStringFromObj(origObjv[i], &elemLen);
|
||||
}
|
||||
@@ -1011,11 +1009,6 @@ Tcl_WrongNumArgs(
|
||||
register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL);
|
||||
} else if (objv[i]->typePtr == &tclEnsembleCmdType) {
|
||||
register EnsembleCmdRep *ecrPtr =
|
||||
objv[i]->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
Tcl_AppendStringsToObj(objPtr, ecrPtr->fullSubcmdName, NULL);
|
||||
} else {
|
||||
/*
|
||||
* Quote the argument if it contains spaces (Bug 942757).
|
||||
@@ -1151,7 +1144,7 @@ Tcl_ParseArgsObjv(
|
||||
curArg = objv[srcIndex];
|
||||
srcIndex++;
|
||||
objc--;
|
||||
str = Tcl_GetStringFromObj(curArg, &length);
|
||||
str = TclGetStringFromObj(curArg, &length);
|
||||
if (length > 0) {
|
||||
c = str[1];
|
||||
} else {
|
||||
|
||||
@@ -1009,7 +1009,7 @@ declare 250 {
|
||||
# Allow extensions for optimization
|
||||
declare 251 {
|
||||
int TclRegisterLiteral(void *envPtr,
|
||||
char *bytes, int length, int flags)
|
||||
const char *bytes, int length, int flags)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
+58
-30
@@ -25,6 +25,19 @@
|
||||
|
||||
#undef ACCEPT_NAN
|
||||
|
||||
/*
|
||||
* In Tcl 8.7, stop supporting special hacks for legacy Itcl 3.
|
||||
* Itcl 4 doesn't need them. Itcl 3 can be updated to not need them
|
||||
* using the Tcl(Init|Reset)RewriteEnsemble() routines in all Tcl 8.6+
|
||||
* releases. Perhaps Tcl 8.7 will add even better public interfaces
|
||||
* supporting all the re-invocation mechanisms extensions like Itcl 3
|
||||
* need. As an absolute last resort, folks who must make Itcl 3 work
|
||||
* unchanged with Tcl 8.7 can remove this line to regain the migration
|
||||
* support. Tcl 9 will no longer offer even that option.
|
||||
*/
|
||||
|
||||
#define AVOID_HACKS_FOR_ITCL 1
|
||||
|
||||
/*
|
||||
* Common include files needed by most of the Tcl source files are included
|
||||
* here, so that system-dependent personalizations for the include files only
|
||||
@@ -48,7 +61,8 @@
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef STDC_HEADERS
|
||||
#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
|
||||
|| defined(__cplusplus) || defined(_MSC_VER)
|
||||
#include <stddef.h>
|
||||
#else
|
||||
typedef int ptrdiff_t;
|
||||
@@ -168,6 +182,21 @@ typedef struct Tcl_ResolverInfo {
|
||||
* at compile time. */
|
||||
} Tcl_ResolverInfo;
|
||||
|
||||
/*
|
||||
* This flag bit should not interfere with TCL_GLOBAL_ONLY,
|
||||
* TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable
|
||||
* lookup is performed for upvar (or similar) purposes, with slightly
|
||||
* different rules:
|
||||
* - Bug #696893 - variable is either proc-local or in the current
|
||||
* namespace; never follow the second (global) resolution path
|
||||
* - Bug #631741 - do not use special namespace or interp resolvers
|
||||
*
|
||||
* It should also not collide with the (deprecated) TCL_PARSE_PART1 flag
|
||||
* (Bug #835020)
|
||||
*/
|
||||
|
||||
#define TCL_AVOID_RESOLVERS 0x40000
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Data structures related to namespaces.
|
||||
@@ -388,27 +417,6 @@ struct NamespacePathEntry {
|
||||
#define TCL_CREATE_NS_IF_UNKNOWN 0x800
|
||||
#define TCL_FIND_ONLY_NS 0x1000
|
||||
|
||||
/*
|
||||
* The data cached in an ensemble subcommand's Tcl_Obj rep (reference in
|
||||
* twoPtrValue.ptr1 field). This structure is not shared between Tcl_Objs
|
||||
* referring to the same subcommand, even where one is a duplicate of another.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Namespace *nsPtr; /* The namespace backing the ensemble which
|
||||
* this is a subcommand of. */
|
||||
int epoch; /* Used to confirm when the data in this
|
||||
* really structure matches up with the
|
||||
* ensemble. */
|
||||
Tcl_Command token; /* Reference to the comamnd for which this
|
||||
* structure is a cache of the resolution. */
|
||||
char *fullSubcmdName; /* The full (local) name of the subcommand,
|
||||
* allocated with ckalloc(). */
|
||||
Tcl_Obj *realPrefixObj; /* Object containing the prefix words of the
|
||||
* command that implements this ensemble
|
||||
* subcommand. */
|
||||
} EnsembleCmdRep;
|
||||
|
||||
/*
|
||||
* The client data for an ensemble command. This consists of the table of
|
||||
* commands that are actually exported by the namespace, and an epoch counter
|
||||
@@ -1682,11 +1690,13 @@ typedef struct Command {
|
||||
* (these last two flags are defined in tcl.h)
|
||||
*/
|
||||
|
||||
#define CMD_IS_DELETED 0x1
|
||||
#define CMD_TRACE_ACTIVE 0x2
|
||||
#define CMD_HAS_EXEC_TRACES 0x4
|
||||
#define CMD_COMPILES_EXPANDED 0x8
|
||||
#define CMD_IS_DELETED 0x01
|
||||
#define CMD_TRACE_ACTIVE 0x02
|
||||
#define CMD_HAS_EXEC_TRACES 0x04
|
||||
#define CMD_COMPILES_EXPANDED 0x08
|
||||
#define CMD_REDEF_IN_PROGRESS 0x10
|
||||
#define CMD_VIA_RESOLVER 0x20
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -2539,6 +2549,15 @@ typedef struct TclFileAttrProcs {
|
||||
TclSetFileAttrProc *setProc;/* The procedure for setting attrs. */
|
||||
} TclFileAttrProcs;
|
||||
|
||||
/*
|
||||
* Private flag value which controls Tcl_GetIndexFromObj*() routines
|
||||
* to instruct them not to cache lookups because the table will not
|
||||
* live long enough to make it worthwhile. Must not clash with public
|
||||
* flag value TCL_EXACT.
|
||||
*/
|
||||
|
||||
#define INDEX_TEMP_TABLE 2
|
||||
|
||||
/*
|
||||
* Opaque handle used in pipeline routines to encapsulate platform-dependent
|
||||
* state.
|
||||
@@ -2690,7 +2709,6 @@ MODULE_SCOPE const Tcl_ObjType tclListType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclDictType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclProcBodyType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclStringType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclArraySearchType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
MODULE_SCOPE const Tcl_ObjType tclWideIntType;
|
||||
@@ -2761,6 +2779,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke;
|
||||
MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues;
|
||||
|
||||
MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr);
|
||||
MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp);
|
||||
@@ -2871,8 +2890,7 @@ MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
|
||||
Tcl_Channel chan);
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
|
||||
MODULE_SCOPE int TclClearRootEnsemble(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble;
|
||||
MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num,
|
||||
int *loc);
|
||||
MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr,
|
||||
@@ -2908,6 +2926,8 @@ MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr,
|
||||
MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
|
||||
Tcl_DString *toAppendPtr);
|
||||
MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
|
||||
MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv, int objc, int *objcPtr);
|
||||
MODULE_SCOPE void TclFinalizeAllocSubsystem(void);
|
||||
MODULE_SCOPE void TclFinalizeAsync(void);
|
||||
MODULE_SCOPE void TclFinalizeDoubleConversion(void);
|
||||
@@ -3110,8 +3130,16 @@ MODULE_SCOPE void TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr);
|
||||
MODULE_SCOPE void TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr,
|
||||
Tcl_Obj *newValue, Tcl_Encoding encoding);
|
||||
MODULE_SCOPE void TclSignalExitThread(Tcl_ThreadId id, int result);
|
||||
MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv, int objc, int subIdx,
|
||||
Tcl_Obj *bad, Tcl_Obj *fix);
|
||||
MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr,
|
||||
int numBytes);
|
||||
MODULE_SCOPE int TclStringCatObjv(Tcl_Interp *interp, int inPlace,
|
||||
int objc, Tcl_Obj *const objv[],
|
||||
Tcl_Obj **objPtrPtr);
|
||||
MODULE_SCOPE int TclStringFind(Tcl_Obj *needle, Tcl_Obj *haystack,
|
||||
unsigned int start);
|
||||
MODULE_SCOPE int TclStringMatch(const char *str, int strLen,
|
||||
const char *pattern, int ptnLen, int flags);
|
||||
MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj,
|
||||
@@ -3964,7 +3992,7 @@ MODULE_SCOPE int TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr,
|
||||
|
||||
MODULE_SCOPE int TclCompareObjKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
MODULE_SCOPE void TclFreeObjEntry(Tcl_HashEntry *hPtr);
|
||||
MODULE_SCOPE unsigned TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
MODULE_SCOPE TCL_HASH_TYPE TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
MODULE_SCOPE int TclFullFinalizationRequested(void);
|
||||
|
||||
|
||||
@@ -615,7 +615,7 @@ EXTERN char * TclDoubleDigits(double dv, int ndigits, int flags,
|
||||
EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags,
|
||||
int force);
|
||||
/* 251 */
|
||||
EXTERN int TclRegisterLiteral(void *envPtr, char *bytes,
|
||||
EXTERN int TclRegisterLiteral(void *envPtr, const char *bytes,
|
||||
int length, int flags);
|
||||
|
||||
typedef struct TclIntStubs {
|
||||
@@ -873,7 +873,7 @@ typedef struct TclIntStubs {
|
||||
int (*tclCopyChannel) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 248 */
|
||||
char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */
|
||||
void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */
|
||||
int (*tclRegisterLiteral) (void *envPtr, char *bytes, int length, int flags); /* 251 */
|
||||
int (*tclRegisterLiteral) (void *envPtr, const char *bytes, int length, int flags); /* 251 */
|
||||
} TclIntStubs;
|
||||
|
||||
extern const TclIntStubs *tclIntStubsPtr;
|
||||
|
||||
+18
-47
@@ -336,7 +336,7 @@ Tcl_Init(
|
||||
Tcl_Interp *interp) /* Interpreter to initialize. */
|
||||
{
|
||||
if (tclPreInitScript != NULL) {
|
||||
if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
|
||||
if (Tcl_EvalEx(interp, tclPreInitScript, -1, 0) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ Tcl_Init(
|
||||
* alternate tclInit command before calling Tcl_Init().
|
||||
*/
|
||||
|
||||
return Tcl_Eval(interp,
|
||||
return Tcl_EvalEx(interp,
|
||||
"if {[namespace which -command tclInit] eq \"\"} {\n"
|
||||
" proc tclInit {} {\n"
|
||||
" global tcl_libPath tcl_library env tclDefaultLibrary\n"
|
||||
@@ -444,7 +444,7 @@ Tcl_Init(
|
||||
" error $msg\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"tclInit");
|
||||
"tclInit", -1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -660,14 +660,9 @@ NRInterpCmd(
|
||||
if (masterInterp == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (TclGetString(objv[5])[0] == '\0') {
|
||||
if (objc == 6) {
|
||||
return AliasDelete(interp, slaveInterp, objv[3]);
|
||||
}
|
||||
} else {
|
||||
return AliasCreate(interp, slaveInterp, masterInterp, objv[3],
|
||||
objv[5], objc - 6, objv + 6);
|
||||
}
|
||||
|
||||
return AliasCreate(interp, slaveInterp, masterInterp, objv[3],
|
||||
objv[5], objc - 6, objv + 6);
|
||||
}
|
||||
goto aliasArgs;
|
||||
}
|
||||
@@ -1795,11 +1790,9 @@ AliasNRCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument vector. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Alias *aliasPtr = clientData;
|
||||
int prefc, cmdc, i;
|
||||
Tcl_Obj **prefv, **cmdv;
|
||||
int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
|
||||
Tcl_Obj *listPtr;
|
||||
List *listRep;
|
||||
int flags = TCL_EVAL_INVOKE;
|
||||
@@ -1831,21 +1824,7 @@ AliasNRCmd(
|
||||
* only the source command should show, not the full target prefix.
|
||||
*/
|
||||
|
||||
if (isRootEnsemble) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 1;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = prefc;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs += prefc - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are sending a 0-refCount obj, do not need a callback: it will be
|
||||
* cleaned up automatically. But we may need to clear the rootEnsemble
|
||||
* stuff ...
|
||||
*/
|
||||
|
||||
if (isRootEnsemble) {
|
||||
if (TclInitRewriteEnsemble(interp, 1, prefc, objv)) {
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
TclSkipTailcall(interp);
|
||||
@@ -1866,7 +1845,7 @@ AliasObjCmd(
|
||||
Tcl_Obj **prefv, **cmdv;
|
||||
Tcl_Obj *cmdArr[ALIAS_CMDV_PREALLOC];
|
||||
Interp *tPtr = (Interp *) targetInterp;
|
||||
int isRootEnsemble = (tPtr->ensembleRewrite.sourceObjs == NULL);
|
||||
int isRootEnsemble;
|
||||
|
||||
/*
|
||||
* Append the arguments to the command prefix and invoke the command in
|
||||
@@ -1896,13 +1875,7 @@ AliasObjCmd(
|
||||
* only the source command should show, not the full target prefix.
|
||||
*/
|
||||
|
||||
if (isRootEnsemble) {
|
||||
tPtr->ensembleRewrite.sourceObjs = objv;
|
||||
tPtr->ensembleRewrite.numRemovedObjs = 1;
|
||||
tPtr->ensembleRewrite.numInsertedObjs = prefc;
|
||||
} else {
|
||||
tPtr->ensembleRewrite.numInsertedObjs += prefc - 1;
|
||||
}
|
||||
isRootEnsemble = TclInitRewriteEnsemble((Tcl_Interp *)tPtr, 1, prefc, objv);
|
||||
|
||||
/*
|
||||
* Protect the target interpreter if it isn't the same as the source
|
||||
@@ -1925,9 +1898,7 @@ AliasObjCmd(
|
||||
*/
|
||||
|
||||
if (isRootEnsemble) {
|
||||
tPtr->ensembleRewrite.sourceObjs = NULL;
|
||||
tPtr->ensembleRewrite.numRemovedObjs = 0;
|
||||
tPtr->ensembleRewrite.numInsertedObjs = 0;
|
||||
TclResetRewriteEnsemble((Tcl_Interp *)tPtr, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2392,7 +2363,7 @@ SlaveCreate(
|
||||
SlaveObjCmd, NRSlaveCmd, slaveInterp, SlaveObjCmdDeleteProc);
|
||||
Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
|
||||
Tcl_SetHashValue(hPtr, slavePtr);
|
||||
Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(slaveInterp, "tcl_interactive", NULL, "0", TCL_GLOBAL_ONLY);
|
||||
|
||||
/*
|
||||
* Inherit the recursion limit.
|
||||
@@ -3219,8 +3190,8 @@ Tcl_MakeSafe(
|
||||
* Assume these functions all work. [Bug 2895741]
|
||||
*/
|
||||
|
||||
(void) Tcl_Eval(interp,
|
||||
"namespace eval ::tcl {namespace eval mathfunc {}}");
|
||||
(void) Tcl_EvalEx(interp,
|
||||
"namespace eval ::tcl {namespace eval mathfunc {}}", -1, 0);
|
||||
(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::min", master,
|
||||
"::tcl::mathfunc::min", 0, NULL);
|
||||
(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::max", master,
|
||||
@@ -4526,7 +4497,7 @@ SlaveCommandLimitCmd(
|
||||
switch ((enum Options) index) {
|
||||
case OPT_CMD:
|
||||
scriptObj = objv[i+1];
|
||||
(void) Tcl_GetStringFromObj(objv[i+1], &scriptLen);
|
||||
(void) TclGetStringFromObj(scriptObj, &scriptLen);
|
||||
break;
|
||||
case OPT_GRAN:
|
||||
granObj = objv[i+1];
|
||||
@@ -4543,7 +4514,7 @@ SlaveCommandLimitCmd(
|
||||
break;
|
||||
case OPT_VAL:
|
||||
limitObj = objv[i+1];
|
||||
(void) Tcl_GetStringFromObj(objv[i+1], &limitLen);
|
||||
(void) TclGetStringFromObj(objv[i+1], &limitLen);
|
||||
if (limitLen == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -4735,7 +4706,7 @@ SlaveTimeLimitCmd(
|
||||
switch ((enum Options) index) {
|
||||
case OPT_CMD:
|
||||
scriptObj = objv[i+1];
|
||||
(void) Tcl_GetStringFromObj(objv[i+1], &scriptLen);
|
||||
(void) TclGetStringFromObj(objv[i+1], &scriptLen);
|
||||
break;
|
||||
case OPT_GRAN:
|
||||
granObj = objv[i+1];
|
||||
@@ -4752,7 +4723,7 @@ SlaveTimeLimitCmd(
|
||||
break;
|
||||
case OPT_MILLI:
|
||||
milliObj = objv[i+1];
|
||||
(void) Tcl_GetStringFromObj(objv[i+1], &milliLen);
|
||||
(void) TclGetStringFromObj(objv[i+1], &milliLen);
|
||||
if (milliLen == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -4770,7 +4741,7 @@ SlaveTimeLimitCmd(
|
||||
break;
|
||||
case OPT_SEC:
|
||||
secObj = objv[i+1];
|
||||
(void) Tcl_GetStringFromObj(objv[i+1], &secLen);
|
||||
(void) TclGetStringFromObj(objv[i+1], &secLen);
|
||||
if (secLen == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -526,7 +526,7 @@ LinkTraceProc(
|
||||
break;
|
||||
|
||||
case TCL_LINK_STRING:
|
||||
value = Tcl_GetStringFromObj(valueObj, &valueLength);
|
||||
value = TclGetStringFromObj(valueObj, &valueLength);
|
||||
valueLength++;
|
||||
pp = (char **) linkPtr->addr;
|
||||
|
||||
|
||||
@@ -897,18 +897,18 @@ Tcl_ListObjReplace(
|
||||
}
|
||||
if (count < 0) {
|
||||
count = 0;
|
||||
} else if (numElems < first+count || first+count < 0) {
|
||||
/*
|
||||
* The 'first+count < 0' condition here guards agains integer
|
||||
* overflow in determining 'first+count'.
|
||||
*/
|
||||
} else if (first > INT_MAX - count /* Handle integer overflow */
|
||||
|| numElems < first+count) {
|
||||
|
||||
count = numElems - first;
|
||||
}
|
||||
|
||||
if (objc > LIST_MAX - (numElems - count)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max length of a Tcl list (%d elements) exceeded", LIST_MAX));
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max length of a Tcl list (%d elements) exceeded",
|
||||
LIST_MAX));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
isShared = (listRepPtr->refCount > 1);
|
||||
|
||||
+32
-23
@@ -174,7 +174,7 @@ TclDeleteLiteralTable(
|
||||
Tcl_Obj *
|
||||
TclCreateLiteral(
|
||||
Interp *iPtr,
|
||||
char *bytes, /* The start of the string. Note that this is
|
||||
const char *bytes, /* The start of the string. Note that this is
|
||||
* not a NUL-terminated string. */
|
||||
int length, /* Number of bytes in the string. */
|
||||
unsigned hash, /* The string's hash. If -1, it will be
|
||||
@@ -214,7 +214,7 @@ TclCreateLiteral(
|
||||
if (globalPtrPtr) {
|
||||
*globalPtrPtr = globalPtr;
|
||||
}
|
||||
if (flags & LITERAL_ON_HEAP) {
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
globalPtr->refCount++;
|
||||
@@ -222,26 +222,40 @@ TclCreateLiteral(
|
||||
}
|
||||
}
|
||||
if (!newPtr) {
|
||||
if (flags & LITERAL_ON_HEAP) {
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The literal is new to the interpreter. Add it to the global literal
|
||||
* table.
|
||||
* The literal is new to the interpreter.
|
||||
*/
|
||||
|
||||
TclNewObj(objPtr);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
if (flags & LITERAL_ON_HEAP) {
|
||||
objPtr->bytes = bytes;
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
objPtr->bytes = (char *) bytes;
|
||||
objPtr->length = length;
|
||||
} else {
|
||||
TclInitStringRep(objPtr, bytes, length);
|
||||
}
|
||||
|
||||
/* Should the new literal be shared globally? */
|
||||
|
||||
if ((flags & LITERAL_UNSHARED)) {
|
||||
/*
|
||||
* No, do *not* add it the global literal table
|
||||
* Make clear, that no global value is returned
|
||||
*/
|
||||
if (globalPtrPtr != NULL) {
|
||||
*globalPtrPtr = NULL;
|
||||
}
|
||||
return objPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes, add it to the global literal table.
|
||||
*/
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (LookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
|
||||
Tcl_Panic("%s: literal \"%.*s\" found globally but shouldn't be",
|
||||
@@ -251,6 +265,7 @@ TclCreateLiteral(
|
||||
|
||||
globalPtr = ckalloc(sizeof(LiteralEntry));
|
||||
globalPtr->objPtr = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
globalPtr->refCount = 1;
|
||||
globalPtr->nsPtr = nsPtr;
|
||||
globalPtr->nextPtr = globalTablePtr->buckets[globalHash];
|
||||
@@ -360,7 +375,7 @@ int
|
||||
TclRegisterLiteral(
|
||||
void *ePtr, /* Points to the CompileEnv in whose object
|
||||
* array an object is found or created. */
|
||||
register char *bytes, /* Points to string for which to find or
|
||||
register const char *bytes, /* Points to string for which to find or
|
||||
* create an object in CompileEnv's object
|
||||
* array. */
|
||||
int length, /* Number of bytes in the string. If < 0, the
|
||||
@@ -398,7 +413,7 @@ TclRegisterLiteral(
|
||||
if ((objPtr->length == length) && ((length == 0)
|
||||
|| ((objPtr->bytes[0] == bytes[0])
|
||||
&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
|
||||
if (flags & LITERAL_ON_HEAP) {
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
objIndex = (localPtr - envPtr->literalArrayPtr);
|
||||
@@ -417,7 +432,7 @@ TclRegisterLiteral(
|
||||
* the namespace as the interp's global NS.
|
||||
*/
|
||||
|
||||
if (flags & LITERAL_CMD_NAME) {
|
||||
if ((flags & LITERAL_CMD_NAME)) {
|
||||
if ((length >= 2) && (bytes[0] == ':') && (bytes[1] == ':')) {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
} else {
|
||||
@@ -431,12 +446,13 @@ TclRegisterLiteral(
|
||||
* Is it in the interpreter's global literal table? If not, create it.
|
||||
*/
|
||||
|
||||
globalPtr = NULL;
|
||||
objPtr = TclCreateLiteral(iPtr, bytes, length, hash, &new, nsPtr, flags,
|
||||
&globalPtr);
|
||||
objIndex = AddLocalLiteralEntry(envPtr, objPtr, localHash);
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (globalPtr->refCount < 1) {
|
||||
if (globalPtr != NULL && globalPtr->refCount < 1) {
|
||||
Tcl_Panic("%s: global literal \"%.*s\" had bad refCount %d",
|
||||
"TclRegisterLiteral", (length>60? 60 : length), bytes,
|
||||
globalPtr->refCount);
|
||||
@@ -671,7 +687,7 @@ AddLocalLiteralEntry(
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
bytes = Tcl_GetStringFromObj(objPtr, &length);
|
||||
bytes = TclGetStringFromObj(objPtr, &length);
|
||||
Tcl_Panic("%s: literal \"%.*s\" wasn't found locally",
|
||||
"AddLocalLiteralEntry", (length>60? 60 : length), bytes);
|
||||
}
|
||||
@@ -1025,7 +1041,7 @@ TclInvalidateCmdLiteral(
|
||||
* invalidate a cmd literal. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Obj *literalObjPtr = TclCreateLiteral(iPtr, (char *) name,
|
||||
Tcl_Obj *literalObjPtr = TclCreateLiteral(iPtr, name,
|
||||
strlen(name), -1, NULL, nsPtr, 0, NULL);
|
||||
|
||||
if (literalObjPtr != NULL) {
|
||||
@@ -1147,18 +1163,11 @@ TclVerifyLocalLiteralTable(
|
||||
localPtr=localPtr->nextPtr) {
|
||||
count++;
|
||||
if (localPtr->refCount != -1) {
|
||||
bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
|
||||
bytes = TclGetStringFromObj(localPtr->objPtr, &length);
|
||||
Tcl_Panic("%s: local literal \"%.*s\" had bad refCount %d",
|
||||
"TclVerifyLocalLiteralTable",
|
||||
(length>60? 60 : length), bytes, localPtr->refCount);
|
||||
}
|
||||
if (LookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
|
||||
localPtr->objPtr) == NULL) {
|
||||
bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
|
||||
Tcl_Panic("%s: local literal \"%.*s\" is not global",
|
||||
"TclVerifyLocalLiteralTable",
|
||||
(length>60? 60 : length), bytes);
|
||||
}
|
||||
if (localPtr->objPtr->bytes == NULL) {
|
||||
Tcl_Panic("%s: literal has NULL string rep",
|
||||
"TclVerifyLocalLiteralTable");
|
||||
@@ -1205,7 +1214,7 @@ TclVerifyGlobalLiteralTable(
|
||||
globalPtr=globalPtr->nextPtr) {
|
||||
count++;
|
||||
if (globalPtr->refCount < 1) {
|
||||
bytes = Tcl_GetStringFromObj(globalPtr->objPtr, &length);
|
||||
bytes = TclGetStringFromObj(globalPtr->objPtr, &length);
|
||||
Tcl_Panic("%s: global literal \"%.*s\" had bad refCount %d",
|
||||
"TclVerifyGlobalLiteralTable",
|
||||
(length>60? 60 : length), bytes, globalPtr->refCount);
|
||||
|
||||
+12
-23
@@ -112,7 +112,7 @@ typedef enum {
|
||||
PROMPT_CONTINUE /* Print prompt for command continuation */
|
||||
} PromptType;
|
||||
|
||||
typedef struct InteractiveState {
|
||||
typedef struct {
|
||||
Tcl_Channel input; /* The standard input channel from which lines
|
||||
* are read. */
|
||||
int tty; /* Non-zero means standard input is a
|
||||
@@ -246,7 +246,7 @@ Tcl_SourceRCFile(
|
||||
const char *fileName;
|
||||
Tcl_Channel chan;
|
||||
|
||||
fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY);
|
||||
fileName = Tcl_GetVar2(interp, "tcl_rcFileName", NULL, TCL_GLOBAL_ONLY);
|
||||
if (fileName != NULL) {
|
||||
Tcl_Channel c;
|
||||
const char *fullName;
|
||||
@@ -266,14 +266,18 @@ Tcl_SourceRCFile(
|
||||
|
||||
c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
|
||||
if (c != NULL) {
|
||||
Tcl_Obj *fullNameObj = Tcl_NewStringObj(fullName, -1);
|
||||
|
||||
Tcl_Close(NULL, c);
|
||||
if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
|
||||
Tcl_IncrRefCount(fullNameObj);
|
||||
if (Tcl_FSEvalFileEx(interp, fullNameObj, NULL) != TCL_OK) {
|
||||
chan = Tcl_GetStdChannel(TCL_STDERR);
|
||||
if (chan) {
|
||||
Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
|
||||
Tcl_WriteChars(chan, "\n", 1);
|
||||
}
|
||||
}
|
||||
Tcl_DecrRefCount(fullNameObj);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&temp);
|
||||
@@ -283,7 +287,7 @@ Tcl_SourceRCFile(
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_Main, Tcl_MainEx --
|
||||
* Tcl_MainEx --
|
||||
*
|
||||
* Main program for tclsh and most other Tcl-based applications.
|
||||
*
|
||||
@@ -532,7 +536,7 @@ Tcl_MainEx(
|
||||
* error messages troubles deeper in, so lop it back off.
|
||||
*/
|
||||
|
||||
Tcl_GetStringFromObj(is.commandPtr, &length);
|
||||
TclGetStringFromObj(is.commandPtr, &length);
|
||||
Tcl_SetObjLength(is.commandPtr, --length);
|
||||
code = Tcl_RecordAndEvalObj(interp, is.commandPtr,
|
||||
TCL_EVAL_GLOBAL);
|
||||
@@ -549,7 +553,7 @@ Tcl_MainEx(
|
||||
} else if (is.tty) {
|
||||
resultPtr = Tcl_GetObjResult(interp);
|
||||
Tcl_IncrRefCount(resultPtr);
|
||||
Tcl_GetStringFromObj(resultPtr, &length);
|
||||
TclGetStringFromObj(resultPtr, &length);
|
||||
chan = Tcl_GetStdChannel(TCL_STDOUT);
|
||||
if ((length > 0) && chan) {
|
||||
Tcl_WriteObj(chan, resultPtr);
|
||||
@@ -634,21 +638,6 @@ Tcl_MainEx(
|
||||
|
||||
Tcl_Exit(exitCode);
|
||||
}
|
||||
|
||||
#if (TCL_MAJOR_VERSION == 8) && !defined(UNICODE)
|
||||
#undef Tcl_Main
|
||||
extern DLLEXPORT void
|
||||
Tcl_Main(
|
||||
int argc, /* Number of arguments. */
|
||||
char **argv, /* Array of argument strings. */
|
||||
Tcl_AppInitProc *appInitProc)
|
||||
/* Application-specific initialization
|
||||
* function to call after most initialization
|
||||
* but before starting to execute commands. */
|
||||
{
|
||||
Tcl_MainEx(argc, argv, appInitProc, Tcl_CreateInterp());
|
||||
}
|
||||
#endif /* TCL_MAJOR_VERSION == 8 && !UNICODE */
|
||||
|
||||
#ifndef TCL_ASCII_MAIN
|
||||
|
||||
@@ -808,7 +797,7 @@ StdinProc(
|
||||
goto prompt;
|
||||
}
|
||||
isPtr->prompt = PROMPT_START;
|
||||
Tcl_GetStringFromObj(commandPtr, &length);
|
||||
TclGetStringFromObj(commandPtr, &length);
|
||||
Tcl_SetObjLength(commandPtr, --length);
|
||||
|
||||
/*
|
||||
@@ -839,7 +828,7 @@ StdinProc(
|
||||
chan = Tcl_GetStdChannel(TCL_STDOUT);
|
||||
|
||||
Tcl_IncrRefCount(resultPtr);
|
||||
Tcl_GetStringFromObj(resultPtr, &length);
|
||||
TclGetStringFromObj(resultPtr, &length);
|
||||
if ((length > 0) && (chan != NULL)) {
|
||||
Tcl_WriteObj(chan, resultPtr);
|
||||
Tcl_WriteChars(chan, "\n", 1);
|
||||
|
||||
+75
-45
@@ -1105,8 +1105,6 @@ TclTeardownNamespace(
|
||||
Interp *iPtr = (Interp *) nsPtr->interp;
|
||||
register Tcl_HashEntry *entryPtr;
|
||||
Tcl_HashSearch search;
|
||||
Tcl_Namespace *childNsPtr;
|
||||
Tcl_Command cmd;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -1121,16 +1119,31 @@ TclTeardownNamespace(
|
||||
/*
|
||||
* Delete all commands in this namespace. Be careful when traversing the
|
||||
* hash table: when each command is deleted, it removes itself from the
|
||||
* command table.
|
||||
*
|
||||
* Don't optimize to Tcl_NextHashEntry() because of traces.
|
||||
* command table. Because of traces (and the desire to avoid the quadratic
|
||||
* problems of just using Tcl_FirstHashEntry over and over, [Bug
|
||||
* f97d4ee020]) we copy to a temporary array and then delete all those
|
||||
* commands.
|
||||
*/
|
||||
|
||||
for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search)) {
|
||||
cmd = Tcl_GetHashValue(entryPtr);
|
||||
Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr, cmd);
|
||||
while (nsPtr->cmdTable.numEntries > 0) {
|
||||
int length = nsPtr->cmdTable.numEntries;
|
||||
Command **cmds = TclStackAlloc((Tcl_Interp *) iPtr,
|
||||
sizeof(Command *) * length);
|
||||
|
||||
i = 0;
|
||||
for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_NextHashEntry(&search)) {
|
||||
cmds[i] = Tcl_GetHashValue(entryPtr);
|
||||
cmds[i]->refCount++;
|
||||
i++;
|
||||
}
|
||||
for (i = 0 ; i < length ; i++) {
|
||||
Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr,
|
||||
(Tcl_Command) cmds[i]);
|
||||
TclCleanupCommandMacro(cmds[i]);
|
||||
}
|
||||
TclStackFree((Tcl_Interp *) iPtr, cmds);
|
||||
}
|
||||
Tcl_DeleteHashTable(&nsPtr->cmdTable);
|
||||
Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
|
||||
@@ -1175,25 +1188,54 @@ TclTeardownNamespace(
|
||||
*
|
||||
* BE CAREFUL: When each child is deleted, it will divorce itself from its
|
||||
* parent. You can't traverse a hash table properly if its elements are
|
||||
* being deleted. We use only the Tcl_FirstHashEntry function to be safe.
|
||||
* being deleted. Because of traces (and the desire to avoid the
|
||||
* quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug
|
||||
* f97d4ee020]) we copy to a temporary array and then delete all those
|
||||
* namespaces.
|
||||
*
|
||||
* Don't optimize to Tcl_NextHashEntry() because of traces.
|
||||
* Important: leave the hash table itself still live.
|
||||
*/
|
||||
|
||||
#ifndef BREAK_NAMESPACE_COMPAT
|
||||
for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search)) {
|
||||
childNsPtr = Tcl_GetHashValue(entryPtr);
|
||||
Tcl_DeleteNamespace(childNsPtr);
|
||||
while (nsPtr->childTable.numEntries > 0) {
|
||||
int length = nsPtr->childTable.numEntries;
|
||||
Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
|
||||
sizeof(Namespace *) * length);
|
||||
|
||||
i = 0;
|
||||
for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_NextHashEntry(&search)) {
|
||||
children[i] = Tcl_GetHashValue(entryPtr);
|
||||
children[i]->refCount++;
|
||||
i++;
|
||||
}
|
||||
for (i = 0 ; i < length ; i++) {
|
||||
Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
|
||||
TclNsDecrRefCount(children[i]);
|
||||
}
|
||||
TclStackFree((Tcl_Interp *) iPtr, children);
|
||||
}
|
||||
#else
|
||||
if (nsPtr->childTablePtr != NULL) {
|
||||
for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr,&search)) {
|
||||
childNsPtr = Tcl_GetHashValue(entryPtr);
|
||||
Tcl_DeleteNamespace(childNsPtr);
|
||||
while (nsPtr->childTablePtr->numEntries > 0) {
|
||||
int length = nsPtr->childTablePtr->numEntries;
|
||||
Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
|
||||
sizeof(Namespace *) * length);
|
||||
|
||||
i = 0;
|
||||
for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
|
||||
entryPtr != NULL;
|
||||
entryPtr = Tcl_NextHashEntry(&search)) {
|
||||
children[i] = Tcl_GetHashValue(entryPtr);
|
||||
children[i]->refCount++;
|
||||
i++;
|
||||
}
|
||||
for (i = 0 ; i < length ; i++) {
|
||||
Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
|
||||
TclNsDecrRefCount(children[i]);
|
||||
}
|
||||
TclStackFree((Tcl_Interp *) iPtr, children);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2524,7 +2566,9 @@ Tcl_FindCommand(
|
||||
}
|
||||
|
||||
if (result == TCL_OK) {
|
||||
((Command *)cmd)->flags |= CMD_VIA_RESOLVER;
|
||||
return cmd;
|
||||
|
||||
} else if (result != TCL_CONTINUE) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -2616,6 +2660,7 @@ Tcl_FindCommand(
|
||||
}
|
||||
|
||||
if (cmdPtr != NULL) {
|
||||
cmdPtr->flags &= ~CMD_VIA_RESOLVER;
|
||||
return (Tcl_Command) cmdPtr;
|
||||
}
|
||||
|
||||
@@ -2841,9 +2886,9 @@ GetNamespaceFromObj(
|
||||
resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
nsPtr = resNamePtr->nsPtr;
|
||||
refNsPtr = resNamePtr->refNsPtr;
|
||||
if (!(nsPtr->flags & NS_DYING) && (interp == nsPtr->interp) &&
|
||||
(!refNsPtr || ((interp == refNsPtr->interp) &&
|
||||
(refNsPtr== (Namespace *) Tcl_GetCurrentNamespace(interp))))){
|
||||
if (!(nsPtr->flags & NS_DYING) && (interp == nsPtr->interp)
|
||||
&& (!refNsPtr || (refNsPtr ==
|
||||
(Namespace *) TclGetCurrentNamespace(interp)))) {
|
||||
*nsPtrPtr = (Tcl_Namespace *) nsPtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -3312,14 +3357,7 @@ NRNamespaceEvalCmd(
|
||||
(void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
|
||||
namespacePtr, /*isProcCallFrame*/ 0);
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
framePtr->objc = objc;
|
||||
framePtr->objv = objv;
|
||||
} else {
|
||||
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
|
||||
}
|
||||
framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
|
||||
|
||||
if (objc == 3) {
|
||||
/*
|
||||
@@ -3726,7 +3764,6 @@ NRNamespaceInscopeCmd(
|
||||
{
|
||||
Tcl_Namespace *namespacePtr;
|
||||
CallFrame *framePtr, **framePtrPtr;
|
||||
register Interp *iPtr = (Interp *) interp;
|
||||
int i;
|
||||
Tcl_Obj *cmdObjPtr;
|
||||
|
||||
@@ -3752,14 +3789,7 @@ NRNamespaceInscopeCmd(
|
||||
(void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
|
||||
namespacePtr, /*isProcCallFrame*/ 0);
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
framePtr->objc = objc;
|
||||
framePtr->objv = objv;
|
||||
} else {
|
||||
framePtr->objc = objc + iPtr->ensembleRewrite.numRemovedObjs
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
framePtr->objv = iPtr->ensembleRewrite.sourceObjs;
|
||||
}
|
||||
framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
|
||||
|
||||
/*
|
||||
* Execute the command. If there is just one argument, just treat it as a
|
||||
@@ -4511,8 +4541,8 @@ NamespaceUpvarCmd(
|
||||
savedNsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
|
||||
iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
|
||||
otherPtr = TclObjLookupVarEx(interp, objv[0], NULL,
|
||||
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
|
||||
/*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
|
||||
(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
|
||||
"access", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
|
||||
iPtr->varFramePtr->nsPtr = (Namespace *) savedNsPtr;
|
||||
if (otherPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
@@ -4752,7 +4782,7 @@ SetNsNameFromAny(
|
||||
if ((name[0] == ':') && (name[1] == ':')) {
|
||||
resNamePtr->refNsPtr = NULL;
|
||||
} else {
|
||||
resNamePtr->refNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
|
||||
resNamePtr->refNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
}
|
||||
resNamePtr->refCount = 1;
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
+13
-16
@@ -68,12 +68,9 @@ static int CloneObjectMethod(Tcl_Interp *interp, Object *oPtr,
|
||||
static void DeletedDefineNamespace(ClientData clientData);
|
||||
static void DeletedObjdefNamespace(ClientData clientData);
|
||||
static void DeletedHelpersNamespace(ClientData clientData);
|
||||
static int FinalizeAlloc(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int FinalizeNext(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int FinalizeObjectCall(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc FinalizeAlloc;
|
||||
static Tcl_NRPostProc FinalizeNext;
|
||||
static Tcl_NRPostProc FinalizeObjectCall;
|
||||
static int InitFoundation(Tcl_Interp *interp);
|
||||
static void KillFoundation(ClientData clientData,
|
||||
Tcl_Interp *interp);
|
||||
@@ -269,7 +266,7 @@ TclOOInit(
|
||||
* to be fully provided.
|
||||
*/
|
||||
|
||||
if (Tcl_Eval(interp, initScript) != TCL_OK) {
|
||||
if (Tcl_EvalEx(interp, initScript, -1, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -463,7 +460,7 @@ InitFoundation(
|
||||
if (TclOODefineSlots(fPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return Tcl_Eval(interp, slotScript);
|
||||
return Tcl_EvalEx(interp, slotScript, -1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1687,7 +1684,7 @@ Tcl_NewObjectInstance(
|
||||
TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL);
|
||||
|
||||
if (contextPtr != NULL) {
|
||||
int result;
|
||||
int isRoot, result;
|
||||
Tcl_InterpState state;
|
||||
|
||||
state = Tcl_SaveInterpState(interp, TCL_OK);
|
||||
@@ -1698,13 +1695,14 @@ Tcl_NewObjectInstance(
|
||||
* Adjust the ensmble tracking record if necessary. [Bug 3514761]
|
||||
*/
|
||||
|
||||
if (((Interp*) interp)->ensembleRewrite.sourceObjs) {
|
||||
((Interp*) interp)->ensembleRewrite.numInsertedObjs += skip-1;
|
||||
((Interp*) interp)->ensembleRewrite.numRemovedObjs += skip-1;
|
||||
}
|
||||
isRoot = TclInitRewriteEnsemble(interp, skip, skip, objv);
|
||||
result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr,
|
||||
objc, objv);
|
||||
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* It's an error if the object was whacked in the constructor.
|
||||
* Force this if it isn't already an error (don't want to lose
|
||||
@@ -1827,9 +1825,8 @@ TclNRNewObjectInstance(
|
||||
* Adjust the ensmble tracking record if necessary. [Bug 3514761]
|
||||
*/
|
||||
|
||||
if (((Interp *) interp)->ensembleRewrite.sourceObjs) {
|
||||
((Interp *) interp)->ensembleRewrite.numInsertedObjs += skip - 1;
|
||||
((Interp *) interp)->ensembleRewrite.numRemovedObjs += skip - 1;
|
||||
if (TclInitRewriteEnsemble(interp, skip, skip, objv)) {
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+3
-6
@@ -70,15 +70,12 @@ static void AddSimpleClassChainToCallContext(Class *classPtr,
|
||||
Class *const filterDecl);
|
||||
static int CmpStr(const void *ptr1, const void *ptr2);
|
||||
static void DupMethodNameRep(Tcl_Obj *srcPtr, Tcl_Obj *dstPtr);
|
||||
static int FinalizeMethodRefs(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc FinalizeMethodRefs;
|
||||
static void FreeMethodNameRep(Tcl_Obj *objPtr);
|
||||
static inline int IsStillValid(CallChain *callPtr, Object *oPtr,
|
||||
int flags, int reuseMask);
|
||||
static int ResetFilterFlags(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int SetFilterFlags(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc ResetFilterFlags;
|
||||
static Tcl_NRPostProc SetFilterFlags;
|
||||
static inline void StashCallChain(Tcl_Obj *objPtr, CallChain *callPtr);
|
||||
|
||||
/*
|
||||
|
||||
+21
-47
@@ -525,7 +525,7 @@ TclOOUnknownDefinition(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
soughtStr = Tcl_GetStringFromObj(objv[1], &soughtLen);
|
||||
soughtStr = TclGetStringFromObj(objv[1], &soughtLen);
|
||||
if (soughtLen == 0) {
|
||||
goto noMatch;
|
||||
}
|
||||
@@ -585,7 +585,7 @@ FindCommand(
|
||||
Tcl_Namespace *const namespacePtr)
|
||||
{
|
||||
int length;
|
||||
const char *nameStr, *string = Tcl_GetStringFromObj(stringObj, &length);
|
||||
const char *nameStr, *string = TclGetStringFromObj(stringObj, &length);
|
||||
register Namespace *const nsPtr = (Namespace *) namespacePtr;
|
||||
FOREACH_HASH_DECLS;
|
||||
Tcl_Command cmd, cmd2;
|
||||
@@ -774,7 +774,7 @@ GenerateErrorInfo(
|
||||
int length;
|
||||
Tcl_Obj *realNameObj = Tcl_ObjectDeleted((Tcl_Object) oPtr)
|
||||
? savedNameObj : TclOOObjectName(interp, oPtr);
|
||||
const char *objName = Tcl_GetStringFromObj(realNameObj, &length);
|
||||
const char *objName = TclGetStringFromObj(realNameObj, &length);
|
||||
int limit = OBJNAME_LENGTH_IN_ERRORINFO_LIMIT;
|
||||
int overflow = (length > limit);
|
||||
|
||||
@@ -847,9 +847,8 @@ TclOODefineObjCmd(
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Command cmd;
|
||||
int dummy;
|
||||
int isRoot, dummy;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
@@ -861,18 +860,7 @@ TclOODefineObjCmd(
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 3;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 1;
|
||||
} else {
|
||||
int ni = iPtr->ensembleRewrite.numInsertedObjs;
|
||||
if (ni < 3) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += 3 - ni;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs -= 2;
|
||||
}
|
||||
}
|
||||
isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
@@ -894,6 +882,9 @@ TclOODefineObjCmd(
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
@@ -927,7 +918,7 @@ TclOOObjDefObjCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
int result;
|
||||
int isRoot, result;
|
||||
Object *oPtr;
|
||||
|
||||
if (objc < 3) {
|
||||
@@ -962,7 +953,6 @@ TclOOObjDefObjCmd(
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Command cmd;
|
||||
int dummy;
|
||||
|
||||
@@ -976,18 +966,7 @@ TclOOObjDefObjCmd(
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 3;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 1;
|
||||
} else {
|
||||
int ni = iPtr->ensembleRewrite.numInsertedObjs;
|
||||
if (ni < 3) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += 3 - ni;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs -= 2;
|
||||
}
|
||||
}
|
||||
isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
@@ -1009,6 +988,10 @@ TclOOObjDefObjCmd(
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
|
||||
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
@@ -1077,9 +1060,8 @@ TclOODefineSelfObjCmd(
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Command cmd;
|
||||
int dummy;
|
||||
int isRoot, dummy;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
@@ -1091,18 +1073,7 @@ TclOODefineSelfObjCmd(
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
if (iPtr->ensembleRewrite.sourceObjs == NULL) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 2;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 1;
|
||||
} else {
|
||||
int ni = iPtr->ensembleRewrite.numInsertedObjs;
|
||||
if (ni < 2) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += 2 - ni;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs -= 1;
|
||||
}
|
||||
}
|
||||
isRoot = TclInitRewriteEnsemble(interp, 2, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
@@ -1124,6 +1095,9 @@ TclOODefineSelfObjCmd(
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-1, objs, TCL_EVAL_INVOKE);
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
@@ -1265,7 +1239,7 @@ TclOODefineConstructorObjCmd(
|
||||
}
|
||||
clsPtr = oPtr->classPtr;
|
||||
|
||||
Tcl_GetStringFromObj(objv[2], &bodyLength);
|
||||
TclGetStringFromObj(objv[2], &bodyLength);
|
||||
if (bodyLength > 0) {
|
||||
/*
|
||||
* Create the method structure.
|
||||
@@ -1384,7 +1358,7 @@ TclOODefineDestructorObjCmd(
|
||||
}
|
||||
clsPtr = oPtr->classPtr;
|
||||
|
||||
Tcl_GetStringFromObj(objv[1], &bodyLength);
|
||||
TclGetStringFromObj(objv[1], &bodyLength);
|
||||
if (bodyLength > 0) {
|
||||
/*
|
||||
* Create the method structure.
|
||||
|
||||
+11
-24
@@ -70,10 +70,8 @@ static Tcl_Obj ** InitEnsembleRewrite(Tcl_Interp *interp, int objc,
|
||||
static int InvokeProcedureMethod(ClientData clientData,
|
||||
Tcl_Interp *interp, Tcl_ObjectContext context,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int FinalizeForwardCall(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int FinalizePMCall(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static Tcl_NRPostProc FinalizeForwardCall;
|
||||
static Tcl_NRPostProc FinalizePMCall;
|
||||
static int PushMethodCallFrame(Tcl_Interp *interp,
|
||||
CallContext *contextPtr, ProcedureMethod *pmPtr,
|
||||
int objc, Tcl_Obj *const *objv,
|
||||
@@ -1168,7 +1166,7 @@ MethodErrorHandler(
|
||||
CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData;
|
||||
Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
|
||||
const char *objectName, *kindName, *methodName =
|
||||
Tcl_GetStringFromObj(mPtr->namePtr, &nameLen);
|
||||
TclGetStringFromObj(mPtr->namePtr, &nameLen);
|
||||
Object *declarerPtr;
|
||||
|
||||
if (mPtr->declaringObjectPtr != NULL) {
|
||||
@@ -1458,6 +1456,11 @@ InvokeForwardMethod(
|
||||
argObjs = InitEnsembleRewrite(interp, objc, objv, skip,
|
||||
numPrefixes, prefixObjs, &len);
|
||||
Tcl_NRAddCallback(interp, FinalizeForwardCall, argObjs, NULL, NULL, NULL);
|
||||
/*
|
||||
* NOTE: The combination of direct set of iPtr->lookupNsPtr and the use
|
||||
* of the TCL_EVAL_NOERR flag results in an evaluation configuration
|
||||
* very much like TCL_EVAL_INVOKE.
|
||||
*/
|
||||
((Interp *)interp)->lookupNsPtr
|
||||
= (Namespace *) contextPtr->oPtr->namespacePtr;
|
||||
return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_NOERR, NULL);
|
||||
@@ -1594,12 +1597,9 @@ InitEnsembleRewrite(
|
||||
int *lengthPtr) /* Where to write the resulting length of the
|
||||
* array of rewritten arguments. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
|
||||
Tcl_Obj **argObjs;
|
||||
unsigned len = rewriteLength + objc - toRewrite;
|
||||
Tcl_Obj **argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len);
|
||||
|
||||
argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len);
|
||||
memcpy(argObjs, rewriteObjs, rewriteLength * sizeof(Tcl_Obj *));
|
||||
memcpy(argObjs + rewriteLength, objv + toRewrite,
|
||||
sizeof(Tcl_Obj *) * (objc - toRewrite));
|
||||
@@ -1613,22 +1613,9 @@ InitEnsembleRewrite(
|
||||
* (and unavoidably).
|
||||
*/
|
||||
|
||||
if (isRootEnsemble) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = toRewrite;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = rewriteLength;
|
||||
} else {
|
||||
int numIns = iPtr->ensembleRewrite.numInsertedObjs;
|
||||
|
||||
if (numIns < toRewrite) {
|
||||
iPtr->ensembleRewrite.numRemovedObjs += toRewrite - numIns;
|
||||
iPtr->ensembleRewrite.numInsertedObjs += rewriteLength - 1;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs +=
|
||||
rewriteLength - toRewrite;
|
||||
}
|
||||
if (TclInitRewriteEnsemble(interp, toRewrite, rewriteLength, objv)) {
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
*lengthPtr = len;
|
||||
return argObjs;
|
||||
}
|
||||
|
||||
+80
-92
@@ -402,7 +402,6 @@ TclInitObjSubsystem(void)
|
||||
Tcl_RegisterObjType(&tclListType);
|
||||
Tcl_RegisterObjType(&tclDictType);
|
||||
Tcl_RegisterObjType(&tclByteCodeType);
|
||||
Tcl_RegisterObjType(&tclArraySearchType);
|
||||
Tcl_RegisterObjType(&tclCmdNameType);
|
||||
Tcl_RegisterObjType(&tclRegexpType);
|
||||
Tcl_RegisterObjType(&tclProcBodyType);
|
||||
@@ -663,7 +662,7 @@ TclContinuationsEnterDerived(
|
||||
* better way which doesn't shimmer?)
|
||||
*/
|
||||
|
||||
Tcl_GetStringFromObj(objPtr, &length);
|
||||
TclGetStringFromObj(objPtr, &length);
|
||||
end = start + length; /* First char after the word */
|
||||
|
||||
/*
|
||||
@@ -1989,7 +1988,7 @@ TclSetBooleanFromAny(
|
||||
badBoolean:
|
||||
if (interp != NULL) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(objPtr, &length);
|
||||
const char *str = TclGetStringFromObj(objPtr, &length);
|
||||
Tcl_Obj *msg;
|
||||
|
||||
TclNewLiteralStringObj(msg, "expected boolean value but got \"");
|
||||
@@ -4048,7 +4047,7 @@ TclFreeObjEntry(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
TCL_HASH_TYPE
|
||||
TclHashObjKey(
|
||||
Tcl_HashTable *tablePtr, /* Hash table. */
|
||||
void *keyPtr) /* Key from which to compute hash value. */
|
||||
@@ -4098,7 +4097,7 @@ TclHashObjKey(
|
||||
result += (result << 3) + UCHAR(*++string);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return (TCL_HASH_TYPE) result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4152,11 +4151,10 @@ Tcl_GetCommandFromObj(
|
||||
*/
|
||||
|
||||
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if ((objPtr->typePtr == &tclCmdNameType) && (resPtr != NULL)) {
|
||||
if (objPtr->typePtr == &tclCmdNameType) {
|
||||
register Command *cmdPtr = resPtr->cmdPtr;
|
||||
|
||||
if ((cmdPtr->cmdEpoch == resPtr->cmdEpoch)
|
||||
&& !(cmdPtr->flags & CMD_IS_DELETED)
|
||||
&& (interp == cmdPtr->nsPtr->interp)
|
||||
&& !(cmdPtr->nsPtr->flags & NS_DYING)) {
|
||||
register Namespace *refNsPtr = (Namespace *)
|
||||
@@ -4204,6 +4202,59 @@ Tcl_GetCommandFromObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
SetCmdNameObj(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr,
|
||||
Command *cmdPtr,
|
||||
ResolvedCmdName *resPtr)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ResolvedCmdName *fillPtr;
|
||||
const char *name = TclGetString(objPtr);
|
||||
|
||||
if (resPtr) {
|
||||
fillPtr = resPtr;
|
||||
} else {
|
||||
fillPtr = ckalloc(sizeof(ResolvedCmdName));
|
||||
fillPtr->refCount = 1;
|
||||
}
|
||||
|
||||
fillPtr->cmdPtr = cmdPtr;
|
||||
cmdPtr->refCount++;
|
||||
fillPtr->cmdEpoch = cmdPtr->cmdEpoch;
|
||||
|
||||
/* NOTE: relying on NULL termination here. */
|
||||
if ((name[0] == ':') && (name[1] == ':')) {
|
||||
/*
|
||||
* Fully qualified names always resolve to same thing. No need
|
||||
* to record resolution context information.
|
||||
*/
|
||||
|
||||
fillPtr->refNsPtr = NULL;
|
||||
fillPtr->refNsId = 0; /* Will not be read */
|
||||
fillPtr->refNsCmdEpoch = 0; /* Will not be read */
|
||||
} else {
|
||||
/*
|
||||
* Record current state of current namespace as the resolution
|
||||
* context of this command name lookup.
|
||||
*/
|
||||
Namespace *currNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
fillPtr->refNsPtr = currNsPtr;
|
||||
fillPtr->refNsId = currNsPtr->nsId;
|
||||
fillPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
|
||||
}
|
||||
|
||||
if (resPtr == NULL) {
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = fillPtr;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclCmdNameType;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TclSetCmdNameObj(
|
||||
Tcl_Interp *interp, /* Points to interpreter containing command
|
||||
@@ -4213,45 +4264,16 @@ TclSetCmdNameObj(
|
||||
Command *cmdPtr) /* Points to Command structure that the
|
||||
* CmdName object should refer to. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
register ResolvedCmdName *resPtr;
|
||||
register Namespace *currNsPtr;
|
||||
const char *name;
|
||||
|
||||
if (objPtr->typePtr == &tclCmdNameType) {
|
||||
return;
|
||||
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (resPtr != NULL && resPtr->cmdPtr == cmdPtr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cmdPtr->refCount++;
|
||||
resPtr = ckalloc(sizeof(ResolvedCmdName));
|
||||
resPtr->cmdPtr = cmdPtr;
|
||||
resPtr->cmdEpoch = cmdPtr->cmdEpoch;
|
||||
resPtr->refCount = 1;
|
||||
|
||||
name = TclGetString(objPtr);
|
||||
if ((*name++ == ':') && (*name == ':')) {
|
||||
/*
|
||||
* The name is fully qualified: set the referring namespace to
|
||||
* NULL.
|
||||
*/
|
||||
|
||||
resPtr->refNsPtr = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Get the current namespace.
|
||||
*/
|
||||
|
||||
currNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
resPtr->refNsPtr = currNsPtr;
|
||||
resPtr->refNsId = currNsPtr->nsId;
|
||||
resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
|
||||
}
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclCmdNameType;
|
||||
SetCmdNameObj(interp, objPtr, cmdPtr, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4282,7 +4304,6 @@ FreeCmdNameInternalRep(
|
||||
{
|
||||
register ResolvedCmdName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
if (resPtr != NULL) {
|
||||
/*
|
||||
* Decrement the reference count of the ResolvedCmdName structure. If
|
||||
* there are no more uses, free the ResolvedCmdName structure.
|
||||
@@ -4300,7 +4321,6 @@ FreeCmdNameInternalRep(
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
ckfree(resPtr);
|
||||
}
|
||||
}
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
@@ -4333,9 +4353,7 @@ DupCmdNameInternalRep(
|
||||
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
if (resPtr != NULL) {
|
||||
resPtr->refCount++;
|
||||
}
|
||||
copyPtr->typePtr = &tclCmdNameType;
|
||||
}
|
||||
|
||||
@@ -4365,10 +4383,8 @@ SetCmdNameFromAny(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
register Tcl_Obj *objPtr) /* The object to convert. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
const char *name;
|
||||
register Command *cmdPtr;
|
||||
Namespace *currNsPtr;
|
||||
register ResolvedCmdName *resPtr;
|
||||
|
||||
if (interp == NULL) {
|
||||
@@ -4388,59 +4404,31 @@ SetCmdNameFromAny(
|
||||
Tcl_FindCommand(interp, name, /*ns*/ NULL, /*flags*/ 0);
|
||||
|
||||
/*
|
||||
* Free the old internalRep before setting the new one. Do this after
|
||||
* getting the string rep to allow the conversion code (in particular,
|
||||
* Tcl_GetStringFromObj) to use that old internalRep.
|
||||
* Stop shimmering and caching nothing when we found nothing. Just
|
||||
* report the failure to find the command as an error.
|
||||
*/
|
||||
|
||||
if (cmdPtr) {
|
||||
cmdPtr->refCount++;
|
||||
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if ((objPtr->typePtr == &tclCmdNameType)
|
||||
&& resPtr && (resPtr->refCount == 1)) {
|
||||
/*
|
||||
* Reuse the old ResolvedCmdName struct instead of freeing it
|
||||
*/
|
||||
if (cmdPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Command *oldCmdPtr = resPtr->cmdPtr;
|
||||
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if ((objPtr->typePtr == &tclCmdNameType) && (resPtr->refCount == 1)) {
|
||||
/*
|
||||
* Re-use existing ResolvedCmdName struct when possible.
|
||||
* Cleanup the old fields that need it.
|
||||
*/
|
||||
|
||||
if (--oldCmdPtr->refCount == 0) {
|
||||
TclCleanupCommandMacro(oldCmdPtr);
|
||||
}
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
resPtr = ckalloc(sizeof(ResolvedCmdName));
|
||||
resPtr->refCount = 1;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclCmdNameType;
|
||||
}
|
||||
resPtr->cmdPtr = cmdPtr;
|
||||
resPtr->cmdEpoch = cmdPtr->cmdEpoch;
|
||||
if ((*name++ == ':') && (*name == ':')) {
|
||||
/*
|
||||
* The name is fully qualified: set the referring namespace to
|
||||
* NULL.
|
||||
*/
|
||||
Command *oldCmdPtr = resPtr->cmdPtr;
|
||||
|
||||
resPtr->refNsPtr = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Get the current namespace.
|
||||
*/
|
||||
|
||||
currNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
resPtr->refNsPtr = currNsPtr;
|
||||
resPtr->refNsId = currNsPtr->nsId;
|
||||
resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
|
||||
if (--oldCmdPtr->refCount == 0) {
|
||||
TclCleanupCommandMacro(oldCmdPtr);
|
||||
}
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclCmdNameType;
|
||||
resPtr = NULL;
|
||||
}
|
||||
|
||||
SetCmdNameObj(interp, objPtr, cmdPtr, resPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ ConvertZeroEffectToNOP(
|
||||
TclGetUInt1AtPtr(currentInstPtr + 1));
|
||||
int numBytes;
|
||||
|
||||
(void) Tcl_GetStringFromObj(litPtr, &numBytes);
|
||||
(void) TclGetStringFromObj(litPtr, &numBytes);
|
||||
if (numBytes == 0) {
|
||||
blank = size + InstLength(nextInst);
|
||||
}
|
||||
@@ -248,7 +248,7 @@ ConvertZeroEffectToNOP(
|
||||
TclGetUInt4AtPtr(currentInstPtr + 1));
|
||||
int numBytes;
|
||||
|
||||
(void) Tcl_GetStringFromObj(litPtr, &numBytes);
|
||||
(void) TclGetStringFromObj(litPtr, &numBytes);
|
||||
if (numBytes == 0) {
|
||||
blank = size + InstLength(nextInst);
|
||||
}
|
||||
|
||||
+77
-101
@@ -167,6 +167,8 @@ static int ParseTokens(const char *src, int numBytes, int mask,
|
||||
int flags, Tcl_Parse *parsePtr);
|
||||
static int ParseWhiteSpace(const char *src, int numBytes,
|
||||
int *incompletePtr, char *typePtr);
|
||||
static int ParseAllWhiteSpace(const char *src, int numBytes,
|
||||
int *incompletePtr);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -298,9 +300,43 @@ Tcl_ParseCommand(
|
||||
*/
|
||||
|
||||
parsePtr->commandStart = src;
|
||||
type = CHAR_TYPE(*src);
|
||||
scanned = 1; /* Can't have missing whitepsace before first word. */
|
||||
while (1) {
|
||||
int expandWord = 0;
|
||||
|
||||
/* Are we at command termination? */
|
||||
|
||||
if ((numBytes == 0) || (type & terminators) != 0) {
|
||||
parsePtr->term = src;
|
||||
parsePtr->commandSize = src + (numBytes != 0)
|
||||
- parsePtr->commandStart;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* Are we missing white space after previous word? */
|
||||
|
||||
if (scanned == 0) {
|
||||
if (src[-1] == '"') {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra characters after close-quote", -1));
|
||||
}
|
||||
parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA;
|
||||
} else {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra characters after close-brace", -1));
|
||||
}
|
||||
parsePtr->errorType = TCL_PARSE_BRACE_EXTRA;
|
||||
}
|
||||
parsePtr->term = src;
|
||||
error:
|
||||
Tcl_FreeParse(parsePtr);
|
||||
parsePtr->commandSize = parsePtr->end - parsePtr->commandStart;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the token for the word.
|
||||
*/
|
||||
@@ -310,23 +346,6 @@ Tcl_ParseCommand(
|
||||
tokenPtr = &parsePtr->tokenPtr[wordIndex];
|
||||
tokenPtr->type = TCL_TOKEN_WORD;
|
||||
|
||||
/*
|
||||
* Skip white space before the word. Also skip a backslash-newline
|
||||
* sequence: it should be treated just like white space.
|
||||
*/
|
||||
|
||||
scanned = ParseWhiteSpace(src,numBytes, &parsePtr->incomplete, &type);
|
||||
src += scanned;
|
||||
numBytes -= scanned;
|
||||
if (numBytes == 0) {
|
||||
parsePtr->term = src;
|
||||
break;
|
||||
}
|
||||
if ((type & terminators) != 0) {
|
||||
parsePtr->term = src;
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
tokenPtr->start = src;
|
||||
parsePtr->numTokens++;
|
||||
parsePtr->numWords++;
|
||||
@@ -546,52 +565,12 @@ Tcl_ParseCommand(
|
||||
tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do two additional checks: (a) make sure we're really at the end of
|
||||
* a word (there might have been garbage left after a quoted or braced
|
||||
* word), and (b) check for the end of the command.
|
||||
*/
|
||||
/* Parse the whitespace between words. */
|
||||
|
||||
scanned = ParseWhiteSpace(src,numBytes, &parsePtr->incomplete, &type);
|
||||
if (scanned) {
|
||||
src += scanned;
|
||||
numBytes -= scanned;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numBytes == 0) {
|
||||
parsePtr->term = src;
|
||||
break;
|
||||
}
|
||||
if ((type & terminators) != 0) {
|
||||
parsePtr->term = src;
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
if (src[-1] == '"') {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra characters after close-quote", -1));
|
||||
}
|
||||
parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA;
|
||||
} else {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra characters after close-brace", -1));
|
||||
}
|
||||
parsePtr->errorType = TCL_PARSE_BRACE_EXTRA;
|
||||
}
|
||||
parsePtr->term = src;
|
||||
goto error;
|
||||
src += scanned;
|
||||
numBytes -= scanned;
|
||||
}
|
||||
|
||||
parsePtr->commandSize = src - parsePtr->commandStart;
|
||||
return TCL_OK;
|
||||
|
||||
error:
|
||||
Tcl_FreeParse(parsePtr);
|
||||
parsePtr->commandSize = parsePtr->end - parsePtr->commandStart;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -733,22 +712,31 @@ ParseWhiteSpace(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
ParseAllWhiteSpace(
|
||||
const char *src, /* First character to parse. */
|
||||
int numBytes, /* Max number of byes to scan */
|
||||
int *incompletePtr) /* Set true if parse is incomplete. */
|
||||
{
|
||||
char type;
|
||||
const char *p = src;
|
||||
|
||||
do {
|
||||
int scanned = ParseWhiteSpace(p, numBytes, incompletePtr, &type);
|
||||
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
} while (numBytes && (*p == '\n') && (p++, --numBytes));
|
||||
return (p-src);
|
||||
}
|
||||
|
||||
int
|
||||
TclParseAllWhiteSpace(
|
||||
const char *src, /* First character to parse. */
|
||||
int numBytes) /* Max number of byes to scan */
|
||||
{
|
||||
int dummy;
|
||||
char type;
|
||||
const char *p = src;
|
||||
|
||||
do {
|
||||
int scanned = ParseWhiteSpace(p, numBytes, &dummy, &type);
|
||||
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
} while (numBytes && (*p == '\n') && (p++, --numBytes));
|
||||
return (p-src);
|
||||
return ParseAllWhiteSpace(src, numBytes, &dummy);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1021,17 +1009,12 @@ ParseComment(
|
||||
* command. */
|
||||
{
|
||||
register const char *p = src;
|
||||
int incomplete = parsePtr->incomplete;
|
||||
|
||||
while (numBytes) {
|
||||
char type;
|
||||
int scanned;
|
||||
|
||||
do {
|
||||
scanned = ParseWhiteSpace(p, numBytes,
|
||||
&parsePtr->incomplete, &type);
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
} while (numBytes && (*p == '\n') && (p++,numBytes--));
|
||||
int scanned = ParseAllWhiteSpace(p, numBytes, &incomplete);
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
|
||||
if ((numBytes == 0) || (*p != '#')) {
|
||||
break;
|
||||
@@ -1040,35 +1023,28 @@ ParseComment(
|
||||
parsePtr->commentStart = p;
|
||||
}
|
||||
|
||||
p++;
|
||||
numBytes--;
|
||||
while (numBytes) {
|
||||
if (*p == '\\') {
|
||||
scanned = ParseWhiteSpace(p, numBytes, &parsePtr->incomplete,
|
||||
&type);
|
||||
if (scanned) {
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
} else {
|
||||
/*
|
||||
* General backslash substitution in comments isn't part
|
||||
* of the formal spec, but test parse-15.47 and history
|
||||
* indicate that it has been the de facto rule. Don't
|
||||
* change it now.
|
||||
*/
|
||||
|
||||
TclParseBackslash(p, numBytes, &scanned, NULL);
|
||||
p += scanned;
|
||||
numBytes -= scanned;
|
||||
}
|
||||
} else {
|
||||
if (*p == '\n') {
|
||||
p++;
|
||||
numBytes--;
|
||||
if (p[-1] == '\n') {
|
||||
break;
|
||||
}
|
||||
if (*p == '\\') {
|
||||
p++;
|
||||
numBytes--;
|
||||
if (numBytes == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
incomplete = (*p == '\n');
|
||||
p++;
|
||||
numBytes--;
|
||||
}
|
||||
parsePtr->commentSize = p - parsePtr->commentStart;
|
||||
}
|
||||
parsePtr->incomplete = incomplete;
|
||||
return (p - src);
|
||||
}
|
||||
|
||||
@@ -2244,7 +2220,7 @@ TclSubstTokens(
|
||||
if (result == 0) {
|
||||
clPos = 0;
|
||||
} else {
|
||||
Tcl_GetStringFromObj(result, &clPos);
|
||||
TclGetStringFromObj(result, &clPos);
|
||||
}
|
||||
|
||||
if (numCL >= maxNumCL) {
|
||||
@@ -2520,7 +2496,7 @@ TclObjCommandComplete(
|
||||
* check. */
|
||||
{
|
||||
int length;
|
||||
const char *script = Tcl_GetStringFromObj(objPtr, &length);
|
||||
const char *script = TclGetStringFromObj(objPtr, &length);
|
||||
|
||||
return CommandComplete(script, length);
|
||||
}
|
||||
|
||||
+33
-29
@@ -231,7 +231,7 @@ TclFSNormalizeAbsolutePath(
|
||||
retVal = Tcl_NewStringObj(path, dirSep - path);
|
||||
Tcl_IncrRefCount(retVal);
|
||||
}
|
||||
Tcl_GetStringFromObj(retVal, &curLen);
|
||||
TclGetStringFromObj(retVal, &curLen);
|
||||
if (curLen == 0) {
|
||||
Tcl_AppendToObj(retVal, dirSep, 1);
|
||||
}
|
||||
@@ -257,7 +257,7 @@ TclFSNormalizeAbsolutePath(
|
||||
retVal = Tcl_NewStringObj(path, dirSep - path);
|
||||
Tcl_IncrRefCount(retVal);
|
||||
}
|
||||
Tcl_GetStringFromObj(retVal, &curLen);
|
||||
TclGetStringFromObj(retVal, &curLen);
|
||||
if (curLen == 0) {
|
||||
Tcl_AppendToObj(retVal, dirSep, 1);
|
||||
}
|
||||
@@ -288,7 +288,7 @@ TclFSNormalizeAbsolutePath(
|
||||
*/
|
||||
|
||||
const char *path =
|
||||
Tcl_GetStringFromObj(retVal, &curLen);
|
||||
TclGetStringFromObj(retVal, &curLen);
|
||||
|
||||
while (--curLen >= 0) {
|
||||
if (IsSeparatorOrNull(path[curLen])) {
|
||||
@@ -303,7 +303,7 @@ TclFSNormalizeAbsolutePath(
|
||||
Tcl_SetObjLength(retVal, curLen+1);
|
||||
Tcl_AppendObjToObj(retVal, linkObj);
|
||||
TclDecrRefCount(linkObj);
|
||||
linkStr = Tcl_GetStringFromObj(retVal, &curLen);
|
||||
linkStr = TclGetStringFromObj(retVal, &curLen);
|
||||
} else {
|
||||
/*
|
||||
* Absolute link.
|
||||
@@ -316,7 +316,7 @@ TclFSNormalizeAbsolutePath(
|
||||
} else {
|
||||
retVal = linkObj;
|
||||
}
|
||||
linkStr = Tcl_GetStringFromObj(retVal, &curLen);
|
||||
linkStr = TclGetStringFromObj(retVal, &curLen);
|
||||
|
||||
/*
|
||||
* Convert to forward-slashes on windows.
|
||||
@@ -333,7 +333,7 @@ TclFSNormalizeAbsolutePath(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
linkStr = Tcl_GetStringFromObj(retVal, &curLen);
|
||||
linkStr = TclGetStringFromObj(retVal, &curLen);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -404,7 +404,7 @@ TclFSNormalizeAbsolutePath(
|
||||
|
||||
if (tclPlatform == TCL_PLATFORM_WINDOWS) {
|
||||
int len;
|
||||
const char *path = Tcl_GetStringFromObj(retVal, &len);
|
||||
const char *path = TclGetStringFromObj(retVal, &len);
|
||||
|
||||
if (len == 2 && path[0] != 0 && path[1] == ':') {
|
||||
if (Tcl_IsShared(retVal)) {
|
||||
@@ -579,7 +579,7 @@ TclPathPart(
|
||||
|
||||
int numBytes;
|
||||
const char *rest =
|
||||
Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
|
||||
TclGetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
|
||||
|
||||
if (strchr(rest, '/') != NULL) {
|
||||
goto standardPath;
|
||||
@@ -617,7 +617,7 @@ TclPathPart(
|
||||
|
||||
int numBytes;
|
||||
const char *rest =
|
||||
Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
|
||||
TclGetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
|
||||
|
||||
if (strchr(rest, '/') != NULL) {
|
||||
goto standardPath;
|
||||
@@ -646,7 +646,7 @@ TclPathPart(
|
||||
const char *fileName, *extension;
|
||||
int length;
|
||||
|
||||
fileName = Tcl_GetStringFromObj(fsPathPtr->normPathPtr,
|
||||
fileName = TclGetStringFromObj(fsPathPtr->normPathPtr,
|
||||
&length);
|
||||
extension = TclGetExtension(fileName);
|
||||
if (extension == NULL) {
|
||||
@@ -698,7 +698,7 @@ TclPathPart(
|
||||
int length;
|
||||
const char *fileName, *extension;
|
||||
|
||||
fileName = Tcl_GetStringFromObj(pathPtr, &length);
|
||||
fileName = TclGetStringFromObj(pathPtr, &length);
|
||||
extension = TclGetExtension(fileName);
|
||||
if (extension == NULL) {
|
||||
Tcl_IncrRefCount(pathPtr);
|
||||
@@ -869,19 +869,23 @@ TclJoinPath(
|
||||
* object which can be normalized more efficiently. Currently we only
|
||||
* use the special case when we have exactly two elements, but we
|
||||
* could expand that in the future.
|
||||
*
|
||||
* Bugfix [a47641a0]. TclNewFSPathObj requires first argument
|
||||
* to be an absolute path. Added a check for that elt is absolute.
|
||||
*/
|
||||
|
||||
if ((i == (elements-2)) && (i == 0)
|
||||
&& (elt->typePtr == &tclFsPathType)
|
||||
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))) {
|
||||
Tcl_Obj *tailObj = objv[i+1];
|
||||
&& (elt->typePtr == &tclFsPathType)
|
||||
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
|
||||
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
|
||||
Tcl_Obj *tailObj = objv[i+1];
|
||||
|
||||
type = TclGetPathType(tailObj, NULL, NULL, NULL);
|
||||
if (type == TCL_PATH_RELATIVE) {
|
||||
const char *str;
|
||||
int len;
|
||||
|
||||
str = Tcl_GetStringFromObj(tailObj, &len);
|
||||
str = TclGetStringFromObj(tailObj, &len);
|
||||
if (len == 0) {
|
||||
/*
|
||||
* This happens if we try to handle the root volume '/'.
|
||||
@@ -943,7 +947,7 @@ TclJoinPath(
|
||||
}
|
||||
}
|
||||
}
|
||||
strElt = Tcl_GetStringFromObj(elt, &strEltLen);
|
||||
strElt = TclGetStringFromObj(elt, &strEltLen);
|
||||
type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
|
||||
if (type != TCL_PATH_RELATIVE) {
|
||||
/*
|
||||
@@ -1030,9 +1034,9 @@ TclJoinPath(
|
||||
noQuickReturn:
|
||||
if (res == NULL) {
|
||||
res = Tcl_NewObj();
|
||||
ptr = Tcl_GetStringFromObj(res, &length);
|
||||
ptr = TclGetStringFromObj(res, &length);
|
||||
} else {
|
||||
ptr = Tcl_GetStringFromObj(res, &length);
|
||||
ptr = TclGetStringFromObj(res, &length);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1077,7 +1081,7 @@ TclJoinPath(
|
||||
|
||||
if (length > 0 && ptr[length -1] != '/') {
|
||||
Tcl_AppendToObj(res, &separator, 1);
|
||||
Tcl_GetStringFromObj(res, &length);
|
||||
TclGetStringFromObj(res, &length);
|
||||
}
|
||||
Tcl_SetObjLength(res, length + (int) strlen(strElt));
|
||||
|
||||
@@ -1372,7 +1376,7 @@ AppendPath(
|
||||
* intrep produce the same results; that is, bugward compatibility. If
|
||||
* we need to fix that bug here, it needs fixing in TclJoinPath() too.
|
||||
*/
|
||||
bytes = Tcl_GetStringFromObj(tail, &numBytes);
|
||||
bytes = TclGetStringFromObj(tail, &numBytes);
|
||||
if (numBytes == 0) {
|
||||
Tcl_AppendToObj(copy, "/", 1);
|
||||
} else {
|
||||
@@ -1431,7 +1435,7 @@ TclFSMakePathRelative(
|
||||
* too little below, leading to wrong answers returned by glob.
|
||||
*/
|
||||
|
||||
tempStr = Tcl_GetStringFromObj(cwdPtr, &cwdLen);
|
||||
tempStr = TclGetStringFromObj(cwdPtr, &cwdLen);
|
||||
|
||||
/*
|
||||
* Should we perhaps use 'Tcl_FSPathSeparator'? But then what about the
|
||||
@@ -1451,7 +1455,7 @@ TclFSMakePathRelative(
|
||||
}
|
||||
break;
|
||||
}
|
||||
tempStr = Tcl_GetStringFromObj(pathPtr, &len);
|
||||
tempStr = TclGetStringFromObj(pathPtr, &len);
|
||||
|
||||
return Tcl_NewStringObj(tempStr + cwdLen, len - cwdLen);
|
||||
}
|
||||
@@ -1715,7 +1719,7 @@ Tcl_FSGetTranslatedStringPath(
|
||||
|
||||
if (transPtr != NULL) {
|
||||
int len;
|
||||
const char *orig = Tcl_GetStringFromObj(transPtr, &len);
|
||||
const char *orig = TclGetStringFromObj(transPtr, &len);
|
||||
char *result = ckalloc(len+1);
|
||||
|
||||
memcpy(result, orig, (size_t) len+1);
|
||||
@@ -1776,7 +1780,7 @@ Tcl_FSGetNormalizedPath(
|
||||
UpdateStringOfFsPath(pathPtr);
|
||||
}
|
||||
|
||||
Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &tailLen);
|
||||
TclGetStringFromObj(fsPathPtr->normPathPtr, &tailLen);
|
||||
if (tailLen) {
|
||||
copy = AppendPath(dir, fsPathPtr->normPathPtr);
|
||||
} else {
|
||||
@@ -1789,7 +1793,7 @@ Tcl_FSGetNormalizedPath(
|
||||
* We now own a reference on both 'dir' and 'copy'
|
||||
*/
|
||||
|
||||
(void) Tcl_GetStringFromObj(dir, &cwdLen);
|
||||
(void) TclGetStringFromObj(dir, &cwdLen);
|
||||
cwdLen += (Tcl_GetString(copy)[cwdLen] == '/');
|
||||
|
||||
/* Normalize the combined string. */
|
||||
@@ -1883,7 +1887,7 @@ Tcl_FSGetNormalizedPath(
|
||||
|
||||
copy = AppendPath(fsPathPtr->cwdPtr, pathPtr);
|
||||
|
||||
(void) Tcl_GetStringFromObj(fsPathPtr->cwdPtr, &cwdLen);
|
||||
(void) TclGetStringFromObj(fsPathPtr->cwdPtr, &cwdLen);
|
||||
cwdLen += (Tcl_GetString(copy)[cwdLen] == '/');
|
||||
|
||||
/*
|
||||
@@ -2333,7 +2337,7 @@ SetFsPathFromAny(
|
||||
* cmdAH.test exercise most of the code).
|
||||
*/
|
||||
|
||||
name = Tcl_GetStringFromObj(pathPtr, &len);
|
||||
name = TclGetStringFromObj(pathPtr, &len);
|
||||
|
||||
/*
|
||||
* Handle tilde substitutions, if needed.
|
||||
@@ -2602,7 +2606,7 @@ UpdateStringOfFsPath(
|
||||
|
||||
copy = AppendPath(fsPathPtr->cwdPtr, fsPathPtr->normPathPtr);
|
||||
|
||||
pathPtr->bytes = Tcl_GetStringFromObj(copy, &cwdLen);
|
||||
pathPtr->bytes = TclGetStringFromObj(copy, &cwdLen);
|
||||
pathPtr->length = cwdLen;
|
||||
copy->bytes = tclEmptyStringRep;
|
||||
copy->length = 0;
|
||||
@@ -2663,7 +2667,7 @@ TclNativePathInFilesystem(
|
||||
|
||||
int len;
|
||||
|
||||
(void) Tcl_GetStringFromObj(pathPtr, &len);
|
||||
(void) TclGetStringFromObj(pathPtr, &len);
|
||||
if (len == 0) {
|
||||
/*
|
||||
* We reject the empty path "".
|
||||
|
||||
+5
-5
@@ -842,7 +842,7 @@ Tcl_PackageObjCmd(
|
||||
} else {
|
||||
pkgPtr = FindPackage(interp, argv2);
|
||||
}
|
||||
argv3 = Tcl_GetStringFromObj(objv[3], &length);
|
||||
argv3 = TclGetStringFromObj(objv[3], &length);
|
||||
|
||||
for (availPtr = pkgPtr->availPtr, prevPtr = NULL; availPtr != NULL;
|
||||
prevPtr = availPtr, availPtr = availPtr->nextPtr) {
|
||||
@@ -883,7 +883,7 @@ Tcl_PackageObjCmd(
|
||||
prevPtr->nextPtr = availPtr;
|
||||
}
|
||||
}
|
||||
argv4 = Tcl_GetStringFromObj(objv[4], &length);
|
||||
argv4 = TclGetStringFromObj(objv[4], &length);
|
||||
DupBlock(availPtr->script, argv4, (unsigned) length + 1);
|
||||
break;
|
||||
}
|
||||
@@ -1034,7 +1034,7 @@ Tcl_PackageObjCmd(
|
||||
if (iPtr->packageUnknown != NULL) {
|
||||
ckfree(iPtr->packageUnknown);
|
||||
}
|
||||
argv2 = Tcl_GetStringFromObj(objv[2], &length);
|
||||
argv2 = TclGetStringFromObj(objv[2], &length);
|
||||
if (argv2[0] == 0) {
|
||||
iPtr->packageUnknown = NULL;
|
||||
} else {
|
||||
@@ -1682,7 +1682,7 @@ AddRequirementsToResult(
|
||||
int i, length;
|
||||
|
||||
for (i = 0; i < reqc; i++) {
|
||||
const char *v = Tcl_GetStringFromObj(reqv[i], &length);
|
||||
const char *v = TclGetStringFromObj(reqv[i], &length);
|
||||
|
||||
if ((length & 0x1) && (v[length/2] == '-')
|
||||
&& (strncmp(v, v+((length+1)/2), length/2) == 0)) {
|
||||
@@ -1895,7 +1895,7 @@ Tcl_PkgInitStubsCheck(
|
||||
{
|
||||
const char *actualVersion = Tcl_PkgPresent(interp, "Tcl", version, 0);
|
||||
|
||||
if (exact && actualVersion) {
|
||||
if ((exact&1) && actualVersion) {
|
||||
const char *p = version;
|
||||
int count = 0;
|
||||
|
||||
|
||||
+10
-47
@@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int isRootEnsemble;
|
||||
Command cmd;
|
||||
ExtraFrameInfo efi;
|
||||
} ApplyExtraData;
|
||||
@@ -344,7 +343,7 @@ Tcl_ProcObjCmd(
|
||||
* The argument list is just "args"; check the body
|
||||
*/
|
||||
|
||||
procBody = Tcl_GetStringFromObj(objv[3], &numBytes);
|
||||
procBody = TclGetStringFromObj(objv[3], &numBytes);
|
||||
if (TclParseAllWhiteSpace(procBody, numBytes) < numBytes) {
|
||||
goto done;
|
||||
}
|
||||
@@ -870,7 +869,7 @@ TclObjGetFrame(
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL", name, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1088,12 +1087,10 @@ ProcWrongNumArgs(
|
||||
if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
|
||||
desiredObjs[0] = Tcl_NewStringObj("lambdaExpr", -1);
|
||||
} else {
|
||||
((Interp *) interp)->ensembleRewrite.numInsertedObjs -= skip - 1;
|
||||
|
||||
#ifdef AVOID_HACKS_FOR_ITCL
|
||||
desiredObjs[0] = framePtr->objv[skip-1];
|
||||
#else
|
||||
desiredObjs[0] = Tcl_NewListObj(skip, framePtr->objv);
|
||||
desiredObjs[0] = Tcl_NewListObj(1, framePtr->objv + skip - 1);
|
||||
#endif /* AVOID_HACKS_FOR_ITCL */
|
||||
}
|
||||
Tcl_IncrRefCount(desiredObjs[0]);
|
||||
@@ -1528,6 +1525,10 @@ InitArgsAndLocals(
|
||||
*/
|
||||
|
||||
incorrectArgs:
|
||||
if ((skip != 1) &&
|
||||
TclInitRewriteEnsemble(interp, skip-1, 0, framePtr->objv)) {
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
memset(varPtr, 0,
|
||||
((framePtr->compiledLocals + localCt)-varPtr) * sizeof(Var));
|
||||
return ProcWrongNumArgs(interp, skip);
|
||||
@@ -2082,7 +2083,7 @@ MakeProcError(
|
||||
* messages and trace information. */
|
||||
{
|
||||
int overflow, limit = 60, nameLen;
|
||||
const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
|
||||
const char *procName = TclGetStringFromObj(procNameObj, &nameLen);
|
||||
|
||||
overflow = (nameLen > limit);
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
@@ -2634,7 +2635,7 @@ TclNRApplyObjCmd(
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Proc *procPtr = NULL;
|
||||
Tcl_Obj *lambdaPtr, *nsObjPtr;
|
||||
int result, isRootEnsemble;
|
||||
int result;
|
||||
Tcl_Namespace *nsPtr;
|
||||
ApplyExtraData *extraPtr;
|
||||
|
||||
@@ -2653,30 +2654,6 @@ TclNRApplyObjCmd(
|
||||
procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
|
||||
}
|
||||
|
||||
#define JOE_EXTENSION 0
|
||||
/*
|
||||
* Note: this code is NOT FUNCTIONAL due to the NR implementation; DO NOT
|
||||
* ENABLE! Leaving here as reminder to (a) TIP the suggestion, and (b) adapt
|
||||
* the code. (MS)
|
||||
*/
|
||||
|
||||
#if JOE_EXTENSION
|
||||
else {
|
||||
/*
|
||||
* Joe English's suggestion to allow cmdNames to function as lambdas.
|
||||
*/
|
||||
|
||||
Tcl_Obj *elemPtr;
|
||||
int numElem;
|
||||
|
||||
if ((lambdaPtr->typePtr == &tclCmdNameType) ||
|
||||
(TclListObjGetElements(interp, lambdaPtr, &numElem,
|
||||
&elemPtr) == TCL_OK && numElem == 1)) {
|
||||
return Tcl_EvalObjv(interp, objc-1, objv+1, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((procPtr == NULL) || (procPtr->iPtr != iPtr)) {
|
||||
result = SetLambdaFromAny(interp, lambdaPtr);
|
||||
if (result != TCL_OK) {
|
||||
@@ -2717,16 +2694,6 @@ TclNRApplyObjCmd(
|
||||
extraPtr->efi.fields[0].clientData = lambdaPtr;
|
||||
extraPtr->cmd.clientData = &extraPtr->efi;
|
||||
|
||||
isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
|
||||
if (isRootEnsemble) {
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = 1;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 0;
|
||||
} else {
|
||||
iPtr->ensembleRewrite.numInsertedObjs -= 1;
|
||||
}
|
||||
extraPtr->isRootEnsemble = isRootEnsemble;
|
||||
|
||||
result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
|
||||
if (result == TCL_OK) {
|
||||
TclNRAddCallback(interp, ApplyNR2, extraPtr, NULL, NULL, NULL);
|
||||
@@ -2743,10 +2710,6 @@ ApplyNR2(
|
||||
{
|
||||
ApplyExtraData *extraPtr = data[0];
|
||||
|
||||
if (extraPtr->isRootEnsemble) {
|
||||
((Interp *) interp)->ensembleRewrite.sourceObjs = NULL;
|
||||
}
|
||||
|
||||
TclStackFree(interp, extraPtr);
|
||||
return result;
|
||||
}
|
||||
@@ -2777,7 +2740,7 @@ MakeLambdaError(
|
||||
* messages and trace information. */
|
||||
{
|
||||
int overflow, limit = 60, nameLen;
|
||||
const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
|
||||
const char *procName = TclGetStringFromObj(procNameObj, &nameLen);
|
||||
|
||||
overflow = (nameLen > limit);
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
|
||||
@@ -396,6 +396,9 @@ static Tcl_WideUInt Nokia770Twiddle(Tcl_WideUInt w);
|
||||
* - TCL_PARSE_SCAN_PREFIXES: ignore the prefixes 0b and 0o that are
|
||||
* not part of the [scan] command's vocabulary. Use only in
|
||||
* combination with TCL_PARSE_INTEGER_ONLY.
|
||||
* - TCL_PARSE_BINARY_ONLY: parse only in the binary format, whether
|
||||
* or not a prefix is present that would lead to binary parsing.
|
||||
* Use only in combination with TCL_PARSE_INTEGER_ONLY.
|
||||
* - TCL_PARSE_OCTAL_ONLY: parse only in the octal format, whether
|
||||
* or not a prefix is present that would lead to octal parsing.
|
||||
* Use only in combination with TCL_PARSE_INTEGER_ONLY.
|
||||
@@ -627,6 +630,9 @@ TclParseNumber(
|
||||
acceptPoint = p;
|
||||
acceptLen = len;
|
||||
if (c == 'x' || c == 'X') {
|
||||
if (flags & (TCL_PARSE_OCTAL_ONLY|TCL_PARSE_BINARY_ONLY)) {
|
||||
goto endgame;
|
||||
}
|
||||
state = ZERO_X;
|
||||
break;
|
||||
}
|
||||
@@ -637,6 +643,9 @@ TclParseNumber(
|
||||
goto zeroo;
|
||||
}
|
||||
if (c == 'b' || c == 'B') {
|
||||
if (flags & TCL_PARSE_OCTAL_ONLY) {
|
||||
goto endgame;
|
||||
}
|
||||
state = ZERO_B;
|
||||
break;
|
||||
}
|
||||
|
||||
+348
-1
@@ -408,6 +408,15 @@ Tcl_GetCharLength(
|
||||
String *stringPtr;
|
||||
int numChars;
|
||||
|
||||
/*
|
||||
* Quick, no-shimmer return for short string reps.
|
||||
*/
|
||||
|
||||
if ((objPtr->bytes) && (objPtr->length < 2)) {
|
||||
/* 0 bytes -> 0 chars; 1 byte -> 1 char */
|
||||
return objPtr->length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimize the case where we're really dealing with a bytearray object
|
||||
* without string representation; we don't need to convert to a string to
|
||||
@@ -1173,6 +1182,8 @@ Tcl_AppendUnicodeToObj(
|
||||
* Side effects:
|
||||
* The string rep of appendObjPtr is appended to the string
|
||||
* representation of objPtr.
|
||||
* IMPORTANT: This routine does not and MUST NOT shimmer appendObjPtr.
|
||||
* Callers are counting on that.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2285,7 +2296,7 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_GetStringFromObj(segment, &segmentNumBytes);
|
||||
TclGetStringFromObj(segment, &segmentNumBytes);
|
||||
if (segmentNumBytes > limit) {
|
||||
if (allocSegment) {
|
||||
Tcl_DecrRefCount(segment);
|
||||
@@ -2598,6 +2609,332 @@ TclGetStringStorage(
|
||||
*sizePtr = stringPtr->allocated;
|
||||
return objPtr->bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclStringCatObjv --
|
||||
*
|
||||
* Performs the [string cat] function.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes to *objPtrPtr the address of Tcl_Obj that is concatenation
|
||||
* of all objc values in objv.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclStringCatObjv(
|
||||
Tcl_Interp *interp,
|
||||
int inPlace,
|
||||
int objc,
|
||||
Tcl_Obj * const objv[],
|
||||
Tcl_Obj **objPtrPtr)
|
||||
{
|
||||
Tcl_Obj *objPtr, *objResultPtr, * const *ov;
|
||||
int oc, length = 0, binary = 1, first = 0;
|
||||
int allowUniChar = 1, requestUniChar = 0;
|
||||
|
||||
/* assert (objc >= 2) */
|
||||
|
||||
/*
|
||||
* Analyze to determine what representation result should be.
|
||||
* GOALS: Avoid shimmering & string rep generation.
|
||||
* Produce pure bytearray when possible.
|
||||
* Error on overflow.
|
||||
*/
|
||||
|
||||
ov = objv, oc = objc;
|
||||
while (oc-- && (binary || allowUniChar)) {
|
||||
objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes) {
|
||||
/* Value has a string rep. */
|
||||
if (objPtr->length) {
|
||||
/*
|
||||
* Non-empty string rep. Not a pure bytearray, so we
|
||||
* won't create a pure bytearray
|
||||
*/
|
||||
binary = 0;
|
||||
if ((objPtr->typePtr) && (objPtr->typePtr != &tclStringType)) {
|
||||
/* Prevent shimmer of non-string types. */
|
||||
allowUniChar = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* assert (objPtr->typePtr != NULL) -- stork! */
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
allowUniChar = 0;
|
||||
} else {
|
||||
binary = 0;
|
||||
if (objPtr->typePtr == &tclStringType) {
|
||||
/* Have a pure Unicode value; ask to preserve it */
|
||||
requestUniChar = 1;
|
||||
} else {
|
||||
/* Have another type; prevent shimmer */
|
||||
allowUniChar = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (binary) {
|
||||
/* Result will be pure byte array. Pre-size it */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
int numBytes;
|
||||
|
||||
Tcl_GetByteArrayFromObj(objPtr, &numBytes);
|
||||
if (length == 0) {
|
||||
first = objc - oc - 1;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
}
|
||||
} else if (allowUniChar && requestUniChar) {
|
||||
/* Result will be pure Tcl_UniChar array. Pre-size it. */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
objPtr = *ov++;
|
||||
|
||||
if ((objPtr->bytes == NULL) || (objPtr->length)) {
|
||||
int numChars;
|
||||
|
||||
Tcl_GetUnicodeFromObj(objPtr, &numChars);
|
||||
if (length == 0) {
|
||||
first = objc - oc - 1;
|
||||
}
|
||||
length += numChars;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Result will be concat of string reps. Pre-size it. */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
int numBytes;
|
||||
|
||||
objPtr = *ov++;
|
||||
|
||||
Tcl_GetStringFromObj(objPtr, &numBytes);
|
||||
if ((length == 0) && numBytes) {
|
||||
first = objc - oc - 1;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
/* Total length of zero means every value has length zero */
|
||||
*objPtrPtr = objv[0];
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
objv += first; objc -= first;
|
||||
|
||||
if (binary) {
|
||||
/* Efficiently produce a pure byte array result */
|
||||
unsigned char *dst;
|
||||
|
||||
if (inPlace && !Tcl_IsShared(*objv)) {
|
||||
int start;
|
||||
|
||||
objResultPtr = *objv++; objc--;
|
||||
Tcl_GetByteArrayFromObj(objResultPtr, &start);
|
||||
dst = Tcl_SetByteArrayLength(objResultPtr, length) + start;
|
||||
} else {
|
||||
objResultPtr = Tcl_NewByteArrayObj(NULL, length);
|
||||
dst = Tcl_SetByteArrayLength(objResultPtr, length);
|
||||
}
|
||||
while (objc--) {
|
||||
Tcl_Obj *objPtr = *objv++;
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
int more;
|
||||
unsigned char *src = Tcl_GetByteArrayFromObj(objPtr, &more);
|
||||
memcpy(dst, src, (size_t) more);
|
||||
dst += more;
|
||||
}
|
||||
}
|
||||
} else if (allowUniChar && requestUniChar) {
|
||||
/* Efficiently produce a pure Tcl_UniChar array result */
|
||||
Tcl_UniChar *dst;
|
||||
|
||||
if (inPlace && !Tcl_IsShared(*objv)) {
|
||||
int start;
|
||||
|
||||
objResultPtr = *objv++; objc--;
|
||||
|
||||
/* Ugly interface! Force resize of the unicode array. */
|
||||
Tcl_GetUnicodeFromObj(objResultPtr, &start);
|
||||
Tcl_InvalidateStringRep(objResultPtr);
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
dst = Tcl_GetUnicode(objResultPtr) + start;
|
||||
} else {
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
/* Ugly interface! No scheme to init array size. */
|
||||
objResultPtr = Tcl_NewUnicodeObj(&ch, 0);
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
dst = Tcl_GetUnicode(objResultPtr);
|
||||
}
|
||||
while (objc--) {
|
||||
Tcl_Obj *objPtr = *objv++;
|
||||
|
||||
if ((objPtr->bytes == NULL) || (objPtr->length)) {
|
||||
int more;
|
||||
Tcl_UniChar *src = Tcl_GetUnicodeFromObj(objPtr, &more);
|
||||
memcpy(dst, src, more * sizeof(Tcl_UniChar));
|
||||
dst += more;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Efficiently concatenate string reps */
|
||||
char *dst;
|
||||
|
||||
if (inPlace && !Tcl_IsShared(*objv)) {
|
||||
int start;
|
||||
|
||||
objResultPtr = *objv++; objc--;
|
||||
|
||||
Tcl_GetStringFromObj(objResultPtr, &start);
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
dst = Tcl_GetString(objResultPtr) + start;
|
||||
if (length > start) {
|
||||
TclFreeIntRep(objResultPtr);
|
||||
}
|
||||
} else {
|
||||
objResultPtr = Tcl_NewObj();
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
dst = Tcl_GetString(objResultPtr);
|
||||
}
|
||||
while (objc--) {
|
||||
Tcl_Obj *objPtr = *objv++;
|
||||
|
||||
if ((objPtr->bytes == NULL) || (objPtr->length)) {
|
||||
int more;
|
||||
char *src = Tcl_GetStringFromObj(objPtr, &more);
|
||||
memcpy(dst, src, (size_t) more);
|
||||
dst += more;
|
||||
}
|
||||
}
|
||||
}
|
||||
*objPtrPtr = objResultPtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclStringFind --
|
||||
*
|
||||
* Implements the [string first] operation.
|
||||
*
|
||||
* Results:
|
||||
* If needle is found as a substring of haystack, the index of the
|
||||
* first instance of such a find is returned. If needle is not present
|
||||
* as a substring of haystack, -1 is returned.
|
||||
*
|
||||
* Side effects:
|
||||
* needle and haystack may have their Tcl_ObjType changed.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclStringFind(
|
||||
Tcl_Obj *needle,
|
||||
Tcl_Obj *haystack,
|
||||
unsigned int start)
|
||||
{
|
||||
int lh, ln = Tcl_GetCharLength(needle);
|
||||
|
||||
if (ln == 0) {
|
||||
/*
|
||||
* We don't find empty substrings. Bizarre!
|
||||
*
|
||||
* TODO: When we one day make this a true substring
|
||||
* finder, change this to "return 0"
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
|
||||
unsigned char *end, *try, *bh;
|
||||
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
|
||||
|
||||
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
|
||||
end = bh + lh;
|
||||
|
||||
try = bh + start;
|
||||
while (try + ln <= end) {
|
||||
try = memchr(try, bn[0], end - try);
|
||||
|
||||
if (try == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (0 == memcmp(try+1, bn+1, ln-1)) {
|
||||
return (try - bh);
|
||||
}
|
||||
try++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
lh = Tcl_GetCharLength(haystack);
|
||||
if (haystack->bytes && (lh == haystack->length)) {
|
||||
/* haystack is all single-byte chars */
|
||||
|
||||
if (needle->bytes && (ln == needle->length)) {
|
||||
/* needle is also all single-byte chars */
|
||||
char *found = strstr(haystack->bytes + start, needle->bytes);
|
||||
|
||||
if (found) {
|
||||
return (found - haystack->bytes);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Cannot find substring with a multi-byte char inside
|
||||
* a string with no multi-byte chars.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Tcl_UniChar *try, *end, *uh;
|
||||
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
|
||||
|
||||
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
|
||||
end = uh + lh;
|
||||
|
||||
try = uh + start;
|
||||
while (try + ln <= end) {
|
||||
if ((*try == *un)
|
||||
&& (0 == memcmp(try+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) {
|
||||
return (try - uh);
|
||||
}
|
||||
try++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
@@ -2948,6 +3285,16 @@ UpdateStringOfString(
|
||||
{
|
||||
String *stringPtr = GET_STRING(objPtr);
|
||||
|
||||
/*
|
||||
* This routine is only called when we need to generate the
|
||||
* string rep objPtr->bytes because it does not exist -- it is NULL.
|
||||
* In that circumstance, any lingering claim about the size of
|
||||
* memory pointed to by that NULL pointer is clearly bogus, and
|
||||
* needs a reset.
|
||||
*/
|
||||
|
||||
stringPtr->allocated = 0;
|
||||
|
||||
if (stringPtr->numChars == 0) {
|
||||
TclInitStringRep(objPtr, tclEmptyStringRep, 0);
|
||||
} else {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
* tcl.h, but do not do that unless you are sure what you're doing!
|
||||
*/
|
||||
|
||||
typedef struct String {
|
||||
typedef struct {
|
||||
int numChars; /* The number of chars in the string. -1 means
|
||||
* this value has not been calculated. >= 0
|
||||
* means that there is a valid Unicode rep, or
|
||||
|
||||
+9
-11
@@ -24,13 +24,10 @@ const TclIntStubs *tclIntStubsPtr = NULL;
|
||||
const TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
|
||||
|
||||
/*
|
||||
* Use our own isDigit to avoid linking to libc on windows
|
||||
* Use our own ISDIGIT to avoid linking to libc on windows
|
||||
*/
|
||||
|
||||
static int isDigit(const int c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
#define ISDIGIT(c) (((unsigned)((c)-'0')) <= 9)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -54,7 +51,8 @@ MODULE_SCOPE const char *
|
||||
Tcl_InitStubs(
|
||||
Tcl_Interp *interp,
|
||||
const char *version,
|
||||
int exact)
|
||||
int exact,
|
||||
int magic)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
const char *actualVersion = NULL;
|
||||
@@ -67,8 +65,8 @@ Tcl_InitStubs(
|
||||
* times. [Bug 615304]
|
||||
*/
|
||||
|
||||
if (!stubsPtr || (stubsPtr->magic != TCL_STUB_MAGIC)) {
|
||||
iPtr->result = "interpreter uses an incompatible stubs mechanism";
|
||||
if (!stubsPtr || (stubsPtr->magic != (((exact&0xff00) >= 0x900) ? magic : TCL_STUB_MAGIC))) {
|
||||
iPtr->result = (char *)"interpreter uses an incompatible stubs mechanism";
|
||||
iPtr->freeProc = TCL_STATIC;
|
||||
return NULL;
|
||||
}
|
||||
@@ -77,12 +75,12 @@ Tcl_InitStubs(
|
||||
if (actualVersion == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (exact) {
|
||||
if (exact&1) {
|
||||
const char *p = version;
|
||||
int count = 0;
|
||||
|
||||
while (*p) {
|
||||
count += !isDigit(*p++);
|
||||
count += !ISDIGIT(*p++);
|
||||
}
|
||||
if (count == 1) {
|
||||
const char *q = actualVersion;
|
||||
@@ -91,7 +89,7 @@ Tcl_InitStubs(
|
||||
while (*p && (*p == *q)) {
|
||||
p++; q++;
|
||||
}
|
||||
if (*p || isDigit(*q)) {
|
||||
if (*p || ISDIGIT(*q)) {
|
||||
/* Construct error message */
|
||||
stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
|
||||
return NULL;
|
||||
|
||||
+97
-40
@@ -42,16 +42,8 @@
|
||||
* Declare external functions used in Windows tests.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
|
||||
* Tcltest_Init declaration is in the source file itself, which is only
|
||||
* accessed when we are building a library.
|
||||
*/
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#define TCL_STORAGE_CLASS DLLEXPORT
|
||||
EXTERN int Tcltest_Init(Tcl_Interp *interp);
|
||||
EXTERN int Tcltest_SafeInit(Tcl_Interp *interp);
|
||||
DLLEXPORT int Tcltest_Init(Tcl_Interp *interp);
|
||||
DLLEXPORT int Tcltest_SafeInit(Tcl_Interp *interp);
|
||||
|
||||
/*
|
||||
* Dynamic string shared by TestdcallCmd and DelCallbackProc; used to collect
|
||||
@@ -416,8 +408,7 @@ static int TestHashSystemHashCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
|
||||
static int NREUnwind_callback(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static Tcl_NRPostProc NREUnwind_callback;
|
||||
static int TestNREUnwind(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -1294,7 +1285,7 @@ TestcmdtraceCmd(
|
||||
cmdTrace = Tcl_CreateObjTrace(interp, 50000,
|
||||
TCL_ALLOW_INLINE_COMPILATION, ObjTraceProc,
|
||||
(ClientData) &deleteCalled, ObjTraceDeleteProc);
|
||||
result = Tcl_Eval(interp, argv[2]);
|
||||
result = Tcl_EvalEx(interp, argv[2], -1, 0);
|
||||
Tcl_DeleteTrace(interp, cmdTrace);
|
||||
if (!deleteCalled) {
|
||||
Tcl_SetResult(interp, "Delete wasn't called", TCL_STATIC);
|
||||
@@ -1308,7 +1299,7 @@ TestcmdtraceCmd(
|
||||
Tcl_DStringInit(&buffer);
|
||||
t1 = Tcl_CreateTrace(interp, 1, CmdTraceProc, &buffer);
|
||||
t2 = Tcl_CreateTrace(interp, 50000, CmdTraceProc, &buffer);
|
||||
result = Tcl_Eval(interp, argv[2]);
|
||||
result = Tcl_EvalEx(interp, argv[2], -1, 0);
|
||||
if (result == TCL_OK) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
|
||||
@@ -1637,7 +1628,7 @@ DelDeleteProc(
|
||||
{
|
||||
DelCmd *dPtr = clientData;
|
||||
|
||||
Tcl_Eval(dPtr->interp, dPtr->deleteCmd);
|
||||
Tcl_EvalEx(dPtr->interp, dPtr->deleteCmd, -1, 0);
|
||||
Tcl_ResetResult(dPtr->interp);
|
||||
ckfree(dPtr->deleteCmd);
|
||||
ckfree(dPtr);
|
||||
@@ -3972,7 +3963,7 @@ TestregexpObjCmd(
|
||||
varName = Tcl_GetString(objv[2]);
|
||||
TclRegExpRangeUniChar(regExpr, -1, &start, &end);
|
||||
sprintf(resinfo, "%d %d", start, end-1);
|
||||
value = Tcl_SetVar(interp, varName, resinfo, 0);
|
||||
value = Tcl_SetVar2(interp, varName, NULL, resinfo, 0);
|
||||
if (value == NULL) {
|
||||
Tcl_AppendResult(interp, "couldn't set variable \"",
|
||||
varName, "\"", NULL);
|
||||
@@ -3986,7 +3977,7 @@ TestregexpObjCmd(
|
||||
Tcl_RegExpGetInfo(regExpr, &info);
|
||||
varName = Tcl_GetString(objv[2]);
|
||||
sprintf(resinfo, "%ld", info.extendStart);
|
||||
value = Tcl_SetVar(interp, varName, resinfo, 0);
|
||||
value = Tcl_SetVar2(interp, varName, NULL, resinfo, 0);
|
||||
if (value == NULL) {
|
||||
Tcl_AppendResult(interp, "couldn't set variable \"",
|
||||
varName, "\"", NULL);
|
||||
@@ -4329,7 +4320,7 @@ StaticInitProc(
|
||||
Tcl_Interp *interp) /* Interpreter in which package is supposedly
|
||||
* being loaded. */
|
||||
{
|
||||
Tcl_SetVar(interp, "x", "loaded", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "x", NULL, "loaded", TCL_GLOBAL_ONLY);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -4413,7 +4404,7 @@ TestupvarCmd(
|
||||
} else if (strcmp(argv[4], "namespace") == 0) {
|
||||
flags = TCL_NAMESPACE_ONLY;
|
||||
}
|
||||
return Tcl_UpVar(interp, argv[1], argv[2], argv[3], flags);
|
||||
return Tcl_UpVar2(interp, argv[1], argv[2], NULL, argv[3], flags);
|
||||
} else {
|
||||
if (strcmp(argv[5], "global") == 0) {
|
||||
flags = TCL_GLOBAL_ONLY;
|
||||
@@ -4907,10 +4898,10 @@ GetTimesObjCmd(
|
||||
timePer/100000);
|
||||
|
||||
/* Tcl_SetVar 100000 times */
|
||||
fprintf(stderr, "Tcl_SetVar of \"12345\" 100000 times\n");
|
||||
fprintf(stderr, "Tcl_SetVar2 of \"12345\" 100000 times\n");
|
||||
Tcl_GetTime(&start);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
s = Tcl_SetVar(interp, "a", "12345", TCL_LEAVE_ERR_MSG);
|
||||
s = Tcl_SetVar2(interp, "a", NULL, "12345", TCL_LEAVE_ERR_MSG);
|
||||
if (s == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -4924,7 +4915,7 @@ GetTimesObjCmd(
|
||||
fprintf(stderr, "Tcl_GetVar of a==\"12345\" 100000 times\n");
|
||||
Tcl_GetTime(&start);
|
||||
for (i = 0; i < 100000; i++) {
|
||||
s = Tcl_GetVar(interp, "a", TCL_LEAVE_ERR_MSG);
|
||||
s = Tcl_GetVar2(interp, "a", NULL, TCL_LEAVE_ERR_MSG);
|
||||
if (s == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -5194,7 +5185,7 @@ TestsaveresultCmd(
|
||||
if (((enum options) index) == RESULT_OBJECT) {
|
||||
result = Tcl_EvalObjEx(interp, objv[2], 0);
|
||||
} else {
|
||||
result = Tcl_Eval(interp, Tcl_GetString(objv[2]));
|
||||
result = Tcl_EvalEx(interp, Tcl_GetString(objv[2]), -1, 0);
|
||||
}
|
||||
|
||||
if (discard) {
|
||||
@@ -6297,7 +6288,7 @@ TestReport(
|
||||
savedResult = Tcl_GetObjResult(interp);
|
||||
Tcl_IncrRefCount(savedResult);
|
||||
Tcl_SetObjResult(interp, Tcl_NewObj());
|
||||
Tcl_Eval(interp, Tcl_DStringValue(&ds));
|
||||
Tcl_EvalEx(interp, Tcl_DStringValue(&ds), -1, 0);
|
||||
Tcl_DStringFree(&ds);
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, savedResult);
|
||||
@@ -7335,23 +7326,82 @@ InterpCmdResolver(
|
||||
CallFrame *varFramePtr = iPtr->varFramePtr;
|
||||
Proc *procPtr = (varFramePtr->isProcCallFrame & FRAME_IS_PROC) ?
|
||||
varFramePtr->procPtr : NULL;
|
||||
Namespace *ns2NsPtr = (Namespace *)
|
||||
Tcl_FindNamespace(interp, "::ns2", NULL, 0);
|
||||
Namespace *callerNsPtr = varFramePtr->nsPtr;
|
||||
Tcl_Command resolvedCmdPtr = NULL;
|
||||
|
||||
if (procPtr && (procPtr->cmdPtr->nsPtr == iPtr->globalNsPtr
|
||||
|| (ns2NsPtr && procPtr->cmdPtr->nsPtr == ns2NsPtr))) {
|
||||
const char *callingCmdName =
|
||||
/*
|
||||
* Just do something special on a cmd literal "z" in two cases:
|
||||
* A) when the caller is a proc "x", and the proc is either in "::" or in "::ns2".
|
||||
* B) the caller's namespace is "ctx1" or "ctx2"
|
||||
*/
|
||||
if ( (name[0] == 'z') && (name[1] == '\0') ) {
|
||||
Namespace *ns2NsPtr = (Namespace *) Tcl_FindNamespace(interp, "::ns2", NULL, 0);
|
||||
|
||||
if (procPtr != NULL
|
||||
&& ((procPtr->cmdPtr->nsPtr == iPtr->globalNsPtr)
|
||||
|| (ns2NsPtr != NULL && procPtr->cmdPtr->nsPtr == ns2NsPtr)
|
||||
)
|
||||
) {
|
||||
/*
|
||||
* Case A)
|
||||
*
|
||||
* - The context, in which this resolver becomes active, is
|
||||
* determined by the name of the caller proc, which has to be
|
||||
* named "x".
|
||||
*
|
||||
* - To determine the name of the caller proc, the proc is taken
|
||||
* from the topmost stack frame.
|
||||
*
|
||||
* - Note that the context is NOT provided during byte-code
|
||||
* compilation (e.g. in TclProcCompileProc)
|
||||
*
|
||||
* When these conditions hold, this function resolves the
|
||||
* passed-in cmd literal into a cmd "y", which is taken from the
|
||||
* the global namespace (for simplicity).
|
||||
*/
|
||||
|
||||
const char *callingCmdName =
|
||||
Tcl_GetCommandName(interp, (Tcl_Command) procPtr->cmdPtr);
|
||||
|
||||
if ((callingCmdName[0] == 'x') && (callingCmdName[1] == '\0')
|
||||
&& (name[0] == 'z') && (name[1] == '\0')) {
|
||||
Tcl_Command sourceCmdPtr = Tcl_FindCommand(interp, "y", NULL,
|
||||
TCL_GLOBAL_ONLY);
|
||||
|
||||
if (sourceCmdPtr != NULL) {
|
||||
*rPtr = sourceCmdPtr;
|
||||
return TCL_OK;
|
||||
if ( callingCmdName[0] == 'x' && callingCmdName[1] == '\0' ) {
|
||||
resolvedCmdPtr = Tcl_FindCommand(interp, "y", NULL, TCL_GLOBAL_ONLY);
|
||||
}
|
||||
} else if (callerNsPtr != NULL) {
|
||||
/*
|
||||
* Case B)
|
||||
*
|
||||
* - The context, in which this resolver becomes active, is
|
||||
* determined by the name of the parent namespace, which has
|
||||
* to be named "ctx1" or "ctx2".
|
||||
*
|
||||
* - To determine the name of the parent namesace, it is taken
|
||||
* from the 2nd highest stack frame.
|
||||
*
|
||||
* - Note that the context can be provided during byte-code
|
||||
* compilation (e.g. in TclProcCompileProc)
|
||||
*
|
||||
* When these conditions hold, this function resolves the
|
||||
* passed-in cmd literal into a cmd "y" or "Y" depending on the
|
||||
* context. The resolved procs are taken from the the global
|
||||
* namespace (for simplicity).
|
||||
*/
|
||||
|
||||
CallFrame *parentFramePtr = varFramePtr->callerPtr;
|
||||
char *context = parentFramePtr != NULL ? parentFramePtr->nsPtr->name : "(NULL)";
|
||||
|
||||
if (strcmp(context, "ctx1") == 0 && (name[0] == 'z') && (name[1] == '\0')) {
|
||||
resolvedCmdPtr = Tcl_FindCommand(interp, "y", NULL, TCL_GLOBAL_ONLY);
|
||||
/* fprintf(stderr, "... y ==> %p\n", resolvedCmdPtr);*/
|
||||
|
||||
} else if (strcmp(context, "ctx2") == 0 && (name[0] == 'z') && (name[1] == '\0')) {
|
||||
resolvedCmdPtr = Tcl_FindCommand(interp, "Y", NULL, TCL_GLOBAL_ONLY);
|
||||
/*fprintf(stderr, "... Y ==> %p\n", resolvedCmdPtr);*/
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedCmdPtr != NULL) {
|
||||
*rPtr = resolvedCmdPtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
return TCL_CONTINUE;
|
||||
@@ -7485,9 +7535,16 @@ TestInterpResolverCmd(
|
||||
int idx;
|
||||
#define RESOLVER_KEY "testInterpResolver"
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "up|down");
|
||||
return TCL_ERROR;
|
||||
if ((objc < 2) || (objc > 3)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "up|down ?interp?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 3) {
|
||||
interp = Tcl_GetSlave(interp, Tcl_GetString(objv[2]));
|
||||
if (interp == NULL) {
|
||||
Tcl_AppendResult(interp, "provided interpreter not found", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], table, "operation", TCL_EXACT,
|
||||
&idx) != TCL_OK) {
|
||||
|
||||
+4
-24
@@ -19,6 +19,7 @@
|
||||
#endif
|
||||
#include "tclInt.h"
|
||||
#include "tommath.h"
|
||||
#include "tclStringRep.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -46,13 +47,6 @@ static int TestobjCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
static int TeststringobjCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
|
||||
typedef struct TestString {
|
||||
int numChars;
|
||||
int allocated;
|
||||
int maxChars;
|
||||
Tcl_UniChar unicode[2];
|
||||
} TestString;
|
||||
|
||||
#define VARPTR_KEY "TCLOBJTEST_VARPTR"
|
||||
#define NUMBER_OF_OBJECT_VARS 20
|
||||
@@ -583,23 +577,9 @@ TestindexobjCmd(
|
||||
}
|
||||
argv[objc-4] = NULL;
|
||||
|
||||
/*
|
||||
* Tcl_GetIndexFromObj assumes that the table is statically-allocated so
|
||||
* that its address is different for each index object. If we accidently
|
||||
* allocate a table at the same address as that cached in the index
|
||||
* object, clear out the object's cached state.
|
||||
*/
|
||||
|
||||
if (objv[3]->typePtr != NULL
|
||||
&& !strcmp("index", objv[3]->typePtr->name)) {
|
||||
indexRep = objv[3]->internalRep.twoPtrValue.ptr1;
|
||||
if (indexRep->tablePtr == (void *) argv) {
|
||||
TclFreeIntRep(objv[3]);
|
||||
}
|
||||
}
|
||||
|
||||
result = Tcl_GetIndexFromObj((setError? interp : NULL), objv[3],
|
||||
argv, "token", (allowAbbrev? 0 : TCL_EXACT), &index);
|
||||
argv, "token", INDEX_TEMP_TABLE|(allowAbbrev? 0 : TCL_EXACT),
|
||||
&index);
|
||||
ckfree(argv);
|
||||
if (result == TCL_OK) {
|
||||
Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
|
||||
@@ -1141,7 +1121,7 @@ TeststringobjCmd(
|
||||
int varIndex, option, i, length;
|
||||
#define MAX_STRINGS 11
|
||||
const char *index, *string, *strings[MAX_STRINGS+1];
|
||||
TestString *strPtr;
|
||||
String *strPtr;
|
||||
Tcl_Obj **varPtr;
|
||||
static const char *const options[] = {
|
||||
"append", "appendstrings", "get", "get2", "length", "length2",
|
||||
|
||||
@@ -1106,9 +1106,9 @@ TclFinalizeThreadAlloc(void)
|
||||
*
|
||||
* TclFinalizeThreadAllocThread --
|
||||
*
|
||||
* This procedure is used to destroy single thread private resources used
|
||||
* in this file.
|
||||
* Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
|
||||
* This procedure is used to destroy single thread private resources
|
||||
* defined in this file. Called either during Tcl_FinalizeThread() or
|
||||
* Tcl_Finalize().
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
||||
@@ -657,7 +657,7 @@ ThreadErrorProc(
|
||||
|
||||
sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
|
||||
|
||||
errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
|
||||
errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
|
||||
if (errorProcString == NULL) {
|
||||
errChannel = Tcl_GetStdChannel(TCL_STDERR);
|
||||
Tcl_WriteChars(errChannel, "Error from thread ", -1);
|
||||
@@ -1032,8 +1032,8 @@ ThreadEventProc(
|
||||
code = Tcl_EvalEx(interp, threadEventPtr->script,-1,TCL_EVAL_GLOBAL);
|
||||
Tcl_DeleteThreadExitHandler(ThreadFreeProc, threadEventPtr->script);
|
||||
if (code != TCL_OK) {
|
||||
errorCode = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
|
||||
errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
|
||||
errorCode = Tcl_GetVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY);
|
||||
errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
|
||||
} else {
|
||||
errorCode = errorInfo = NULL;
|
||||
}
|
||||
|
||||
+3
-3
@@ -91,7 +91,7 @@ typedef struct IdleHandler {
|
||||
* The structure defined below is used in this file only.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
TimerHandler *firstTimerHandlerPtr; /* First event in queue. */
|
||||
int lastTimerId; /* Timer identifier of most recently created
|
||||
* timer. */
|
||||
@@ -900,10 +900,10 @@ Tcl_AfterObjCmd(
|
||||
} else {
|
||||
commandPtr = Tcl_ConcatObj(objc-2, objv+2);;
|
||||
}
|
||||
command = Tcl_GetStringFromObj(commandPtr, &length);
|
||||
command = TclGetStringFromObj(commandPtr, &length);
|
||||
for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
|
||||
afterPtr = afterPtr->nextPtr) {
|
||||
tempCommand = Tcl_GetStringFromObj(afterPtr->commandPtr,
|
||||
tempCommand = TclGetStringFromObj(afterPtr->commandPtr,
|
||||
&tempLength);
|
||||
if ((length == tempLength)
|
||||
&& !memcmp(command, tempCommand, (unsigned) length)) {
|
||||
|
||||
+5
-5
@@ -143,7 +143,7 @@ static int TraceVarEx(Tcl_Interp *interp, const char *part1,
|
||||
* trace procs
|
||||
*/
|
||||
|
||||
typedef struct StringTraceData {
|
||||
typedef struct {
|
||||
ClientData clientData; /* Client data from Tcl_CreateTrace */
|
||||
Tcl_CmdTraceProc *proc; /* Trace function from Tcl_CreateTrace */
|
||||
} StringTraceData;
|
||||
@@ -278,7 +278,7 @@ Tcl_TraceObjCmd(
|
||||
|
||||
opsList = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(opsList);
|
||||
flagOps = Tcl_GetStringFromObj(objv[3], &numFlags);
|
||||
flagOps = TclGetStringFromObj(objv[3], &numFlags);
|
||||
if (numFlags == 0) {
|
||||
Tcl_DecrRefCount(opsList);
|
||||
goto badVarOps;
|
||||
@@ -462,7 +462,7 @@ TraceExecutionObjCmd(
|
||||
break;
|
||||
}
|
||||
}
|
||||
command = Tcl_GetStringFromObj(objv[5], &commandLength);
|
||||
command = TclGetStringFromObj(objv[5], &commandLength);
|
||||
length = (size_t) commandLength;
|
||||
if ((enum traceOptions) optionIndex == TRACE_ADD) {
|
||||
TraceCommandInfo *tcmdPtr = ckalloc(
|
||||
@@ -701,7 +701,7 @@ TraceCommandObjCmd(
|
||||
}
|
||||
}
|
||||
|
||||
command = Tcl_GetStringFromObj(objv[5], &commandLength);
|
||||
command = TclGetStringFromObj(objv[5], &commandLength);
|
||||
length = (size_t) commandLength;
|
||||
if ((enum traceOptions) optionIndex == TRACE_ADD) {
|
||||
TraceCommandInfo *tcmdPtr = ckalloc(
|
||||
@@ -904,7 +904,7 @@ TraceVariableObjCmd(
|
||||
break;
|
||||
}
|
||||
}
|
||||
command = Tcl_GetStringFromObj(objv[5], &commandLength);
|
||||
command = TclGetStringFromObj(objv[5], &commandLength);
|
||||
length = (size_t) commandLength;
|
||||
if ((enum traceOptions) optionIndex == TRACE_ADD) {
|
||||
CombinedTraceVarInfo *ctvarPtr = ckalloc(
|
||||
|
||||
+934
-883
File diff suppressed because it is too large
Load Diff
+23
-43
@@ -73,16 +73,7 @@ static const unsigned char totalBytes[256] = {
|
||||
#else
|
||||
1,1,1,1,1,1,1,1,
|
||||
#endif
|
||||
#if TCL_UTF_MAX > 4
|
||||
5,5,5,5,
|
||||
#else
|
||||
1,1,1,1,
|
||||
#endif
|
||||
#if TCL_UTF_MAX > 5
|
||||
6,6,6,6
|
||||
#else
|
||||
1,1,1,1
|
||||
#endif
|
||||
1,1,1,1,1,1,1,1
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -105,14 +96,14 @@ int
|
||||
TclUtfCount(
|
||||
int ch) /* The Tcl_UniChar whose size is returned. */
|
||||
{
|
||||
if ((ch > 0) && (ch < UNICODE_SELF)) {
|
||||
if ((unsigned)(ch - 1) < (UNICODE_SELF - 1)) {
|
||||
return 1;
|
||||
}
|
||||
if (ch <= 0x7FF) {
|
||||
return 2;
|
||||
}
|
||||
#if TCL_UTF_MAX > 3
|
||||
if ((ch > 0xFFFF) && (ch <= 0x10FFFF)) {
|
||||
if (((unsigned)(ch - 0x10000) <= 0xfffff)) {
|
||||
return 4;
|
||||
}
|
||||
#endif
|
||||
@@ -146,7 +137,7 @@ Tcl_UniCharToUtf(
|
||||
* large enough to hold the UTF-8 character
|
||||
* (at most TCL_UTF_MAX bytes). */
|
||||
{
|
||||
if ((ch > 0) && (ch < UNICODE_SELF)) {
|
||||
if ((unsigned)(ch - 1) < (UNICODE_SELF - 1)) {
|
||||
buf[0] = (char) ch;
|
||||
return 1;
|
||||
}
|
||||
@@ -174,11 +165,7 @@ Tcl_UniCharToUtf(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
three:
|
||||
buf[2] = (char) ((ch | 0x80) & 0xBF);
|
||||
buf[1] = (char) (((ch >> 6) | 0x80) & 0xBF);
|
||||
buf[0] = (char) ((ch >> 12) | 0xE0);
|
||||
return 3;
|
||||
goto three;
|
||||
}
|
||||
|
||||
#if TCL_UTF_MAX > 3
|
||||
@@ -193,7 +180,11 @@ Tcl_UniCharToUtf(
|
||||
}
|
||||
|
||||
ch = 0xFFFD;
|
||||
goto three;
|
||||
three:
|
||||
buf[2] = (char) ((ch | 0x80) & 0xBF);
|
||||
buf[1] = (char) (((ch >> 6) | 0x80) & 0xBF);
|
||||
buf[0] = (char) ((ch >> 12) | 0xE0);
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -308,9 +299,6 @@ Tcl_UtfToUniChar(
|
||||
* A two-byte-character lead-byte not followed by trail-byte
|
||||
* represents itself.
|
||||
*/
|
||||
|
||||
*chPtr = (Tcl_UniChar) byte;
|
||||
return 1;
|
||||
} else if (byte < 0xF0) {
|
||||
if (((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80)) {
|
||||
/*
|
||||
@@ -326,31 +314,23 @@ Tcl_UtfToUniChar(
|
||||
* A three-byte-character lead-byte not followed by two trail-bytes
|
||||
* represents itself.
|
||||
*/
|
||||
|
||||
*chPtr = (Tcl_UniChar) byte;
|
||||
return 1;
|
||||
}
|
||||
#if TCL_UTF_MAX > 3
|
||||
{
|
||||
int ch, total, trail;
|
||||
else if (byte < 0xF8) {
|
||||
if (((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80) && ((src[3] & 0xC0) == 0x80)) {
|
||||
/*
|
||||
* Four-byte-character lead byte followed by three trail bytes.
|
||||
*/
|
||||
|
||||
total = totalBytes[byte];
|
||||
trail = total - 1;
|
||||
if (trail > 0) {
|
||||
ch = byte & (0x3F >> trail);
|
||||
do {
|
||||
src++;
|
||||
if ((*src & 0xC0) != 0x80) {
|
||||
*chPtr = byte;
|
||||
return 1;
|
||||
}
|
||||
ch <<= 6;
|
||||
ch |= (*src & 0x3F);
|
||||
trail--;
|
||||
} while (trail > 0);
|
||||
*chPtr = ch;
|
||||
return total;
|
||||
*chPtr = (Tcl_UniChar) (((byte & 0x0E) << 18) | ((src[1] & 0x3F) << 12)
|
||||
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F));
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* A three-byte-character lead-byte not followed by two trail-bytes
|
||||
* represents itself.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+27
-3
@@ -1968,7 +1968,7 @@ Tcl_ConcatObj(
|
||||
if (TclListObjIsCanonical(objPtr)) {
|
||||
continue;
|
||||
}
|
||||
Tcl_GetStringFromObj(objPtr, &length);
|
||||
TclGetStringFromObj(objPtr, &length);
|
||||
if (length > 0) {
|
||||
break;
|
||||
}
|
||||
@@ -2634,7 +2634,19 @@ Tcl_DStringAppend(
|
||||
memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
|
||||
dsPtr->string = newString;
|
||||
} else {
|
||||
int offset = -1;
|
||||
|
||||
/* See [16896d49fd] */
|
||||
if (bytes >= dsPtr->string
|
||||
&& bytes <= dsPtr->string + dsPtr->length) {
|
||||
offset = bytes - dsPtr->string;
|
||||
}
|
||||
|
||||
dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
|
||||
|
||||
if (offset >= 0) {
|
||||
bytes = dsPtr->string + offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2665,7 +2677,7 @@ TclDStringAppendObj(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
int length;
|
||||
char *bytes = Tcl_GetStringFromObj(objPtr, &length);
|
||||
char *bytes = TclGetStringFromObj(objPtr, &length);
|
||||
|
||||
return Tcl_DStringAppend(dsPtr, bytes, length);
|
||||
}
|
||||
@@ -2725,7 +2737,19 @@ Tcl_DStringAppendElement(
|
||||
memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
|
||||
dsPtr->string = newString;
|
||||
} else {
|
||||
int offset = -1;
|
||||
|
||||
/* See [16896d49fd] */
|
||||
if (element >= dsPtr->string
|
||||
&& element <= dsPtr->string + dsPtr->length) {
|
||||
offset = element - dsPtr->string;
|
||||
}
|
||||
|
||||
dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
|
||||
|
||||
if (offset >= 0) {
|
||||
element = dsPtr->string + offset;
|
||||
}
|
||||
}
|
||||
dst = dsPtr->string + dsPtr->length;
|
||||
}
|
||||
@@ -3976,7 +4000,7 @@ TclSetProcessGlobalValue(
|
||||
} else {
|
||||
Tcl_CreateExitHandler(FreeProcessGlobalValue, pgvPtr);
|
||||
}
|
||||
bytes = Tcl_GetStringFromObj(newValue, &pgvPtr->numBytes);
|
||||
bytes = TclGetStringFromObj(newValue, &pgvPtr->numBytes);
|
||||
pgvPtr->value = ckalloc(pgvPtr->numBytes + 1);
|
||||
memcpy(pgvPtr->value, bytes, (unsigned) pgvPtr->numBytes + 1);
|
||||
if (pgvPtr->encoding) {
|
||||
|
||||
+147
-369
@@ -149,6 +149,7 @@ static const char *isArrayElement =
|
||||
*/
|
||||
|
||||
typedef struct ArraySearch {
|
||||
Tcl_Obj *name; /* Name of this search */
|
||||
int id; /* Integer id used to distinguish among
|
||||
* multiple concurrent searches for the same
|
||||
* array. */
|
||||
@@ -188,8 +189,7 @@ static ArraySearch * ParseSearchId(Tcl_Interp *interp, const Var *varPtr,
|
||||
static void UnsetVarStruct(Var *varPtr, Var *arrayPtr,
|
||||
Interp *iPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, int flags, int index);
|
||||
static int SetArraySearchObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static Var * VerifyArray(Tcl_Interp *interp, Tcl_Obj *varNameObj);
|
||||
|
||||
/*
|
||||
* Functions defined in this file that may be exported in the future for use
|
||||
@@ -214,10 +214,6 @@ static Tcl_DupInternalRepProc DupParsedVarName;
|
||||
* or NULL if it is this same obj
|
||||
* twoPtrValue.ptr2: index into locals table
|
||||
*
|
||||
* nsVarName - INTERNALREP DEFINITION:
|
||||
* twoPtrValue.ptr1: pointer to the namespace containing the reference
|
||||
* twoPtrValue.ptr2: pointer to the corresponding Var
|
||||
*
|
||||
* parsedVarName - INTERNALREP DEFINITION:
|
||||
* twoPtrValue.ptr1: pointer to the array name Tcl_Obj, or NULL if it is a
|
||||
* scalar variable
|
||||
@@ -235,22 +231,6 @@ static const Tcl_ObjType tclParsedVarNameType = {
|
||||
FreeParsedVarName, DupParsedVarName, NULL, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of Tcl_Objs used to speed up array searches.
|
||||
*
|
||||
* INTERNALREP DEFINITION:
|
||||
* twoPtrValue.ptr1: searchIdNumber (cast to pointer)
|
||||
* twoPtrValue.ptr2: variableNameStartInString (cast to pointer)
|
||||
*
|
||||
* Note that the value stored in ptr2 is the offset into the string of the
|
||||
* start of the variable name and not the address of the variable name itself,
|
||||
* as this can be safely copied.
|
||||
*/
|
||||
|
||||
const Tcl_ObjType tclArraySearchType = {
|
||||
"array search",
|
||||
NULL, NULL, NULL, SetArraySearchObj
|
||||
};
|
||||
|
||||
Var *
|
||||
TclVarHashCreateVar(
|
||||
@@ -521,16 +501,13 @@ TclObjLookupVarEx(
|
||||
* is set to NULL. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
CallFrame *varFramePtr = iPtr->varFramePtr;
|
||||
register Var *varPtr; /* Points to the variable's in-frame Var
|
||||
* structure. */
|
||||
const char *part1;
|
||||
int index, len1, len2;
|
||||
int parsed = 0;
|
||||
Tcl_Obj *objPtr;
|
||||
const Tcl_ObjType *typePtr = part1Ptr->typePtr;
|
||||
const char *errMsg = NULL;
|
||||
CallFrame *varFramePtr = iPtr->varFramePtr;
|
||||
const char *part2 = part2Ptr? TclGetString(part2Ptr):NULL;
|
||||
int index, parsed = 0;
|
||||
const Tcl_ObjType *typePtr = part1Ptr->typePtr;
|
||||
|
||||
*arrayPtrPtr = NULL;
|
||||
|
||||
if (typePtr == &localVarNameType) {
|
||||
@@ -546,7 +523,7 @@ TclObjLookupVarEx(
|
||||
*/
|
||||
|
||||
Tcl_Obj *namePtr = part1Ptr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_Obj *checkNamePtr = localName(iPtr->varFramePtr, localIndex);
|
||||
Tcl_Obj *checkNamePtr = localName(varFramePtr, localIndex);
|
||||
|
||||
if ((!namePtr && (checkNamePtr == part1Ptr)) ||
|
||||
(namePtr && (checkNamePtr == namePtr))) {
|
||||
@@ -577,11 +554,7 @@ TclObjLookupVarEx(
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if ((part2Ptr = part1Ptr->internalRep.twoPtrValue.ptr2)) {
|
||||
if (createPart2) {
|
||||
Tcl_IncrRefCount(part2Ptr);
|
||||
}
|
||||
}
|
||||
part2Ptr = part1Ptr->internalRep.twoPtrValue.ptr2;
|
||||
part1Ptr = part1Ptr->internalRep.twoPtrValue.ptr1;
|
||||
typePtr = part1Ptr->typePtr;
|
||||
if (typePtr == &localVarNameType) {
|
||||
@@ -590,18 +563,23 @@ TclObjLookupVarEx(
|
||||
}
|
||||
parsed = 1;
|
||||
}
|
||||
part1 = TclGetStringFromObj(part1Ptr, &len1);
|
||||
|
||||
if (!parsed && len1 && (*(part1 + len1 - 1) == ')')) {
|
||||
if (!parsed) {
|
||||
|
||||
/*
|
||||
* part1Ptr is possibly an unparsed array element.
|
||||
*/
|
||||
|
||||
register int i;
|
||||
int len;
|
||||
const char *part1 = TclGetStringFromObj(part1Ptr, &len);
|
||||
|
||||
if (len > 1 && (part1[len - 1] == ')')) {
|
||||
|
||||
const char *part2 = strchr(part1, '(');
|
||||
|
||||
if (part2) {
|
||||
Tcl_Obj *arrayPtr;
|
||||
|
||||
len2 = -1;
|
||||
for (i = 0; i < len1; i++) {
|
||||
if (*(part1 + i) == '(') {
|
||||
if (part2Ptr != NULL) {
|
||||
if (flags & TCL_LEAVE_ERR_MSG) {
|
||||
TclObjVarErrMsg(interp, part1Ptr, part2Ptr, msg,
|
||||
@@ -612,47 +590,19 @@ TclObjLookupVarEx(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* part1Ptr points to an array element; first copy the element
|
||||
* name to a new string part2.
|
||||
*/
|
||||
arrayPtr = Tcl_NewStringObj(part1, (part2 - part1));
|
||||
part2Ptr = Tcl_NewStringObj(part2 + 1, len - (part2 - part1) - 2);
|
||||
|
||||
part2 = part1 + i + 1;
|
||||
len2 = len1 - i - 2;
|
||||
len1 = i;
|
||||
TclFreeIntRep(part1Ptr);
|
||||
|
||||
part2Ptr = Tcl_NewStringObj(part2, len2);
|
||||
if (createPart2) {
|
||||
Tcl_IncrRefCount(part2Ptr);
|
||||
}
|
||||
Tcl_IncrRefCount(arrayPtr);
|
||||
part1Ptr->internalRep.twoPtrValue.ptr1 = arrayPtr;
|
||||
Tcl_IncrRefCount(part2Ptr);
|
||||
part1Ptr->internalRep.twoPtrValue.ptr2 = part2Ptr;
|
||||
part1Ptr->typePtr = &tclParsedVarNameType;
|
||||
|
||||
/*
|
||||
* Free the internal rep of the original part1Ptr, now renamed
|
||||
* objPtr, and set it to tclParsedVarNameType.
|
||||
*/
|
||||
|
||||
objPtr = part1Ptr;
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = &tclParsedVarNameType;
|
||||
|
||||
/*
|
||||
* Define a new string object to hold the new part1Ptr, i.e.,
|
||||
* the array name. Set the internal rep of objPtr, reset
|
||||
* typePtr and part1 to contain the references to the array
|
||||
* name.
|
||||
*/
|
||||
|
||||
TclNewStringObj(part1Ptr, part1, len1);
|
||||
Tcl_IncrRefCount(part1Ptr);
|
||||
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = part1Ptr;
|
||||
Tcl_IncrRefCount(part2Ptr);
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = part2Ptr;
|
||||
|
||||
typePtr = part1Ptr->typePtr;
|
||||
part1 = TclGetString(part1Ptr);
|
||||
break;
|
||||
}
|
||||
part1Ptr = arrayPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,8 +612,6 @@ TclObjLookupVarEx(
|
||||
* the cached types if possible.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(part1Ptr);
|
||||
|
||||
varPtr = TclLookupSimpleVar(interp, part1Ptr, flags, createPart1,
|
||||
&errMsg, &index);
|
||||
if (varPtr == NULL) {
|
||||
@@ -679,11 +627,12 @@ TclObjLookupVarEx(
|
||||
* Cache the newly found variable if possible.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(part1Ptr);
|
||||
if (index >= 0) {
|
||||
/*
|
||||
* An indexed local variable.
|
||||
*/
|
||||
Tcl_Obj *cachedNamePtr = localName(iPtr->varFramePtr, index);
|
||||
Tcl_Obj *cachedNamePtr = localName(varFramePtr, index);
|
||||
|
||||
part1Ptr->typePtr = &localVarNameType;
|
||||
if (part1Ptr != cachedNamePtr) {
|
||||
@@ -724,21 +673,6 @@ TclObjLookupVarEx(
|
||||
return varPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* This flag bit should not interfere with TCL_GLOBAL_ONLY,
|
||||
* TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable
|
||||
* lookup is performed for upvar (or similar) purposes, with slightly
|
||||
* different rules:
|
||||
* - Bug #696893 - variable is either proc-local or in the current
|
||||
* namespace; never follow the second (global) resolution path
|
||||
* - Bug #631741 - do not use special namespace or interp resolvers
|
||||
*
|
||||
* It should also not collide with the (deprecated) TCL_PARSE_PART1 flag
|
||||
* (Bug #835020)
|
||||
*/
|
||||
|
||||
#define AVOID_RESOLVERS 0x40000
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -788,8 +722,8 @@ TclLookupSimpleVar(
|
||||
Tcl_Obj *varNamePtr, /* This is a simple variable name that could
|
||||
* represent a scalar or an array. */
|
||||
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
|
||||
* AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG bits
|
||||
* matter. */
|
||||
* TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
|
||||
* bits matter. */
|
||||
const int create, /* If 1, create hash table entry for varname,
|
||||
* if it doesn't already exist. If 0, return
|
||||
* error if it doesn't exist. */
|
||||
@@ -829,7 +763,7 @@ TclLookupSimpleVar(
|
||||
*/
|
||||
|
||||
if ((cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)
|
||||
&& !(flags & AVOID_RESOLVERS)) {
|
||||
&& !(flags & TCL_AVOID_RESOLVERS)) {
|
||||
resPtr = iPtr->resolverPtr;
|
||||
if (cxtNsPtr->varResProc) {
|
||||
result = cxtNsPtr->varResProc(interp, varName,
|
||||
@@ -882,7 +816,7 @@ TclLookupSimpleVar(
|
||||
*indexPtr = -1;
|
||||
flags = (flags | TCL_GLOBAL_ONLY) & ~TCL_NAMESPACE_ONLY;
|
||||
} else {
|
||||
if (flags & AVOID_RESOLVERS) {
|
||||
if (flags & TCL_AVOID_RESOLVERS) {
|
||||
flags = (flags | TCL_NAMESPACE_ONLY);
|
||||
}
|
||||
if (flags & TCL_NAMESPACE_ONLY) {
|
||||
@@ -897,7 +831,7 @@ TclLookupSimpleVar(
|
||||
|
||||
varPtr = (Var *) ObjFindNamespaceVar(interp, varNamePtr,
|
||||
(Tcl_Namespace *) cxtNsPtr,
|
||||
(flags | AVOID_RESOLVERS) & ~TCL_LEAVE_ERR_MSG);
|
||||
(flags | TCL_AVOID_RESOLVERS) & ~TCL_LEAVE_ERR_MSG);
|
||||
if (varPtr == NULL) {
|
||||
Tcl_Obj *tailPtr;
|
||||
|
||||
@@ -2913,34 +2847,22 @@ TclArraySet(
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
ArrayStartSearchCmd(
|
||||
ClientData clientData,
|
||||
|
||||
static Var *
|
||||
VerifyArray(
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
Tcl_Obj *varNameObj)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Var *varPtr, *arrayPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Tcl_Obj *varNameObj;
|
||||
int isNew;
|
||||
ArraySearch *searchPtr;
|
||||
const char *varName;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
varNameObj = objv[1];
|
||||
const char *varName = TclGetString(varNameObj);
|
||||
Var *arrayPtr;
|
||||
|
||||
/*
|
||||
* Locate the array variable.
|
||||
*/
|
||||
|
||||
varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
|
||||
Var *varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
|
||||
/*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
|
||||
varName = TclGetString(varNameObj);
|
||||
|
||||
/*
|
||||
* Special array trace used to keep the env array in sync for array names,
|
||||
@@ -2952,7 +2874,7 @@ ArrayStartSearchCmd(
|
||||
if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
|
||||
(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
|
||||
TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2962,11 +2884,36 @@ ArrayStartSearchCmd(
|
||||
* traces.
|
||||
*/
|
||||
|
||||
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|
||||
|| TclIsVarUndefined(varPtr)) {
|
||||
if ((varPtr == NULL) || !TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't an array", varName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", varName, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return varPtr;
|
||||
}
|
||||
|
||||
static int
|
||||
ArrayStartSearchCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Var *varPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew;
|
||||
ArraySearch *searchPtr;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
varPtr = VerifyArray(interp, objv[1]);
|
||||
if (varPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2988,8 +2935,9 @@ ArrayStartSearchCmd(
|
||||
searchPtr->nextEntry = VarHashFirstEntry(varPtr->value.tablePtr,
|
||||
&searchPtr->search);
|
||||
Tcl_SetHashValue(hPtr, searchPtr);
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_ObjPrintf("s-%d-%s", searchPtr->id, varName));
|
||||
searchPtr->name = Tcl_ObjPrintf("s-%d-%s", searchPtr->id, TclGetString(objv[1]));
|
||||
Tcl_IncrRefCount(searchPtr->name);
|
||||
Tcl_SetObjResult(interp, searchPtr->name);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3019,7 +2967,7 @@ ArrayAnyMoreCmd(
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Var *varPtr, *arrayPtr;
|
||||
Var *varPtr;
|
||||
Tcl_Obj *varNameObj, *searchObj;
|
||||
int gotValue;
|
||||
ArraySearch *searchPtr;
|
||||
@@ -3031,39 +2979,8 @@ ArrayAnyMoreCmd(
|
||||
varNameObj = objv[1];
|
||||
searchObj = objv[2];
|
||||
|
||||
/*
|
||||
* Locate the array variable.
|
||||
*/
|
||||
|
||||
varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
|
||||
/*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
|
||||
|
||||
/*
|
||||
* Special array trace used to keep the env array in sync for array names,
|
||||
* array get, etc.
|
||||
*/
|
||||
|
||||
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
|
||||
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
|
||||
if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
|
||||
(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
|
||||
TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that it is indeed an array variable. This test comes after the
|
||||
* traces - the variable may actually become an array as an effect of said
|
||||
* traces.
|
||||
*/
|
||||
|
||||
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|
||||
|| TclIsVarUndefined(varPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't an array", TclGetString(varNameObj)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
|
||||
TclGetString(varNameObj), NULL);
|
||||
varPtr = VerifyArray(interp, varNameObj);
|
||||
if (varPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3125,8 +3042,7 @@ ArrayNextElementCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Var *varPtr, *arrayPtr;
|
||||
Var *varPtr;
|
||||
Tcl_Obj *varNameObj, *searchObj;
|
||||
ArraySearch *searchPtr;
|
||||
|
||||
@@ -3137,39 +3053,8 @@ ArrayNextElementCmd(
|
||||
varNameObj = objv[1];
|
||||
searchObj = objv[2];
|
||||
|
||||
/*
|
||||
* Locate the array variable.
|
||||
*/
|
||||
|
||||
varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
|
||||
/*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
|
||||
|
||||
/*
|
||||
* Special array trace used to keep the env array in sync for array names,
|
||||
* array get, etc.
|
||||
*/
|
||||
|
||||
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
|
||||
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
|
||||
if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
|
||||
(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
|
||||
TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that it is indeed an array variable. This test comes after the
|
||||
* traces - the variable may actually become an array as an effect of said
|
||||
* traces.
|
||||
*/
|
||||
|
||||
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|
||||
|| TclIsVarUndefined(varPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't an array", TclGetString(varNameObj)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
|
||||
TclGetString(varNameObj), NULL);
|
||||
varPtr = VerifyArray(interp, varNameObj);
|
||||
if (varPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3235,7 +3120,7 @@ ArrayDoneSearchCmd(
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Var *varPtr, *arrayPtr;
|
||||
Var *varPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Tcl_Obj *varNameObj, *searchObj;
|
||||
ArraySearch *searchPtr, *prevPtr;
|
||||
@@ -3247,39 +3132,8 @@ ArrayDoneSearchCmd(
|
||||
varNameObj = objv[1];
|
||||
searchObj = objv[2];
|
||||
|
||||
/*
|
||||
* Locate the array variable.
|
||||
*/
|
||||
|
||||
varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
|
||||
/*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
|
||||
|
||||
/*
|
||||
* Special array trace used to keep the env array in sync for array names,
|
||||
* array get, etc.
|
||||
*/
|
||||
|
||||
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
|
||||
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
|
||||
if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
|
||||
(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
|
||||
TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that it is indeed an array variable. This test comes after the
|
||||
* traces - the variable may actually become an array as an effect of said
|
||||
* traces.
|
||||
*/
|
||||
|
||||
if ((varPtr == NULL) || !TclIsVarArray(varPtr)
|
||||
|| TclIsVarUndefined(varPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't an array", TclGetString(varNameObj)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
|
||||
TclGetString(varNameObj), NULL);
|
||||
varPtr = VerifyArray(interp, varNameObj);
|
||||
if (varPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3313,6 +3167,7 @@ ArrayDoneSearchCmd(
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_DecrRefCount(searchPtr->name);
|
||||
ckfree(searchPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4379,15 +4234,15 @@ TclPtrObjMakeUpvar(
|
||||
|
||||
/*
|
||||
* Lookup and eventually create the new variable. Set the flag bit
|
||||
* AVOID_RESOLVERS to indicate the special resolution rules for upvar
|
||||
* purposes:
|
||||
* TCL_AVOID_RESOLVERS to indicate the special resolution rules for
|
||||
* upvar purposes:
|
||||
* - Bug #696893 - variable is either proc-local or in the current
|
||||
* namespace; never follow the second (global) resolution path.
|
||||
* - Bug #631741 - do not use special namespace or interp resolvers.
|
||||
*/
|
||||
|
||||
varPtr = TclLookupSimpleVar(interp, myNamePtr,
|
||||
myFlags|AVOID_RESOLVERS, /* create */ 1, &errMsg, &index);
|
||||
myFlags|TCL_AVOID_RESOLVERS, /* create */ 1, &errMsg, &index);
|
||||
if (varPtr == NULL) {
|
||||
TclObjVarErrMsg(interp, myNamePtr, NULL, "create", errMsg, -1);
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
|
||||
@@ -4921,7 +4776,8 @@ Tcl_UpvarObjCmd(
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad level \"%s\"", TclGetString(levelObj)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LEVEL", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
|
||||
TclGetString(levelObj), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -4948,75 +4804,6 @@ Tcl_UpvarObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* SetArraySearchObj --
|
||||
*
|
||||
* This function converts the given tcl object into one that has the
|
||||
* "array search" internal type.
|
||||
*
|
||||
* Results:
|
||||
* TCL_OK if the conversion succeeded, and TCL_ERROR if it failed (when
|
||||
* an error message will be placed in the interpreter's result.)
|
||||
*
|
||||
* Side effects:
|
||||
* Updates the internal type and representation of the object to make
|
||||
* this an array-search object. See the tclArraySearchType declaration
|
||||
* above for details of the internal representation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
SetArraySearchObj(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
const char *string;
|
||||
char *end; /* Can't be const due to strtoul defn. */
|
||||
int id;
|
||||
size_t offset;
|
||||
|
||||
/*
|
||||
* Get the string representation. Make it up-to-date if necessary.
|
||||
*/
|
||||
|
||||
string = TclGetString(objPtr);
|
||||
|
||||
/*
|
||||
* Parse the id into the three parts separated by dashes.
|
||||
*/
|
||||
|
||||
if ((string[0] != 's') || (string[1] != '-')) {
|
||||
goto syntax;
|
||||
}
|
||||
id = strtoul(string+2, &end, 10);
|
||||
if ((end == (string+2)) || (*end != '-')) {
|
||||
goto syntax;
|
||||
}
|
||||
|
||||
/*
|
||||
* Can't perform value check in this context, so place reference to place
|
||||
* in string to use for the check in the object instead.
|
||||
*/
|
||||
|
||||
end++;
|
||||
offset = end - string;
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = &tclArraySearchType;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(id);
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(offset);
|
||||
return TCL_OK;
|
||||
|
||||
syntax:
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"illegal search identifier \"%s\"", string));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -5030,10 +4817,6 @@ SetArraySearchObj(
|
||||
* or NULL if there isn't one. If NULL is returned, the interp's result
|
||||
* contains an error message.
|
||||
*
|
||||
* Side effects:
|
||||
* The tcl object might have its internal type and representation
|
||||
* modified.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -5049,65 +4832,43 @@ ParseSearchId(
|
||||
* name. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
register const char *string;
|
||||
register size_t offset;
|
||||
int id;
|
||||
ArraySearch *searchPtr;
|
||||
const char *varName = TclGetString(varNamePtr);
|
||||
|
||||
/*
|
||||
* Parse the id.
|
||||
*/
|
||||
|
||||
if ((handleObj->typePtr != &tclArraySearchType)
|
||||
&& (SetArraySearchObj(interp, handleObj) != TCL_OK)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the information out of the Tcl_Obj.
|
||||
*/
|
||||
|
||||
id = PTR2INT(handleObj->internalRep.twoPtrValue.ptr1);
|
||||
string = TclGetString(handleObj);
|
||||
offset = PTR2INT(handleObj->internalRep.twoPtrValue.ptr2);
|
||||
|
||||
/*
|
||||
* This test cannot be placed inside the Tcl_Obj machinery, since it is
|
||||
* dependent on the variable context.
|
||||
*/
|
||||
|
||||
if (strcmp(string+offset, varName) != 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"search identifier \"%s\" isn't for variable \"%s\"",
|
||||
string, varName));
|
||||
goto badLookup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search through the list of active searches on the interpreter to see if
|
||||
* the desired one exists.
|
||||
*
|
||||
* Note that we cannot store the searchPtr directly in the Tcl_Obj as that
|
||||
* would run into trouble when DeleteSearches() was called so we must scan
|
||||
* this list every time.
|
||||
*/
|
||||
const char *handle = TclGetString(handleObj);
|
||||
char *end;
|
||||
|
||||
if (varPtr->flags & VAR_SEARCH_ACTIVE) {
|
||||
Tcl_HashEntry *hPtr =
|
||||
Tcl_FindHashEntry(&iPtr->varSearches, varPtr);
|
||||
|
||||
/* First look for same (Tcl_Obj *) */
|
||||
for (searchPtr = Tcl_GetHashValue(hPtr); searchPtr != NULL;
|
||||
searchPtr = searchPtr->nextPtr) {
|
||||
if (searchPtr->id == id) {
|
||||
if (searchPtr->name == handleObj) {
|
||||
return searchPtr;
|
||||
}
|
||||
}
|
||||
/* Fallback: do string compares. */
|
||||
for (searchPtr = Tcl_GetHashValue(hPtr); searchPtr != NULL;
|
||||
searchPtr = searchPtr->nextPtr) {
|
||||
if (strcmp(TclGetString(searchPtr->name), handle) == 0) {
|
||||
return searchPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't find search \"%s\"", string));
|
||||
badLookup:
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
|
||||
if ((handle[0] != 's') || (handle[1] != '-')
|
||||
|| (strtoul(handle + 2, &end, 10), end == (handle + 2))
|
||||
|| (*end != '-')) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"illegal search identifier \"%s\"", handle));
|
||||
} else if (strcmp(end + 1, TclGetString(varNamePtr)) != 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"search identifier \"%s\" isn't for variable \"%s\"",
|
||||
handle, TclGetString(varNamePtr)));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't find search \"%s\"", handle));
|
||||
}
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", handle, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5142,6 +4903,7 @@ DeleteSearches(
|
||||
for (searchPtr = Tcl_GetHashValue(sPtr); searchPtr != NULL;
|
||||
searchPtr = nextPtr) {
|
||||
nextPtr = searchPtr->nextPtr;
|
||||
Tcl_DecrRefCount(searchPtr->name);
|
||||
ckfree(searchPtr);
|
||||
}
|
||||
arrayVarPtr->flags &= ~VAR_SEARCH_ACTIVE;
|
||||
@@ -5194,13 +4956,16 @@ TclDeleteNamespaceVars(
|
||||
VarHashRefCount(varPtr)++; /* Make sure we get to remove from
|
||||
* hash. */
|
||||
Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
|
||||
UnsetVarStruct(varPtr, NULL, iPtr, /* part1 */ objPtr, NULL, flags,
|
||||
-1);
|
||||
Tcl_DecrRefCount(objPtr); /* Free no longer needed obj */
|
||||
UnsetVarStruct(varPtr, NULL, iPtr, /* part1 */ objPtr,
|
||||
NULL, flags, -1);
|
||||
|
||||
/*
|
||||
* Remove the variable from the table and force it undefined in case
|
||||
* an unset trace brought it back from the dead.
|
||||
* We just unset the variable. However, an unset trace might
|
||||
* have re-set it, or might have re-established traces on it.
|
||||
* This namespace and its vartable are going away unconditionally,
|
||||
* so we cannot let such things linger. That would be a leak.
|
||||
*
|
||||
* First we destroy all traces. ...
|
||||
*/
|
||||
|
||||
if (TclIsVarTraced(varPtr)) {
|
||||
@@ -5224,6 +4989,17 @@ TclDeleteNamespaceVars(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ...and then, if the variable still holds a value, we unset it
|
||||
* again. This time with no traces left, we're sure it goes away.
|
||||
*/
|
||||
|
||||
if (!TclIsVarUndefined(varPtr)) {
|
||||
UnsetVarStruct(varPtr, NULL, iPtr, /* part1 */ objPtr,
|
||||
NULL, flags, -1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr); /* free no longer needed obj */
|
||||
VarHashRefCount(varPtr)--;
|
||||
VarHashDeleteEntry(varPtr);
|
||||
}
|
||||
@@ -5614,11 +5390,12 @@ Tcl_FindNamespaceVar(
|
||||
* Otherwise, points to namespace in which to
|
||||
* resolve name. If NULL, look up name in the
|
||||
* current namespace. */
|
||||
int flags) /* An OR'd combination of: AVOID_RESOLVERS,
|
||||
* TCL_GLOBAL_ONLY (look up name only in
|
||||
* global namespace), TCL_NAMESPACE_ONLY (look
|
||||
* up only in contextNsPtr, or the current
|
||||
* namespace if contextNsPtr is NULL), and
|
||||
int flags) /* An OR'd combination of:
|
||||
* TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
|
||||
* up name only in global namespace),
|
||||
* TCL_NAMESPACE_ONLY (look up only in
|
||||
* contextNsPtr, or the current namespace if
|
||||
* contextNsPtr is NULL), and
|
||||
* TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
|
||||
* and TCL_NAMESPACE_ONLY are given,
|
||||
* TCL_GLOBAL_ONLY is ignored. */
|
||||
@@ -5644,11 +5421,12 @@ ObjFindNamespaceVar(
|
||||
* Otherwise, points to namespace in which to
|
||||
* resolve name. If NULL, look up name in the
|
||||
* current namespace. */
|
||||
int flags) /* An OR'd combination of: AVOID_RESOLVERS,
|
||||
* TCL_GLOBAL_ONLY (look up name only in
|
||||
* global namespace), TCL_NAMESPACE_ONLY (look
|
||||
* up only in contextNsPtr, or the current
|
||||
* namespace if contextNsPtr is NULL), and
|
||||
int flags) /* An OR'd combination of:
|
||||
* TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
|
||||
* up name only in global namespace),
|
||||
* TCL_NAMESPACE_ONLY (look up only in
|
||||
* contextNsPtr, or the current namespace if
|
||||
* contextNsPtr is NULL), and
|
||||
* TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
|
||||
* and TCL_NAMESPACE_ONLY are given,
|
||||
* TCL_GLOBAL_ONLY is ignored. */
|
||||
@@ -5678,7 +5456,7 @@ ObjFindNamespaceVar(
|
||||
cxtNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
}
|
||||
|
||||
if (!(flags & AVOID_RESOLVERS) &&
|
||||
if (!(flags & TCL_AVOID_RESOLVERS) &&
|
||||
(cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)) {
|
||||
resPtr = iPtr->resolverPtr;
|
||||
|
||||
|
||||
+134
-97
@@ -177,6 +177,8 @@ static Tcl_ObjCmdProc ZlibStreamPutCmd;
|
||||
static void ConvertError(Tcl_Interp *interp, int code,
|
||||
uLong adler);
|
||||
static Tcl_Obj * ConvertErrorToList(int code, uLong adler);
|
||||
static inline int Deflate(z_streamp strm, void *bufferPtr,
|
||||
int bufferSize, int flush, int *writtenPtr);
|
||||
static void ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj);
|
||||
static int GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj,
|
||||
GzipHeader *headerPtr, int *extraSizePtr);
|
||||
@@ -438,7 +440,7 @@ GenerateHeader(
|
||||
if (GetValue(interp, dictObj, "comment", &value) != TCL_OK) {
|
||||
goto error;
|
||||
} else if (value != NULL) {
|
||||
valueStr = Tcl_GetStringFromObj(value, &len);
|
||||
valueStr = TclGetStringFromObj(value, &len);
|
||||
Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
|
||||
headerPtr->nativeCommentBuf, MAX_COMMENT_LEN-1, NULL, &len,
|
||||
NULL);
|
||||
@@ -459,7 +461,7 @@ GenerateHeader(
|
||||
if (GetValue(interp, dictObj, "filename", &value) != TCL_OK) {
|
||||
goto error;
|
||||
} else if (value != NULL) {
|
||||
valueStr = Tcl_GetStringFromObj(value, &len);
|
||||
valueStr = TclGetStringFromObj(value, &len);
|
||||
Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
|
||||
headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len, NULL);
|
||||
headerPtr->nativeFilenameBuf[len] = '\0';
|
||||
@@ -578,6 +580,10 @@ ExtractHeader(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Disentangle the worst of how the zlib API is used.
|
||||
*/
|
||||
|
||||
static int
|
||||
SetInflateDictionary(
|
||||
z_streamp strm,
|
||||
@@ -605,6 +611,38 @@ SetDeflateDictionary(
|
||||
}
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
Deflate(
|
||||
z_streamp strm,
|
||||
void *bufferPtr,
|
||||
int bufferSize,
|
||||
int flush,
|
||||
int *writtenPtr)
|
||||
{
|
||||
int e;
|
||||
|
||||
strm->next_out = (Bytef *) bufferPtr;
|
||||
strm->avail_out = (unsigned) bufferSize;
|
||||
e = deflate(strm, flush);
|
||||
if (writtenPtr != NULL) {
|
||||
*writtenPtr = bufferSize - strm->avail_out;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
static inline void
|
||||
AppendByteArray(
|
||||
Tcl_Obj *listObj,
|
||||
void *buffer,
|
||||
int size)
|
||||
{
|
||||
if (size > 0) {
|
||||
Tcl_Obj *baObj = Tcl_NewByteArrayObj((unsigned char *) buffer, size);
|
||||
|
||||
Tcl_ListObjAppendElement(NULL, listObj, baObj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1139,6 +1177,8 @@ Tcl_ZlibStreamSetCompressionDictionary(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define BUFFER_SIZE_LIMIT 0xFFFF
|
||||
|
||||
int
|
||||
Tcl_ZlibStreamPut(
|
||||
Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */
|
||||
@@ -1148,8 +1188,7 @@ Tcl_ZlibStreamPut(
|
||||
{
|
||||
ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
|
||||
char *dataTmp = NULL;
|
||||
int e, size, outSize;
|
||||
Tcl_Obj *obj;
|
||||
int e, size, outSize, toStore;
|
||||
|
||||
if (zshPtr->streamEnd) {
|
||||
if (zshPtr->interp) {
|
||||
@@ -1175,26 +1214,45 @@ Tcl_ZlibStreamPut(
|
||||
if (HaveDictToSet(zshPtr)) {
|
||||
e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
|
||||
if (e != Z_OK) {
|
||||
if (zshPtr->interp) {
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
}
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
DictWasSet(zshPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deflatebound doesn't seem to take various header sizes into
|
||||
* account, so we add 100 extra bytes.
|
||||
* deflateBound() doesn't seem to take various header sizes into
|
||||
* account, so we add 100 extra bytes. However, we can also loop
|
||||
* around again so we also set an upper bound on the output buffer
|
||||
* size.
|
||||
*/
|
||||
|
||||
outSize = deflateBound(&zshPtr->stream, zshPtr->stream.avail_in)+100;
|
||||
zshPtr->stream.avail_out = outSize;
|
||||
dataTmp = ckalloc(zshPtr->stream.avail_out);
|
||||
zshPtr->stream.next_out = (Bytef *) dataTmp;
|
||||
outSize = deflateBound(&zshPtr->stream, size) + 100;
|
||||
if (outSize > BUFFER_SIZE_LIMIT) {
|
||||
outSize = BUFFER_SIZE_LIMIT;
|
||||
}
|
||||
dataTmp = ckalloc(outSize);
|
||||
|
||||
while (1) {
|
||||
e = Deflate(&zshPtr->stream, dataTmp, outSize, flush, &toStore);
|
||||
|
||||
/*
|
||||
* Test if we've filled the buffer up and have to ask deflate() to
|
||||
* give us some more. Note that the condition for needing to
|
||||
* repeat a buffer transfer when the result is Z_OK is whether
|
||||
* there is no more space in the buffer we provided; the zlib
|
||||
* library does not necessarily return a different code in that
|
||||
* case. [Bug b26e38a3e4] [Tk Bug 10f2e7872b]
|
||||
*/
|
||||
|
||||
if ((e != Z_BUF_ERROR) && (e != Z_OK || toStore < outSize)) {
|
||||
if ((e == Z_OK) || (flush == Z_FINISH && e == Z_STREAM_END)) {
|
||||
break;
|
||||
}
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
e = deflate(&zshPtr->stream, flush);
|
||||
while (e == Z_BUF_ERROR || (flush == Z_FINISH && e == Z_OK)) {
|
||||
/*
|
||||
* Output buffer too small to hold the data being generated or we
|
||||
* are doing the end-of-stream flush (which can spit out masses of
|
||||
@@ -1202,45 +1260,21 @@ Tcl_ZlibStreamPut(
|
||||
* saving the old generated data to the outData list.
|
||||
*/
|
||||
|
||||
obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize);
|
||||
Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
|
||||
AppendByteArray(zshPtr->outData, dataTmp, outSize);
|
||||
|
||||
if (outSize < 0xFFFF) {
|
||||
outSize = 0xFFFF; /* There may be *lots* of data left to
|
||||
* output... */
|
||||
if (outSize < BUFFER_SIZE_LIMIT) {
|
||||
outSize = BUFFER_SIZE_LIMIT;
|
||||
/* There may be *lots* of data left to output... */
|
||||
dataTmp = ckrealloc(dataTmp, outSize);
|
||||
}
|
||||
zshPtr->stream.avail_out = outSize;
|
||||
zshPtr->stream.next_out = (Bytef *) dataTmp;
|
||||
|
||||
e = deflate(&zshPtr->stream, flush);
|
||||
}
|
||||
|
||||
if (e != Z_OK && !(flush==Z_FINISH && e==Z_STREAM_END)) {
|
||||
if (zshPtr->interp) {
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* And append the final data block.
|
||||
* And append the final data block to the outData list.
|
||||
*/
|
||||
|
||||
if (outSize - zshPtr->stream.avail_out > 0) {
|
||||
obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp,
|
||||
outSize - zshPtr->stream.avail_out);
|
||||
|
||||
/*
|
||||
* Now append the compressed data to the outData list.
|
||||
*/
|
||||
|
||||
Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
|
||||
}
|
||||
|
||||
if (dataTmp) {
|
||||
ckfree(dataTmp);
|
||||
}
|
||||
AppendByteArray(zshPtr->outData, dataTmp, toStore);
|
||||
ckfree(dataTmp);
|
||||
} else {
|
||||
/*
|
||||
* This is easy. Just append to the inData list.
|
||||
@@ -1356,9 +1390,7 @@ Tcl_ZlibStreamGet(
|
||||
if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr)) {
|
||||
e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
|
||||
if (e != Z_OK) {
|
||||
if (zshPtr->interp) {
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
}
|
||||
ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
DictWasSet(zshPtr);
|
||||
@@ -2864,7 +2896,7 @@ ZlibTransformClose(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
ZlibChannelData *cd = instanceData;
|
||||
int e, result = TCL_OK;
|
||||
int e, written, result = TCL_OK;
|
||||
|
||||
/*
|
||||
* Delete the support timer.
|
||||
@@ -2879,9 +2911,18 @@ ZlibTransformClose(
|
||||
if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
|
||||
cd->outStream.avail_in = 0;
|
||||
do {
|
||||
cd->outStream.next_out = (Bytef *) cd->outBuffer;
|
||||
cd->outStream.avail_out = (unsigned) cd->outAllocated;
|
||||
e = deflate(&cd->outStream, Z_FINISH);
|
||||
e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated,
|
||||
Z_FINISH, &written);
|
||||
|
||||
/*
|
||||
* Can't be sure that deflate() won't declare the buffer to be
|
||||
* full (with Z_BUF_ERROR) so handle that case.
|
||||
*/
|
||||
|
||||
if (e == Z_BUF_ERROR) {
|
||||
e = Z_OK;
|
||||
written = cd->outAllocated;
|
||||
}
|
||||
if (e != Z_OK && e != Z_STREAM_END) {
|
||||
/* TODO: is this the right way to do errors on close? */
|
||||
if (!TclInThreadExit()) {
|
||||
@@ -2890,25 +2931,22 @@ ZlibTransformClose(
|
||||
result = TCL_ERROR;
|
||||
break;
|
||||
}
|
||||
if (cd->outStream.avail_out != (unsigned) cd->outAllocated) {
|
||||
if (Tcl_WriteRaw(cd->parent, cd->outBuffer,
|
||||
cd->outAllocated - cd->outStream.avail_out) < 0) {
|
||||
/* TODO: is this the right way to do errors on close?
|
||||
* Note: when close is called from FinalizeIOSubsystem
|
||||
* then interp may be NULL */
|
||||
if (!TclInThreadExit() && interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error while finalizing file: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
break;
|
||||
if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) < 0) {
|
||||
/* TODO: is this the right way to do errors on close?
|
||||
* Note: when close is called from FinalizeIOSubsystem then
|
||||
* interp may be NULL */
|
||||
if (!TclInThreadExit() && interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error while finalizing file: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
break;
|
||||
}
|
||||
} while (e != Z_STREAM_END);
|
||||
e = deflateEnd(&cd->outStream);
|
||||
(void) deflateEnd(&cd->outStream);
|
||||
} else {
|
||||
e = inflateEnd(&cd->inStream);
|
||||
(void) inflateEnd(&cd->inStream);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3078,13 +3116,21 @@ ZlibTransformOutput(
|
||||
cd->outStream.next_in = (Bytef *) buf;
|
||||
cd->outStream.avail_in = toWrite;
|
||||
do {
|
||||
cd->outStream.next_out = (Bytef *) cd->outBuffer;
|
||||
cd->outStream.avail_out = cd->outAllocated;
|
||||
e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated,
|
||||
Z_NO_FLUSH, &produced);
|
||||
|
||||
e = deflate(&cd->outStream, Z_NO_FLUSH);
|
||||
produced = cd->outAllocated - cd->outStream.avail_out;
|
||||
if ((e == Z_OK && produced > 0) || e == Z_BUF_ERROR) {
|
||||
/*
|
||||
* deflate() indicates that it is out of space by returning
|
||||
* Z_BUF_ERROR *or* by simply returning Z_OK with no remaining
|
||||
* space; in either case, we must write the whole buffer out and
|
||||
* retry to compress what is left.
|
||||
*/
|
||||
|
||||
if (e == Z_OK && produced > 0) {
|
||||
if (e == Z_BUF_ERROR) {
|
||||
produced = cd->outAllocated;
|
||||
e = Z_OK;
|
||||
}
|
||||
if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) {
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
return -1;
|
||||
@@ -3131,10 +3177,8 @@ ZlibTransformFlush(
|
||||
* Get the bytes to go out of the compression engine.
|
||||
*/
|
||||
|
||||
cd->outStream.next_out = (Bytef *) cd->outBuffer;
|
||||
cd->outStream.avail_out = cd->outAllocated;
|
||||
|
||||
e = deflate(&cd->outStream, flushType);
|
||||
e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated,
|
||||
flushType, &len);
|
||||
if (e != Z_OK && e != Z_BUF_ERROR) {
|
||||
ConvertError(interp, e, cd->outStream.adler);
|
||||
return TCL_ERROR;
|
||||
@@ -3144,7 +3188,6 @@ ZlibTransformFlush(
|
||||
* Write the bytes we've received to the next layer.
|
||||
*/
|
||||
|
||||
len = cd->outStream.next_out - (Bytef *) cd->outBuffer;
|
||||
if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) < 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"problem flushing channel: %s",
|
||||
@@ -3344,10 +3387,13 @@ ZlibTransformGetOption(
|
||||
Tcl_DStringAppendElement(dsPtr, "");
|
||||
}
|
||||
} else {
|
||||
int len;
|
||||
const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len);
|
||||
if (cd->compDictObj) {
|
||||
int len;
|
||||
const char *str = TclGetStringFromObj(cd->compDictObj, &len);
|
||||
|
||||
Tcl_DStringAppend(dsPtr, str, len);
|
||||
Tcl_DStringAppend(dsPtr, str, len);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3549,7 +3595,6 @@ ZlibStackChannelTransform(
|
||||
ZlibChannelData *cd = ckalloc(sizeof(ZlibChannelData));
|
||||
Tcl_Channel chan;
|
||||
int wbits = 0;
|
||||
int e;
|
||||
|
||||
if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) {
|
||||
Tcl_Panic("unknown mode: %d", mode);
|
||||
@@ -3603,43 +3648,35 @@ ZlibStackChannelTransform(
|
||||
*/
|
||||
|
||||
if (mode == TCL_ZLIB_STREAM_INFLATE) {
|
||||
e = inflateInit2(&cd->inStream, wbits);
|
||||
if (e != Z_OK) {
|
||||
if (inflateInit2(&cd->inStream, wbits) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
cd->inAllocated = DEFAULT_BUFFER_SIZE;
|
||||
cd->inBuffer = ckalloc(cd->inAllocated);
|
||||
if (cd->flags & IN_HEADER) {
|
||||
e = inflateGetHeader(&cd->inStream, &cd->inHeader.header);
|
||||
if (e != Z_OK) {
|
||||
if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
|
||||
e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
|
||||
if (e != Z_OK) {
|
||||
if (SetInflateDictionary(&cd->inStream, cd->compDictObj) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
TclDecrRefCount(cd->compDictObj);
|
||||
cd->compDictObj = NULL;
|
||||
}
|
||||
} else {
|
||||
e = deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
|
||||
MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
||||
if (e != Z_OK) {
|
||||
if (deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
|
||||
MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
cd->outAllocated = DEFAULT_BUFFER_SIZE;
|
||||
cd->outBuffer = ckalloc(cd->outAllocated);
|
||||
if (cd->flags & OUT_HEADER) {
|
||||
e = deflateSetHeader(&cd->outStream, &cd->outHeader.header);
|
||||
if (e != Z_OK) {
|
||||
if (deflateSetHeader(&cd->outStream, &cd->outHeader.header) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (cd->compDictObj) {
|
||||
e = SetDeflateDictionary(&cd->outStream, cd->compDictObj);
|
||||
if (e != Z_OK) {
|
||||
if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -122,11 +122,9 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} {
|
||||
# uniquify $dirs in order
|
||||
array set seen {}
|
||||
foreach i $dirs {
|
||||
# Take note that the [file normalize] below has been noted to cause
|
||||
# difficulties for the freewrap utility. See Bug 1072136. Until
|
||||
# freewrap resolves the matter, one might work around the problem by
|
||||
# disabling that branch.
|
||||
# Make sure $i is unique under normalization. Avoid repeated [source].
|
||||
if {[interp issafe]} {
|
||||
# Safe interps have no [file normalize].
|
||||
set norm $i
|
||||
} else {
|
||||
set norm [file normalize $i]
|
||||
@@ -135,10 +133,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} {
|
||||
continue
|
||||
}
|
||||
set seen($norm) {}
|
||||
lappend uniqdirs $i
|
||||
}
|
||||
set dirs $uniqdirs
|
||||
foreach i $dirs {
|
||||
|
||||
set the_library $i
|
||||
set file [file join $i $initScript]
|
||||
|
||||
|
||||
@@ -56,6 +56,30 @@ proc ::history {args} {
|
||||
tailcall apply {arglist {tailcall history {*}$arglist} ::tcl} $args
|
||||
}
|
||||
|
||||
# (unnamed) --
|
||||
#
|
||||
# Callback when [::history] is destroyed. Destroys the implementation.
|
||||
#
|
||||
# Parameters:
|
||||
# oldName what the command was called.
|
||||
# newName what the command is now called (an empty string).
|
||||
# op the operation (= delete).
|
||||
#
|
||||
# Results:
|
||||
# none
|
||||
#
|
||||
# Side Effects:
|
||||
# The implementation of the [::history] command ceases to exist.
|
||||
|
||||
trace add command ::history delete [list apply {{oldName newName op} {
|
||||
variable history
|
||||
unset -nocomplain history
|
||||
foreach c [info procs ::tcl::Hist*] {
|
||||
rename $c {}
|
||||
}
|
||||
rename ::tcl::history {}
|
||||
} ::tcl}]
|
||||
|
||||
# tcl::HistAdd --
|
||||
#
|
||||
# Add an item to the history, and optionally eval it at the global scope
|
||||
|
||||
+35
-3
@@ -8,10 +8,10 @@
|
||||
# See the file "license.terms" for information on usage and redistribution of
|
||||
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
package require Tcl 8.6
|
||||
package require Tcl 8.6-
|
||||
# Keep this in sync with pkgIndex.tcl and with the install directories in
|
||||
# Makefiles
|
||||
package provide http 2.8.9
|
||||
package provide http 2.8.10
|
||||
|
||||
namespace eval http {
|
||||
# Allow resourcing to not clobber existing data
|
||||
@@ -1047,7 +1047,7 @@ proc http::Event {sock token} {
|
||||
fconfigure $sock -translation binary
|
||||
|
||||
if {
|
||||
$state(-binary) || ![string match -nocase text* $state(type)]
|
||||
$state(-binary) || [IsBinaryContentType $state(type)]
|
||||
} {
|
||||
# Turn off conversions for non-text data
|
||||
set state(binary) 1
|
||||
@@ -1183,6 +1183,38 @@ proc http::Event {sock token} {
|
||||
}
|
||||
}
|
||||
|
||||
# http::IsBinaryContentType --
|
||||
#
|
||||
# Determine if the content-type means that we should definitely transfer
|
||||
# the data as binary. [Bug 838e99a76d]
|
||||
#
|
||||
# Arguments
|
||||
# type The content-type of the data.
|
||||
#
|
||||
# Results:
|
||||
# Boolean, true if we definitely should be binary.
|
||||
|
||||
proc http::IsBinaryContentType {type} {
|
||||
lassign [split [string tolower $type] "/;"] major minor
|
||||
if {$major eq "text"} {
|
||||
return false
|
||||
}
|
||||
# There's a bunch of XML-as-application-format things about. See RFC 3023
|
||||
# and so on.
|
||||
if {$major eq "application"} {
|
||||
set minor [string trimright $minor]
|
||||
if {$minor in {"xml" "xml-external-parsed-entity" "xml-dtd"}} {
|
||||
return false
|
||||
}
|
||||
}
|
||||
# Not just application/foobar+xml but also image/svg+xml, so let us not
|
||||
# restrict things for now...
|
||||
if {[string match "*+xml" $minor]} {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
# http::getTextLine --
|
||||
#
|
||||
# Get one line with the stream in blocking crlf mode
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
if {![package vsatisfies [package provide Tcl] 8.6]} {return}
|
||||
package ifneeded http 2.8.9 [list tclPkgSetup $dir http 2.8.9 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
|
||||
if {![package vsatisfies [package provide Tcl] 8.6-]} {return}
|
||||
package ifneeded http 2.8.10 [list tclPkgSetup $dir http 2.8.10 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# See the file "license.terms" for information on usage and redistribution
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
package require Tcl 8.5
|
||||
package require Tcl 8.5-
|
||||
# When the version number changes, be sure to update the pkgIndex.tcl file,
|
||||
# and the installation directory in the Makefiles.
|
||||
package provide msgcat 1.6.0
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
if {([info commands ::tcl::pkgconfig] eq "")
|
||||
|| ([info sharedlibextension] ne ".dll")} return
|
||||
if {[::tcl::pkgconfig get debug]} {
|
||||
package ifneeded registry 1.3.1 \
|
||||
package ifneeded registry 1.3.2 \
|
||||
[list load [file join $dir tclreg13g.dll] registry]
|
||||
} else {
|
||||
package ifneeded registry 1.3.1 \
|
||||
package ifneeded registry 1.3.2 \
|
||||
[list load [file join $dir tclreg13.dll] registry]
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
# full path name of this file's directory.
|
||||
|
||||
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
|
||||
package ifneeded tcltest 2.3.8 [list source [file join $dir tcltest.tcl]]
|
||||
package ifneeded tcltest 2.4.0 [list source [file join $dir tcltest.tcl]]
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
# Contributions from Don Porter, NIST, 2002. (not subject to US copyright)
|
||||
# All rights reserved.
|
||||
|
||||
package require Tcl 8.5 ;# -verbose line uses [info frame]
|
||||
package require Tcl 8.5- ;# -verbose line uses [info frame]
|
||||
namespace eval tcltest {
|
||||
|
||||
# When the version number changes, be sure to update the pkgIndex.tcl file,
|
||||
# and the install directory in the Makefiles. When the minor version
|
||||
# changes (new feature) be sure to update the man page as well.
|
||||
variable Version 2.3.8
|
||||
variable Version 2.4.0
|
||||
|
||||
# Compatibility support for dumb variables defined in tcltest 1
|
||||
# Do not use these. Call [package provide Tcl] and [info patchlevel]
|
||||
@@ -611,16 +611,27 @@ namespace eval tcltest {
|
||||
|
||||
proc AcceptVerbose { level } {
|
||||
set level [AcceptList $level]
|
||||
set levelMap {
|
||||
l list
|
||||
p pass
|
||||
b body
|
||||
s skip
|
||||
t start
|
||||
e error
|
||||
l line
|
||||
m msec
|
||||
u usec
|
||||
}
|
||||
set levelRegexp "^([join [dict values $levelMap] |])\$"
|
||||
if {[llength $level] == 1} {
|
||||
if {![regexp {^(pass|body|skip|start|error|line)$} $level]} {
|
||||
if {![regexp $levelRegexp $level]} {
|
||||
# translate single characters abbreviations to expanded list
|
||||
set level [string map {p pass b body s skip t start e error l line} \
|
||||
[split $level {}]]
|
||||
set level [string map $levelMap [split $level {}]]
|
||||
}
|
||||
}
|
||||
set valid [list]
|
||||
foreach v $level {
|
||||
if {[regexp {^(pass|body|skip|start|error|line)$} $v]} {
|
||||
if {[regexp $levelRegexp $v]} {
|
||||
lappend valid $v
|
||||
}
|
||||
}
|
||||
@@ -1972,6 +1983,11 @@ proc tcltest::test {name description args} {
|
||||
# Only run the test body if the setup was successful
|
||||
if {!$setupFailure} {
|
||||
|
||||
# Register startup time
|
||||
if {[IsVerbose msec] || [IsVerbose usec]} {
|
||||
set timeStart [clock microseconds]
|
||||
}
|
||||
|
||||
# Verbose notification of $body start
|
||||
if {[IsVerbose start]} {
|
||||
puts [outputChannel] "---- $name start"
|
||||
@@ -2076,6 +2092,16 @@ proc tcltest::test {name description args} {
|
||||
}
|
||||
}
|
||||
|
||||
if {[IsVerbose msec] || [IsVerbose usec]} {
|
||||
set t [expr {[clock microseconds] - $timeStart}]
|
||||
if {[IsVerbose usec]} {
|
||||
puts [outputChannel] "++++ $name took $t μs"
|
||||
}
|
||||
if {[IsVerbose msec]} {
|
||||
puts [outputChannel] "++++ $name took [expr {round($t/1000.)}] ms"
|
||||
}
|
||||
}
|
||||
|
||||
# if we didn't experience any failures, then we passed
|
||||
variable numTests
|
||||
if {!($setupFailure || $cleanupFailure || $coreFailure
|
||||
@@ -2683,7 +2709,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
|
||||
DebugPuts 1 "No test directories remain after applying match\
|
||||
and skip patterns!"
|
||||
}
|
||||
return $matchDirs
|
||||
return [lsort $matchDirs]
|
||||
}
|
||||
|
||||
# tcltest::runAllTests --
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Cambridge_Bay) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-1577923200 -25200 0 MST}
|
||||
{-880210800 -21600 1 MWT}
|
||||
{-769395600 -21600 1 MPT}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Inuvik) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-536457600 -28800 0 PST}
|
||||
{-147888000 -21600 1 PDDT}
|
||||
{-131558400 -28800 0 PST}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Iqaluit) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-865296000 -14400 0 EWT}
|
||||
{-769395600 -14400 1 EPT}
|
||||
{-765396000 -18000 0 EST}
|
||||
|
||||
@@ -11,41 +11,41 @@ set TZData(:America/Los_Angeles) {
|
||||
{-769395600 -25200 1 PPT}
|
||||
{-765385200 -28800 0 PST}
|
||||
{-757353600 -28800 0 PST}
|
||||
{-687967200 -25200 1 PDT}
|
||||
{-687967140 -25200 1 PDT}
|
||||
{-662655600 -28800 0 PST}
|
||||
{-620834400 -25200 1 PDT}
|
||||
{-620838000 -25200 1 PDT}
|
||||
{-608137200 -28800 0 PST}
|
||||
{-589384800 -25200 1 PDT}
|
||||
{-589388400 -25200 1 PDT}
|
||||
{-576082800 -28800 0 PST}
|
||||
{-557935200 -25200 1 PDT}
|
||||
{-557938800 -25200 1 PDT}
|
||||
{-544633200 -28800 0 PST}
|
||||
{-526485600 -25200 1 PDT}
|
||||
{-526489200 -25200 1 PDT}
|
||||
{-513183600 -28800 0 PST}
|
||||
{-495036000 -25200 1 PDT}
|
||||
{-495039600 -25200 1 PDT}
|
||||
{-481734000 -28800 0 PST}
|
||||
{-463586400 -25200 1 PDT}
|
||||
{-463590000 -25200 1 PDT}
|
||||
{-450284400 -28800 0 PST}
|
||||
{-431532000 -25200 1 PDT}
|
||||
{-431535600 -25200 1 PDT}
|
||||
{-418230000 -28800 0 PST}
|
||||
{-400082400 -25200 1 PDT}
|
||||
{-400086000 -25200 1 PDT}
|
||||
{-386780400 -28800 0 PST}
|
||||
{-368632800 -25200 1 PDT}
|
||||
{-368636400 -25200 1 PDT}
|
||||
{-355330800 -28800 0 PST}
|
||||
{-337183200 -25200 1 PDT}
|
||||
{-337186800 -25200 1 PDT}
|
||||
{-323881200 -28800 0 PST}
|
||||
{-305733600 -25200 1 PDT}
|
||||
{-305737200 -25200 1 PDT}
|
||||
{-292431600 -28800 0 PST}
|
||||
{-273679200 -25200 1 PDT}
|
||||
{-273682800 -25200 1 PDT}
|
||||
{-260982000 -28800 0 PST}
|
||||
{-242229600 -25200 1 PDT}
|
||||
{-242233200 -25200 1 PDT}
|
||||
{-226508400 -28800 0 PST}
|
||||
{-210780000 -25200 1 PDT}
|
||||
{-210783600 -25200 1 PDT}
|
||||
{-195058800 -28800 0 PST}
|
||||
{-179330400 -25200 1 PDT}
|
||||
{-179334000 -25200 1 PDT}
|
||||
{-163609200 -28800 0 PST}
|
||||
{-147880800 -25200 1 PDT}
|
||||
{-147884400 -25200 1 PDT}
|
||||
{-131554800 -28800 0 PST}
|
||||
{-116431200 -25200 1 PDT}
|
||||
{-116434800 -25200 1 PDT}
|
||||
{-100105200 -28800 0 PST}
|
||||
{-94665600 -28800 0 PST}
|
||||
{-84376800 -25200 1 PDT}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Pangnirtung) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-1546300800 -14400 0 AST}
|
||||
{-880221600 -10800 1 AWT}
|
||||
{-769395600 -10800 1 APT}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Rankin_Inlet) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-410227200 -21600 0 CST}
|
||||
{-147895200 -14400 1 CDDT}
|
||||
{-131565600 -21600 0 CST}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
|
||||
set TZData(:America/Resolute) {
|
||||
{-9223372036854775808 0 0 zzz}
|
||||
{-9223372036854775808 0 0 -00}
|
||||
{-704937600 -21600 0 CST}
|
||||
{-147895200 -14400 1 CDDT}
|
||||
{-131565600 -21600 0 CST}
|
||||
|
||||
@@ -14,19 +14,19 @@ set TZData(:America/Tijuana) {
|
||||
{-686073600 -25200 1 PDT}
|
||||
{-661539600 -28800 0 PST}
|
||||
{-504892800 -28800 0 PST}
|
||||
{-495036000 -25200 1 PDT}
|
||||
{-495039600 -25200 1 PDT}
|
||||
{-481734000 -28800 0 PST}
|
||||
{-463586400 -25200 1 PDT}
|
||||
{-463590000 -25200 1 PDT}
|
||||
{-450284400 -28800 0 PST}
|
||||
{-431532000 -25200 1 PDT}
|
||||
{-431535600 -25200 1 PDT}
|
||||
{-418230000 -28800 0 PST}
|
||||
{-400082400 -25200 1 PDT}
|
||||
{-400086000 -25200 1 PDT}
|
||||
{-386780400 -28800 0 PST}
|
||||
{-368632800 -25200 1 PDT}
|
||||
{-368636400 -25200 1 PDT}
|
||||
{-355330800 -28800 0 PST}
|
||||
{-337183200 -25200 1 PDT}
|
||||
{-337186800 -25200 1 PDT}
|
||||
{-323881200 -28800 0 PST}
|
||||
{-305733600 -25200 1 PDT}
|
||||
{-305737200 -25200 1 PDT}
|
||||
{-292431600 -28800 0 PST}
|
||||
{-283968000 -28800 0 PST}
|
||||
{189331200 -28800 0 PST}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user