Compare commits

...
Author SHA1 Message Date
dgp 38a14b1f4f merge 8.7 2018-04-26 18:19:42 +00:00
jan.nijtmans 9e733498f1 Update test-cases, so they are selected or not for -DTCL_UTF_MAX=6. Now all relevant test-cases pass for TCL_UTF_MAX=6 builds on UNIX (but not yet on Windows)! 2018-04-26 08:32:19 +00:00
dgp 859bcc9f86 merge 8.6 2018-04-25 11:48:43 +00:00
dgp c876decde3 Doc typo fix from Andy Goth. 2018-04-25 11:48:14 +00:00
dgp fec8aee1a1 Merge 8.6 (bug-fix and test-case for Tcl_UtfAtIndex with TCL_UTF_MAX=4)
((Replacement checkin for earlier attempt with botched timestamp))
2018-04-24 13:45:57 +00:00
jan.nijtmans 4519681dcd Bug-fix in Tcl_UtfAtIndex (for TCL_UTF_MAX=4 only). With test-case (in "string totitle") demonstrating the bug. 2018-04-23 23:23:00 +00:00
jan.nijtmans 27c2e432b5 Some better surrogate handling in encodings. Not spotted before ... 2018-04-23 15:06:40 +00:00
jan.nijtmans 9acb063268 Add some state to encodings, so we can do better surrogate handling for TCL_UTF_MAX >= 4. Backported from TIP #389. 2018-04-23 14:56:44 +00:00
dgp 5e3c1650cb merge 8.7 2018-04-23 13:51:57 +00:00
dgp 523d6ea42c Dup test name. 2018-04-23 13:51:05 +00:00
bll 95f2469359 Rework 'array for' to pass the arrayNameObj to the NRE routines
rather than saving it in the ArraySearch structure (which will
not work).
Create ArrayPopulateSearch to consolidate duplicate code.
2018-04-23 12:58:41 +00:00
dgp 6d8afefe93 Add a test for the compiled pathway. 2018-04-22 23:16:29 +00:00
dgp 82bb26a278 Candidate fix for [e87bcf819f]. Makes sure the unset of a scalar variable
linked to an array element terminates searches on that array.
In order to accomplish this, some deep revisions in Var handling were done
and new routine "Var * TclArrayContaining(Var *varPtr)" was created to return
the (Var *) of the array that contains the (Var *) varPtr argument when it
is an array element. Callers must verify the argument.

The only code that was unhappy with these deep revisions was the
varname method of TclOO, but revising it to the new situation was not too
difficult. Arguably the code is better now, if a bit uglier and fragile to
further deep Var tinkering.

Second party review would be a good idea, as well as opinions on whether
a backport to 8.6.* is warranted to fix corresponding bugs in the array
enumeration suite of commands.
2018-04-22 23:09:47 +00:00
dgp dc6bc431e9 merge 8.6 2018-04-22 13:27:45 +00:00
dgp 8e06fd796b [46a2410650] compiled [unset] was bypassing cleanup of active array search.
Overdue thanks to Andy Goth for tests and report.
2018-04-22 13:22:20 +00:00
dgp ae76fbd559 DeleteArray has only one caller. It is called on the "dummy" variable
that is created during unset, and which cannot be reached by resolving
any name. It cannot have VAR_SEARCH_ACTIVE set because the sole thing that
sets that flag is an [array startsearch] applied to a named variable.
2018-04-20 20:17:17 +00:00
dgp 24d501cb0d TIP 421 Implementation. 2018-04-20 16:02:47 +00:00
jan.nijtmans ca5638e01f TIP #389 implementation. 2018-04-20 10:16:31 +00:00
jan.nijtmans 1734eed89f Slightly improved (more fail-safe) surrogate handling for TCL_UTF_MAX>3. Backported from latest TIP 389 implementation. (to be used for androwish) 2018-04-19 22:29:00 +00:00
dgp 5c2ea0542f Adapt [array for] to use the refactored routines. 2018-04-19 17:46:37 +00:00
dgp 346eec1892 merge 8.7 2018-04-19 17:40:10 +00:00
oehhar ddb7bbe66c correct msgcat test numbering for section util from 15.x (used twice) to 18.x 2018-04-19 11:48:28 +00:00
dgp 567fb6cc27 merge 8.6 2018-04-19 02:45:38 +00:00
dgp 75bd116527 Fold TclArraySet() into its only caller. tclEnv.c no longer calls it 2018-04-19 02:01:29 +00:00
dgp 7ac6487eda merge 8.5 2018-04-19 01:41:13 +00:00
dgp df94eecf11 An [array set] from a dict can only take shortcuts when the dict is "pure",
that is, has no string rep.
2018-04-19 01:39:38 +00:00
dgp 8d0340e39e Refactor error reporting when value is not an expected array variable name. 2018-04-18 23:41:48 +00:00
dgp 61f580bd36 Refactor to bring the test for existence of an array variable into
LocateArray().
2018-04-18 23:31:07 +00:00
dgp 08c1a8dd34 cleanup of refactor 2018-04-18 21:03:53 +00:00
dgp fb91d4b68b Refactor the common operations of looking up and checking traces on an array
variable into a single routine LocateArray().
2018-04-18 19:21:33 +00:00
oehhar 327595170b http::geturl now returns full error stack information if the initial socket command fails Ticket [ff82755e15] 2018-04-18 11:59:57 +00:00
jan.nijtmans 28ac086633 Slightly better unmatched-surrogates handling. Unmatched High surrogates will still be silently removed, but Unmatched Low surrogates will pass through as-is now. Inspired by Kevin Kenny's remarks. Thanks! 2018-04-17 21:49:00 +00:00
dgp 6b8039a952 Refactor array trace handling into a common routine TclCheckArrayTraces(). 2018-04-17 20:29:02 +00:00
dgp 62ea5e49a1 Array trace firing must come before argument checking might raise error. 2018-04-17 19:14:01 +00:00
dgp 5dff80f2fe Gentler fallback. 2018-04-17 18:54:36 +00:00
dgp f316d7539c [array set] must fire array traces. Don't disrupt that by reporting argument
errors too early.
2018-04-17 18:34:41 +00:00
dgp 31a291920a merge 8.6 2018-04-17 14:39:12 +00:00
dgp 05845fbe5f merge 8.5 2018-04-17 14:38:28 +00:00
dgp 80e5aed49e Restore build success to the TCL_REMOVE_OBSOLETE_TRACES configuration. 2018-04-17 14:32:30 +00:00
dgp 47fc4afd86 Satisfy test var-23.14 2018-04-17 11:11:35 +00:00
dgp 08d704bbb1 Test of shimmer segfault. 2018-04-17 03:48:47 +00:00
dgp 2d5be38603 Memleak fix from Brad Lanam. 2018-04-16 14:15:22 +00:00
dgp 994ba283c9 merge 8.7 2018-04-11 16:17:44 +00:00
dgp 019016e71a merge 8.7 2018-04-11 12:45:01 +00:00
dgp d525fa6f68 merge 8.7 2018-03-30 21:10:04 +00:00
dgp c120622483 merge 8.7 2018-03-15 14:37:55 +00:00
dgp a8ffcb0b4c merge 8.7 2018-03-15 14:18:39 +00:00
dgp 9b9635f82e merge 8.7 2018-03-11 22:34:51 +00:00
dgp d660f467cb merge 8.7 2018-03-10 16:03:02 +00:00
bll a735b5d3ac array for:
Add missing ObjCmdProc wrapper around the NR proc.
2018-03-06 18:42:25 +00:00
bll d2d193de11 array for: updated documentation: value variable is not optional, add
specifics about when array for terminates.
2018-03-06 18:21:34 +00:00
bll 77d58c5993 tip-421: array for:
a) Fix bug starting search (name not set).
  b) Fix error message for array change on iteration.
2018-03-06 17:19:40 +00:00
dgp 6bb961ffc6 merge 8.7 2018-03-06 13:46:24 +00:00
dgp 96e07632d9 merge 8.7 2018-03-05 17:41:24 +00:00
dgp b1e6769ef3 Rebase TIP 421 implementation to core-8-branch (8.7). var-23.1[01] segfaults! 2018-03-05 16:49:07 +00:00
jan.nijtmans d98ee54c8d merge core-8-branch.
Also add range checks to Tcl_GetUniChar() and Tcl_Range(), as suggested by Don Porter.
2018-01-26 16:20:29 +00:00
jan.nijtmans 6904b0f77f merge core-8-branch 2018-01-23 15:51:00 +00:00
dgp bed15f1d81 merge 8.7 2018-01-18 14:05:07 +00:00
jan.nijtmans c8219a9a29 Fix [11ae2be95d]: tip-389 branch: string range errors with code points greater than U+FFFF 2018-01-12 10:03:58 +00:00
jan.nijtmans 27e7f096b2 merge core-8-branch. Remove left-over debugging code. Test-case string-5.21 still fails. 2018-01-11 15:59:17 +00:00
jan.nijtmans eb3422673f Add test-cases for bug [11ae2be95dac9417], and make a start fixing it. Almost works. 2018-01-11 14:11:38 +00:00
jan.nijtmans 2a8fce94bd merge core-8-branch 2018-01-10 14:03:26 +00:00
jan.nijtmans 04d3db5592 Don't use TclUtfToUniChar here: it doesn't give any advantage over Tcl_UtfToUniChar 2018-01-10 09:32:51 +00:00
jan.nijtmans 3889f63614 merge core-8-branch 2018-01-10 08:27:03 +00:00
jan.nijtmans 815ebb9a0f merge core-8-branch 2017-12-28 21:17:22 +00:00
jan.nijtmans 7a13be75b6 merge core-8-branch 2017-12-28 20:29:10 +00:00
jan.nijtmans e71f41cf89 merge core-8-branch.
Re-implement Tcl_WinTCharToUtf/Tcl_WinUtfToTChar using only win32 API.
2017-12-27 20:24:13 +00:00
jan.nijtmans 9977b3e79c merge core-8-branch 2017-12-23 20:18:01 +00:00
jan.nijtmans 9b47336cbd merge core-8-branch 2017-12-01 11:33:27 +00:00
jan.nijtmans 7ecb945209 Merge core-8-branch. Also, use a different value for TCL_STUB_MAGIC when TCL_UTF_MAX>4. 2017-11-29 11:49:49 +00:00
jan.nijtmans 03c66864aa Fix [8e1e31eac0fd6b6c4452bc108a98ab08c6b64588|8e1e31eac0]: lsort treats NUL chars strangely 2017-11-29 09:49:31 +00:00
jan.nijtmans 3af16acbcb Treat invalid UTF-8 characters in the range 0x80-0x9F as cp1252: See [https://en.wikipedia.org/wiki/UTF-8]. To be added to TIP #389 2017-11-29 08:59:49 +00:00
jan.nijtmans eef0b72b5e merge core-8-branch 2017-11-29 08:41:05 +00:00
jan.nijtmans 61536390c5 Fix executable flags 2017-11-20 13:05:36 +00:00
jan.nijtmans 3a7618f91e merge core-8-branch 2017-11-20 12:58:54 +00:00
jan.nijtmans 2ea8f0fe98 merge core-8-branch. Fix some Tcl_UniChar initialization, in case TCL_UTF_MAX == 4 2017-11-17 16:08:49 +00:00
jan.nijtmans b832920adb merge core-8-branch 2017-11-17 15:34:01 +00:00
jan.nijtmans dfbe0053d1 merge core-8-branch 2017-11-09 16:07:06 +00:00
jan.nijtmans 48b529209c Somewhat simplified implementation of TIP #389, in which the "string length" if characters > U+FFFF is considered to be 2, not 1. 2017-11-07 12:15:30 +00:00
fvogel d8cae66217 Fix typo in set-old.test 2017-10-25 17:31:09 +00:00
fvogel 40ce2eccbc 'array for' implementation (TIP #421) from Brad Lanam 2017-10-24 21:24:07 +00:00
29 changed files with 1194 additions and 652 deletions
+3 -2
View File
@@ -37,7 +37,7 @@ Tcl_UniChar *
Tcl_UniChar *
\fBTcl_GetUnicode\fR(\fIobjPtr\fR)
.sp
Tcl_UniChar
int
\fBTcl_GetUniChar\fR(\fIobjPtr, index\fR)
.sp
int
@@ -204,7 +204,8 @@ where the caller does not need the length of the unicode string
representation.
.PP
\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
value's Unicode representation.
value's Unicode representation. If the index is out of range or
it references a low surrogate preceded by a high surrogate, it returns -1;
.PP
\fBTcl_GetRange\fR returns a newly created value comprised of the
characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
+3 -3
View File
@@ -13,13 +13,13 @@ Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_UniChar
int
\fBTcl_UniCharToUpper\fR(\fIch\fR)
.sp
Tcl_UniChar
int
\fBTcl_UniCharToLower\fR(\fIch\fR)
.sp
Tcl_UniChar
int
\fBTcl_UniCharToTitle\fR(\fIch\fR)
.sp
int
+4 -1
View File
@@ -63,7 +63,7 @@ const char *
const char *
\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
.sp
Tcl_UniChar
int
\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
.sp
const char *
@@ -140,6 +140,9 @@ number of bytes read from \fIsrc\fR. The caller must ensure that the
source buffer is long enough such that this routine does not run off the
end and dereference non-existent or random memory; if the source buffer
is known to be null-terminated, this will not happen. If the input is
a byte in the range 0x80 - 0x9F, \fBTcl_UtfToUniChar\fR assumes the
cp1252 encoding, stores the corresponding Tcl_UniChar in \fI*chPtr\fR
and returns 1. If the input is otherwise
not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
0x00ff and return 1.
+9
View File
@@ -47,6 +47,15 @@ been the return value from a previous invocation of
Returns 1 if \fIarrayName\fR is an array variable, 0 if there
is no variable by that name or if it is a scalar variable.
.TP
\fBarray for {\fIkeyVariable valueVariable\fB} \fIarrayName body\fP
The first argument is a two element list of variable names for the
key and value of each entry in the array. The second argument is the
array name to iterate over. The third argument is the body to execute
for each key and value returned.
The ordering of the returned keys is undefined.
If an array element is deleted or a new array element is inserted during
the \fIarray for\fP process, the command will terminate with an error.
.TP
\fBarray get \fIarrayName\fR ?\fIpattern\fR?
Returns a list containing pairs of elements. The first
element in each pair is the name of an element in \fIarrayName\fR
+1 -1
View File
@@ -50,7 +50,7 @@ being constructed. Within the constructor, the \fBnext\fR command should be
used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
string, the constructor will be deleted.
.TP
\fBdeletemethod\fI name\fR ?\fIname ...\fR
\fBdeletemethod\fI name\fR ?\fIname ...\fR?
.
This deletes each of the methods called \fIname\fR from a class. The methods
must have previously existed in that class. Does not affect the superclasses
+5 -5
View File
@@ -1145,16 +1145,16 @@ declare 319 {
Tcl_QueuePosition position)
}
declare 320 {
Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index)
int Tcl_UniCharAtIndex(const char *src, int index)
}
declare 321 {
Tcl_UniChar Tcl_UniCharToLower(int ch)
int Tcl_UniCharToLower(int ch)
}
declare 322 {
Tcl_UniChar Tcl_UniCharToTitle(int ch)
int Tcl_UniCharToTitle(int ch)
}
declare 323 {
Tcl_UniChar Tcl_UniCharToUpper(int ch)
int Tcl_UniCharToUpper(int ch)
}
declare 324 {
int Tcl_UniCharToUtf(int ch, char *buf)
@@ -1348,7 +1348,7 @@ declare 380 {
int Tcl_GetCharLength(Tcl_Obj *objPtr)
}
declare 381 {
Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
int Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
}
declare 382 {
Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr)
+3 -3
View File
@@ -2155,7 +2155,7 @@ typedef struct Tcl_EncodingType {
*/
#ifndef TCL_UTF_MAX
#define TCL_UTF_MAX 3
#define TCL_UTF_MAX 4
#endif
/*
@@ -2345,10 +2345,10 @@ 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.
* stubs tables. If TCL_UTF_MAX>4 use a different value.
*/
#define TCL_STUB_MAGIC ((int) 0xFCA3BACF)
#define TCL_STUB_MAGIC ((int) 0xFCA3BACF + (TCL_UTF_MAX>4))
/*
* The following function is required to be defined in all stubs aware
+10 -6
View File
@@ -491,7 +491,7 @@ Tcl_RegsubObjCmd(
Tcl_RegExp regExpr;
Tcl_RegExpInfo info;
Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec = 0, *wend;
static const char *const options[] = {
"-all", "-command", "-expanded", "-line",
@@ -1220,7 +1220,7 @@ Tcl_SplitObjCmd(
len = TclUtfToUniChar(stringPtr, &ch);
fullchar = ch;
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
if (!len) {
len += TclUtfToUniChar(stringPtr, &ch);
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
@@ -1419,7 +1419,7 @@ StringIndexCmd(
}
/*
* Get the char length to calulate what 'end' means.
* Get the char length to calculate what 'end' means.
*/
length = Tcl_GetCharLength(objv[1]);
@@ -1428,7 +1428,11 @@ StringIndexCmd(
}
if ((index >= 0) && (index < length)) {
Tcl_UniChar ch = Tcl_GetUniChar(objv[1], index);
int ch = Tcl_GetUniChar(objv[1], index);
if (ch == -1) {
return TCL_OK;
}
/*
* If we have a ByteArray object, we're careful to generate a new
@@ -1440,7 +1444,7 @@ StringIndexCmd(
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
} else {
char buf[TCL_UTF_MAX];
char buf[4];
length = Tcl_UniCharToUtf(ch, buf);
Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
@@ -1803,7 +1807,7 @@ StringIsCmd(
int fullchar;
length2 = TclUtfToUniChar(string1, &ch);
fullchar = ch;
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
if (!length2) {
length2 = TclUtfToUniChar(string1, &ch);
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
+15 -3
View File
@@ -322,11 +322,22 @@ TclCompileArraySetCmd(
*/
if (isDataValid && !isDataEven) {
/* Abandon custom compile and let invocation raise the error */
code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
goto done;
/*
* We used to compile to the bytecode that would throw the error,
* but that was wrong because it would not invoke the array trace
* on the variable.
*
PushStringLiteral(envPtr, "list must have an even number of elements");
PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR, envPtr);
TclEmitInt4( 0, envPtr);
goto done;
*
*/
}
/*
@@ -404,6 +415,10 @@ TclCompileArraySetCmd(
* Start issuing instructions to write to the array.
*/
TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
CompileWord(envPtr, dataTokenPtr, interp, 2);
if (!isDataLiteral || !isDataValid) {
/*
@@ -428,9 +443,6 @@ TclCompileArraySetCmd(
TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
}
TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr);
offsetBack = CurrentOffset(envPtr);
Emit14Inst( INST_LOAD_SCALAR, keyVar, envPtr);
+10 -10
View File
@@ -962,13 +962,13 @@ EXTERN void Tcl_ThreadAlert(Tcl_ThreadId threadId);
EXTERN void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId,
Tcl_Event *evPtr, Tcl_QueuePosition position);
/* 320 */
EXTERN Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index);
EXTERN int Tcl_UniCharAtIndex(const char *src, int index);
/* 321 */
EXTERN Tcl_UniChar Tcl_UniCharToLower(int ch);
EXTERN int Tcl_UniCharToLower(int ch);
/* 322 */
EXTERN Tcl_UniChar Tcl_UniCharToTitle(int ch);
EXTERN int Tcl_UniCharToTitle(int ch);
/* 323 */
EXTERN Tcl_UniChar Tcl_UniCharToUpper(int ch);
EXTERN int Tcl_UniCharToUpper(int ch);
/* 324 */
EXTERN int Tcl_UniCharToUtf(int ch, char *buf);
/* 325 */
@@ -1123,7 +1123,7 @@ EXTERN void Tcl_SetUnicodeObj(Tcl_Obj *objPtr,
/* 380 */
EXTERN int Tcl_GetCharLength(Tcl_Obj *objPtr);
/* 381 */
EXTERN Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index);
EXTERN int Tcl_GetUniChar(Tcl_Obj *objPtr, int index);
/* 382 */
EXTERN Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr);
/* 383 */
@@ -2193,10 +2193,10 @@ typedef struct TclStubs {
Tcl_Obj * (*tcl_SetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 317 */
void (*tcl_ThreadAlert) (Tcl_ThreadId threadId); /* 318 */
void (*tcl_ThreadQueueEvent) (Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 319 */
Tcl_UniChar (*tcl_UniCharAtIndex) (const char *src, int index); /* 320 */
Tcl_UniChar (*tcl_UniCharToLower) (int ch); /* 321 */
Tcl_UniChar (*tcl_UniCharToTitle) (int ch); /* 322 */
Tcl_UniChar (*tcl_UniCharToUpper) (int ch); /* 323 */
int (*tcl_UniCharAtIndex) (const char *src, int index); /* 320 */
int (*tcl_UniCharToLower) (int ch); /* 321 */
int (*tcl_UniCharToTitle) (int ch); /* 322 */
int (*tcl_UniCharToUpper) (int ch); /* 323 */
int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */
const char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */
int (*tcl_UtfCharComplete) (const char *src, int length); /* 326 */
@@ -2254,7 +2254,7 @@ typedef struct TclStubs {
Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, int numChars); /* 378 */
void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int numChars); /* 379 */
int (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 380 */
Tcl_UniChar (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */
int (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */
Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */
Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, int first, int last); /* 383 */
void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int length); /* 384 */
+21 -4
View File
@@ -2359,8 +2359,15 @@ UtfToUtfProc(
src += 1;
dst += Tcl_UniCharToUtf(*chPtr, dst);
} else {
src += TclUtfToUniChar(src, chPtr);
int len = TclUtfToUniChar(src, chPtr);
src += len;
dst += Tcl_UniCharToUtf(*chPtr, dst);
#if TCL_UTF_MAX <= 4
if (!len) {
src += TclUtfToUniChar(src, chPtr);
dst += Tcl_UniCharToUtf(*chPtr, dst);
}
#endif
}
}
@@ -2766,7 +2773,7 @@ TableFromUtfProc(
}
len = TclUtfToUniChar(src, &ch);
#if TCL_UTF_MAX > 3
#if TCL_UTF_MAX > 4
/*
* This prevents a crash condition. More evaluation is required for
* full support of int Tcl_UniChar. [Bug 1004065]
@@ -2775,6 +2782,10 @@ TableFromUtfProc(
if (ch & 0xffff0000) {
word = 0;
} else
#else
if (!len) {
word = 0;
} else
#endif
word = fromUnicode[(ch >> 8)][ch & 0xff];
@@ -2972,12 +2983,18 @@ Iso88591FromUtfProc(
* Check for illegal characters.
*/
if (ch > 0xff) {
if (ch > 0xff
#if TCL_UTF_MAX <= 4
|| !len
#endif
) {
if (flags & TCL_ENCODING_STOPONERROR) {
result = TCL_CONVERT_UNKNOWN;
break;
}
#if TCL_UTF_MAX <= 4
if (!len) len = 4;
#endif
/*
* Plunge on, using '?' as a fallback character.
*/
+11 -15
View File
@@ -3890,7 +3890,8 @@ TEBCresume(
}
TRACE(("%s %u \"%.30s\" => ",
(flags ? "normal" : "noerr"), opnd, O2S(part2Ptr)));
if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)) {
if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)
&& !(arrayPtr->flags & VAR_SEARCH_ACTIVE)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (varPtr && TclIsVarDirectUnsettable(varPtr)) {
/*
@@ -4015,17 +4016,12 @@ TEBCresume(
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/0, /*createPart2*/0, &arrayPtr);
doArrayExists:
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
DECACHE_STACK_INFO();
result = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
NULL, (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|
TCL_GLOBAL_ONLY|TCL_TRACE_ARRAY), 1, opnd);
CACHE_STACK_INFO();
if (result == TCL_ERROR) {
TRACE_ERROR(interp);
goto gotError;
}
DECACHE_STACK_INFO();
result = TclCheckArrayTraces(interp, varPtr, arrayPtr, part1Ptr, opnd);
CACHE_STACK_INFO();
if (result == TCL_ERROR) {
TRACE_ERROR(interp);
goto gotError;
}
if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
objResultPtr = TCONST(1);
@@ -5297,8 +5293,8 @@ TEBCresume(
objResultPtr = Tcl_NewStringObj((const char *)
valuePtr->bytes+index, 1);
} else {
char buf[TCL_UTF_MAX];
Tcl_UniChar ch = Tcl_GetUniChar(valuePtr, index);
char buf[4];
int ch = Tcl_GetUniChar(valuePtr, index);
/*
* This could be: Tcl_NewUnicodeObj((const Tcl_UniChar *)&ch, 1)
@@ -5306,7 +5302,7 @@ TEBCresume(
* practical use.
*/
length = Tcl_UniCharToUtf(ch, buf);
length = (ch != -1) ? Tcl_UniCharToUtf(ch, buf) : 0;
objResultPtr = Tcl_NewStringObj(buf, length);
}
+4 -2
View File
@@ -853,6 +853,8 @@ typedef struct VarInHash {
#define VarHashRefCount(varPtr) \
((VarInHash *) (varPtr))->refCount
MODULE_SCOPE Var * TclArrayContaining(Var *varPtr);
/*
* Macros for direct variable access by TEBC.
*/
@@ -2889,8 +2891,6 @@ MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp,
CmdFrame *cfPtr);
MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj,
CmdFrame **cfPtrPtr, int *wordPtr);
MODULE_SCOPE int TclArraySet(Tcl_Interp *interp,
Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj);
MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum);
MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string,
int strLen, const unsigned char *pattern,
@@ -2898,6 +2898,8 @@ MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string,
MODULE_SCOPE double TclCeil(const mp_int *a);
MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan);
MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan);
MODULE_SCOPE int TclCheckArrayTraces(Tcl_Interp *interp, Var *varPtr,
Var *arrayPtr, Tcl_Obj *name, int index);
MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp,
const char *value);
MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
+5 -18
View File
@@ -728,27 +728,14 @@ TclOO_Object_VarName(
*/
varNamePtr = Tcl_NewObj();
if (aryVar != NULL) {
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
if (TclIsVarArrayElement(varPtr)) {
aryVar = TclArrayContaining(varPtr);
Tcl_GetVariableFullName(interp, (Tcl_Var) aryVar, varNamePtr);
/*
* WARNING! This code pokes inside the implementation of hash tables!
*/
hPtr = Tcl_FirstHashEntry((Tcl_HashTable *) aryVar->value.tablePtr,
&search);
while (hPtr != NULL) {
if (varPtr == Tcl_GetHashValue(hPtr)) {
Tcl_AppendToObj(varNamePtr, "(", -1);
Tcl_AppendObjToObj(varNamePtr, hPtr->key.objPtr);
Tcl_AppendToObj(varNamePtr, ")", -1);
break;
}
hPtr = Tcl_NextHashEntry(&search);
}
Tcl_AppendToObj(varNamePtr, "(", -1);
Tcl_AppendObjToObj(varNamePtr, ((VarInHash *)varPtr)->entry.key.objPtr);
Tcl_AppendToObj(varNamePtr, ")", -1);
} else {
Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr);
}
+59 -11
View File
@@ -460,8 +460,9 @@ Tcl_GetCharLength(
*
* Tcl_GetUniChar --
*
* Get the index'th Unicode character from the String object. The index
* is assumed to be in the appropriate range.
* Get the index'th Unicode character from the String object. If index
* is out of range or it references a low surrogate preceded by a high
* surrogate, the result = -1;
*
* Results:
* Returns the index'th Unicode character in the Object.
@@ -472,13 +473,18 @@ Tcl_GetCharLength(
*----------------------------------------------------------------------
*/
Tcl_UniChar
int
Tcl_GetUniChar(
Tcl_Obj *objPtr, /* The object to get the Unicode charater
* from. */
int index) /* Get the index'th Unicode character. */
{
String *stringPtr;
int ch, length;
if (index < 0) {
return -1;
}
/*
* Optimize the case where we're really dealing with a bytearray object
@@ -486,9 +492,12 @@ Tcl_GetUniChar(
*/
if (TclIsPureByteArray(objPtr)) {
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, NULL);
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
if (index >= length) {
return -1;
}
return (Tcl_UniChar) bytes[index];
return (int) bytes[index];
}
/*
@@ -512,7 +521,26 @@ Tcl_GetUniChar(
FillUnicodeRep(objPtr);
stringPtr = GET_STRING(objPtr);
}
return stringPtr->unicode[index];
if (index >= stringPtr->numChars) {
return -1;
}
ch = stringPtr->unicode[index];
#if TCL_UTF_MAX <= 4
/* See: bug [11ae2be95dac9417] */
if ((ch&0xF800) == 0xD800) {
if (ch&0x400) {
if ((index > 0) && ((stringPtr->unicode[index-1]&0xFC00) == 0xD800)) {
ch = -1; /* low surrogate preceded by high surrogate */
}
} else if ((++index < stringPtr->numChars)
&& ((stringPtr->unicode[index]&0xFC00) == 0xDC00)) {
/* high surrogate followed by low surrogate */
ch = (((ch & 0x3FF) << 10) | (stringPtr->unicode[index] & 0x3FF)) + 0x10000;
}
}
#endif
return ch;
}
/*
@@ -612,15 +640,24 @@ Tcl_GetRange(
{
Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */
String *stringPtr;
int length;
if (first < 0) {
first = 0;
}
/*
* Optimize the case where we're really dealing with a bytearray object
* we don't need to convert to a string to perform the substring operation.
*/
if (TclIsPureByteArray(objPtr)) {
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, NULL);
unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length);
if (last >= length) {
last = length - 1;
}
if (last < first) {
return Tcl_NewObj();
}
return Tcl_NewByteArrayObj(bytes+first, last-first+1);
}
@@ -640,6 +677,12 @@ Tcl_GetRange(
TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length);
}
if (stringPtr->numChars == objPtr->length) {
if (last >= stringPtr->numChars) {
last = stringPtr->numChars - 1;
}
if (last < first) {
return Tcl_NewObj();
}
newObjPtr = Tcl_NewStringObj(objPtr->bytes + first, last-first+1);
/*
@@ -654,8 +697,13 @@ Tcl_GetRange(
FillUnicodeRep(objPtr);
stringPtr = GET_STRING(objPtr);
}
#if TCL_UTF_MAX == 4
if (last > stringPtr->numChars) {
last = stringPtr->numChars;
}
if (last < first) {
return Tcl_NewObj();
}
#if TCL_UTF_MAX <= 4
/* See: bug [11ae2be95dac9417] */
if ((first>0) && ((stringPtr->unicode[first]&0xFC00) == 0xDC00)
&& ((stringPtr->unicode[first-1]&0xFC00) == 0xD800)) {
@@ -1930,7 +1978,7 @@ Tcl_AppendFormatToObj(
}
break;
case 'c': {
char buf[TCL_UTF_MAX];
char buf[4];
int code, length;
if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) {
+52 -1
View File
@@ -191,8 +191,10 @@ Tcl_TraceObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
int optionIndex;
#ifndef TCL_REMOVE_OBSOLETE_TRACES
const char *name;
const char *flagOps, *p;
#endif
/* Main sub commands to 'trace' */
static const char *const traceOptions[] = {
"add", "info", "remove",
@@ -365,12 +367,14 @@ Tcl_TraceObjCmd(
}
return TCL_OK;
#ifndef TCL_REMOVE_OBSOLETE_TRACES
badVarOps:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad operations \"%s\": should be one or more of rwua",
flagOps));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "BADOPS", NULL);
return TCL_ERROR;
#endif
}
/*
@@ -912,9 +916,11 @@ TraceVariableObjCmd(
+ 1 + length);
ctvarPtr->traceCmdInfo.flags = flags;
#ifndef TCL_REMOVE_OBSOLETE_TRACES
if (objv[0] == NULL) {
ctvarPtr->traceCmdInfo.flags |= TCL_TRACE_OLD_STYLE;
}
#endif
ctvarPtr->traceCmdInfo.length = length;
flags |= TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT;
memcpy(ctvarPtr->traceCmdInfo.command, command, length+1);
@@ -939,7 +945,11 @@ TraceVariableObjCmd(
TraceVarInfo *tvarPtr = clientData;
if ((tvarPtr->length == length)
&& ((tvarPtr->flags & ~TCL_TRACE_OLD_STYLE)==flags)
&& ((tvarPtr->flags
#ifndef TCL_REMOVE_OBSOLETE_TRACES
& ~TCL_TRACE_OLD_STYLE
#endif
)==flags)
&& (strncmp(command, tvarPtr->command,
(size_t) length) == 0)) {
Tcl_UntraceVar2(interp, name, NULL,
@@ -2465,6 +2475,47 @@ TclVarTraceExists(
return varPtr;
}
/*
*----------------------------------------------------------------------
*
* TclCheckArrayTraces --
*
* This function is invoked to when we operate on an array variable,
* to allow any array traces to fire.
*
* Results:
* Returns TCL_OK to indicate normal operation. Returns TCL_ERROR if
* invocation of a trace function indicated an error. When TCL_ERROR is
* returned, then error information is left in interp.
*
* Side effects:
* Almost anything can happen, depending on trace; this function itself
* doesn't have any side effects.
*
*----------------------------------------------------------------------
*/
int
TclCheckArrayTraces(
Tcl_Interp *interp,
Var *varPtr,
Var *arrayPtr,
Tcl_Obj *name,
int index)
{
int code = TCL_OK;
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
Interp *iPtr = (Interp *)interp;
code = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, name, NULL,
(TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY| TCL_TRACE_ARRAY),
/* leaveErrMsg */ 1, index);
}
return code;
}
/*
*----------------------------------------------------------------------
*
+141 -95
View File
@@ -98,11 +98,9 @@ TclUtfCount(
if (ch <= 0x7FF) {
return 2;
}
#if TCL_UTF_MAX > 3
if (((unsigned)(ch - 0x10000) <= 0xFFFFF)) {
return 4;
}
#endif
return 3;
}
@@ -131,7 +129,7 @@ Tcl_UniCharToUtf(
char *buf) /* Buffer in which the UTF-8 representation of
* the Tcl_UniChar is stored. Buffer must be
* large enough to hold the UTF-8 character
* (at most TCL_UTF_MAX bytes). */
* (at most 4 bytes). */
{
if ((unsigned)(ch - 1) < (UNICODE_SELF - 1)) {
buf[0] = (char) ch;
@@ -144,27 +142,30 @@ Tcl_UniCharToUtf(
return 2;
}
if (ch <= 0xFFFF) {
#if TCL_UTF_MAX == 4
if ((ch & 0xF800) == 0xD800) {
if (ch & 0x0400) {
/* Low surrogate */
buf[3] = (char) ((ch | 0x80) & 0xBF);
buf[2] |= (char) (((ch >> 6) | 0x80) & 0x8F);
return 4;
if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
&& ((buf[2] & 0xCF) == 0)) {
/* Previous Tcl_UniChar was a High surrogate, so combine */
buf[3] = (char) ((ch & 0x3F) | 0x80);
buf[2] |= (char) (((ch >> 6) & 0x0F) | 0x80);
return 4;
}
/* Previous Tcl_UniChar was not a High surrogate, so just output */
} else {
/* High surrogate */
ch += 0x40;
buf[2] = (char) (((ch << 4) | 0x80) & 0xB0);
buf[1] = (char) (((ch >> 2) | 0x80) & 0xBF);
buf[0] = (char) (((ch >> 8) | 0xF0) & 0xF7);
/* Fill buffer with specific 3-byte (invalid) byte combination,
so following Low surrogate can recognize it and combine */
buf[2] = (char) ((ch << 4) & 0x30);
buf[1] = (char) (((ch >> 2) & 0x3F) | 0x80);
buf[0] = (char) (((ch >> 8) & 0x07) | 0xF0);
return 0;
}
}
#endif
goto three;
}
#if TCL_UTF_MAX > 3
if (ch <= 0x10FFFF) {
buf[3] = (char) ((ch | 0x80) & 0xBF);
buf[2] = (char) (((ch >> 6) | 0x80) & 0xBF);
@@ -172,7 +173,6 @@ Tcl_UniCharToUtf(
buf[0] = (char) ((ch >> 18) | 0xF0);
return 4;
}
#endif
}
ch = 0xFFFD;
@@ -214,12 +214,11 @@ Tcl_UniCharToUtfDString(
int oldLength;
/*
* UTF-8 string length in bytes will be <= Unicode string length *
* TCL_UTF_MAX.
* UTF-8 string length in bytes will be <= Unicode string length * 4.
*/
oldLength = Tcl_DStringLength(dsPtr);
Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * TCL_UTF_MAX);
Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * 4);
string = Tcl_DStringValue(dsPtr) + oldLength;
p = string;
@@ -268,6 +267,13 @@ Tcl_UniCharToUtfDString(
*---------------------------------------------------------------------------
*/
static const unsigned short cp1252[32] = {
0x20ac, 0x81, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F,
0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x2DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178
};
int
Tcl_UtfToUniChar(
register const char *src, /* The UTF-8 string. */
@@ -284,11 +290,17 @@ Tcl_UtfToUniChar(
if (byte < 0xC0) {
/*
* Handles properly formed UTF-8 characters between 0x01 and 0x7F.
* Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
* Treats naked trail bytes 0x80 to 0x9F as valid characters from
* the cp1252 table. See: <https://en.wikipedia.org/wiki/UTF-8>
* Also treats \0 and other naked trail bytes 0xA0 to 0xBF as valid
* characters representing themselves.
*/
*chPtr = (Tcl_UniChar) byte;
if ((unsigned)(byte-0x80) < (unsigned) 0x20) {
*chPtr = (Tcl_UniChar) cp1252[byte-0x80];
} else {
*chPtr = (Tcl_UniChar) byte;
}
return 1;
} else if (byte < 0xE0) {
if ((src[1] & 0xC0) == 0x80) {
@@ -329,17 +341,7 @@ Tcl_UtfToUniChar(
/*
* Four-byte-character lead byte followed by three trail bytes.
*/
#if TCL_UTF_MAX == 3
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)) - 0x10000;
if (byte & 0x100000) {
/* out of range, < 0x10000 or > 0x10ffff */
} else {
/* produce replacement character, and advance source pointer */
*chPtr = (Tcl_UniChar) 0xFFFD;
return 4;
}
#elif TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
Tcl_UniChar surrogate;
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
@@ -551,7 +553,7 @@ Tcl_UtfFindFirst(
while (1) {
len = TclUtfToUniChar(src, &find);
fullchar = find;
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
if (!len) {
len += TclUtfToUniChar(src, &find);
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
@@ -599,7 +601,7 @@ Tcl_UtfFindLast(
while (1) {
len = TclUtfToUniChar(src, &find);
fullchar = find;
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
if (!len) {
len += TclUtfToUniChar(src, &find);
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
@@ -642,7 +644,7 @@ Tcl_UtfNext(
Tcl_UniChar ch = 0;
int len = TclUtfToUniChar(src, &ch);
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
if (len == 0) {
len = TclUtfToUniChar(src, &ch);
}
@@ -717,17 +719,33 @@ Tcl_UtfPrev(
*---------------------------------------------------------------------------
*/
Tcl_UniChar
int
Tcl_UniCharAtIndex(
register const char *src, /* The UTF-8 string to dereference. */
register int index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
int fullchar = 0;
#if TCL_UTF_MAX <= 4
int len = 1;
#endif
while (index-- >= 0) {
#if TCL_UTF_MAX <= 4
src += (len = TclUtfToUniChar(src, &ch));
#else
src += TclUtfToUniChar(src, &ch);
#endif
}
return ch;
fullchar = ch;
#if TCL_UTF_MAX <= 4
if (!len) {
/* If last Tcl_UniChar was an upper surrogate, combine with lower surrogate */
(void)TclUtfToUniChar(src, &ch);
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
return fullchar;
}
/*
@@ -736,7 +754,9 @@ Tcl_UniCharAtIndex(
* Tcl_UtfAtIndex --
*
* Returns a pointer to the specified character (not byte) position in
* the UTF-8 string.
* the UTF-8 string. If TCL_UTF_MAX <= 4, characters > U+FFFF count as
* 2 positions, but then the pointer should never be placed between
* the two positions.
*
* Results:
* As above.
@@ -753,10 +773,18 @@ Tcl_UtfAtIndex(
register int index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
int len = 1;
while (index-- > 0) {
len = TclUtfToUniChar(src, &ch);
src += len;
}
#if TCL_UTF_MAX <= 4
if (!len) {
/* Index points at character following High Surrogate */
src += TclUtfToUniChar(src, &ch);
}
#endif
return src;
}
@@ -835,7 +863,8 @@ int
Tcl_UtfToUpper(
char *str) /* String to convert in place. */
{
Tcl_UniChar ch = 0, upChar;
Tcl_UniChar ch = 0;
int upChar;
char *src, *dst;
int bytes;
@@ -846,7 +875,16 @@ Tcl_UtfToUpper(
src = dst = str;
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
upChar = Tcl_UniCharToUpper(ch);
upChar = ch;
#if TCL_UTF_MAX <= 4
if (!bytes) {
/* TclUtfToUniChar only returns 0 for chars > 0xffff ! */
bytes = TclUtfToUniChar(src, &ch);
/* Combine surrogates */
upChar = (((upChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
upChar = Tcl_UniCharToUpper(upChar);
/*
* To keep badly formed Utf strings from getting inflated by the
@@ -888,7 +926,8 @@ int
Tcl_UtfToLower(
char *str) /* String to convert in place. */
{
Tcl_UniChar ch = 0, lowChar;
Tcl_UniChar ch = 0;
int lowChar;
char *src, *dst;
int bytes;
@@ -899,7 +938,16 @@ Tcl_UtfToLower(
src = dst = str;
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
lowChar = Tcl_UniCharToLower(ch);
lowChar = ch;
#if TCL_UTF_MAX <= 4
if (!bytes) {
/* TclUtfToUniChar only returns 0 for chars > 0xffff ! */
bytes = TclUtfToUniChar(src, &ch);
/* Combine surrogates */
lowChar = (((lowChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
lowChar = Tcl_UniCharToLower(lowChar);
/*
* To keep badly formed Utf strings from getting inflated by the
@@ -942,7 +990,8 @@ int
Tcl_UtfToTitle(
char *str) /* String to convert in place. */
{
Tcl_UniChar ch = 0, titleChar, lowChar;
Tcl_UniChar ch = 0;
int titleChar, lowChar;
char *src, *dst;
int bytes;
@@ -955,7 +1004,16 @@ Tcl_UtfToTitle(
if (*src) {
bytes = TclUtfToUniChar(src, &ch);
titleChar = Tcl_UniCharToTitle(ch);
titleChar = ch;
#if TCL_UTF_MAX <= 4
if (!bytes) {
/* TclUtfToUniChar only returns 0 for chars > 0xffff ! */
bytes = TclUtfToUniChar(src, &ch);
/* Combine surrogates */
titleChar = (((titleChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
titleChar = Tcl_UniCharToTitle(titleChar);
if (bytes < TclUtfCount(titleChar)) {
memcpy(dst, src, (size_t) bytes);
@@ -967,7 +1025,16 @@ Tcl_UtfToTitle(
}
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
lowChar = Tcl_UniCharToLower(ch);
lowChar = ch;
#if TCL_UTF_MAX <= 4
if (!bytes) {
/* TclUtfToUniChar only returns 0 for chars > 0xffff ! */
bytes = TclUtfToUniChar(src, &ch);
/* Combine surrogates */
lowChar = (((lowChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
}
#endif
lowChar = Tcl_UniCharToLower(lowChar);
if (bytes < TclUtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
@@ -1069,7 +1136,7 @@ Tcl_UtfNcmp(
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
/* Surrogates always report higher than non-surrogates */
if (((ch1 & 0xFC00) == 0xD800)) {
if ((ch2 & 0xFC00) != 0xD800) {
@@ -1120,7 +1187,7 @@ Tcl_UtfNcasecmp(
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
/* Surrogates always report higher than non-surrogates */
if (((ch1 & 0xFC00) == 0xD800)) {
if ((ch2 & 0xFC00) != 0xD800) {
@@ -1169,7 +1236,7 @@ TclUtfCmp(
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
/* Surrogates always report higher than non-surrogates */
if (((ch1 & 0xFC00) == 0xD800)) {
if ((ch2 & 0xFC00) != 0xD800) {
@@ -1215,7 +1282,7 @@ TclUtfCasecmp(
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
#if TCL_UTF_MAX <= 4
/* Surrogates always report higher than non-surrogates */
if (((ch1 & 0xFC00) == 0xD800)) {
if ((ch2 & 0xFC00) != 0xD800) {
@@ -1252,16 +1319,18 @@ TclUtfCasecmp(
*----------------------------------------------------------------------
*/
Tcl_UniChar
int
Tcl_UniCharToUpper(
int ch) /* Unicode character to convert. */
{
int info = GetUniCharInfo(ch);
if (!UNICODE_OUT_OF_RANGE(ch)) {
int info = GetUniCharInfo(ch);
if (GetCaseType(info) & 0x04) {
ch -= GetDelta(info);
if (GetCaseType(info) & 0x04) {
ch -= GetDelta(info);
}
}
return (Tcl_UniChar) ch;
return ch & 0x1FFFFF;
}
/*
@@ -1280,16 +1349,18 @@ Tcl_UniCharToUpper(
*----------------------------------------------------------------------
*/
Tcl_UniChar
int
Tcl_UniCharToLower(
int ch) /* Unicode character to convert. */
{
int info = GetUniCharInfo(ch);
if (!UNICODE_OUT_OF_RANGE(ch)) {
int info = GetUniCharInfo(ch);
if (GetCaseType(info) & 0x02) {
ch += GetDelta(info);
if (GetCaseType(info) & 0x02) {
ch += GetDelta(info);
}
}
return (Tcl_UniChar) ch;
return ch & 0x1FFFFF;
}
/*
@@ -1308,23 +1379,25 @@ Tcl_UniCharToLower(
*----------------------------------------------------------------------
*/
Tcl_UniChar
int
Tcl_UniCharToTitle(
int ch) /* Unicode character to convert. */
{
int info = GetUniCharInfo(ch);
int mode = GetCaseType(info);
if (!UNICODE_OUT_OF_RANGE(ch)) {
int info = GetUniCharInfo(ch);
int mode = GetCaseType(info);
if (mode & 0x1) {
/*
* Subtract or add one depending on the original case.
*/
if (mode & 0x1) {
/*
* Subtract or add one depending on the original case.
*/
ch += ((mode & 0x4) ? -1 : 1);
} else if (mode == 0x4) {
ch -= GetDelta(info);
ch += ((mode & 0x4) ? -1 : 1);
} else if (mode == 0x4) {
ch -= GetDelta(info);
}
}
return (Tcl_UniChar) ch;
return ch & 0x1FFFFF;
}
/*
@@ -1458,11 +1531,9 @@ int
Tcl_UniCharIsAlnum(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return (((ALPHA_BITS | DIGIT_BITS) >> GetCategory(ch)) & 1);
}
@@ -1486,11 +1557,9 @@ int
Tcl_UniCharIsAlpha(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return ((ALPHA_BITS >> GetCategory(ch)) & 1);
}
@@ -1514,7 +1583,6 @@ int
Tcl_UniCharIsControl(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
ch &= 0x1FFFFF;
if ((ch == 0xE0001) || ((ch >= 0xE0020) && (ch <= 0xE007f))) {
@@ -1525,7 +1593,6 @@ Tcl_UniCharIsControl(
}
return 0;
}
#endif
return ((CONTROL_BITS >> GetCategory(ch)) & 1);
}
@@ -1549,11 +1616,9 @@ int
Tcl_UniCharIsDigit(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return (GetCategory(ch) == DECIMAL_DIGIT_NUMBER);
}
@@ -1577,12 +1642,10 @@ int
Tcl_UniCharIsGraph(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
ch &= 0x1FFFFF;
return (ch >= 0xE0100) && (ch <= 0xE01EF);
}
#endif
return ((GRAPH_BITS >> GetCategory(ch)) & 1);
}
@@ -1606,11 +1669,9 @@ int
Tcl_UniCharIsLower(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return (GetCategory(ch) == LOWERCASE_LETTER);
}
@@ -1634,12 +1695,10 @@ int
Tcl_UniCharIsPrint(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
ch &= 0x1FFFFF;
return (ch >= 0xE0100) && (ch <= 0xE01EF);
}
#endif
return (((GRAPH_BITS|SPACE_BITS) >> GetCategory(ch)) & 1);
}
@@ -1663,11 +1722,9 @@ int
Tcl_UniCharIsPunct(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return ((PUNCT_BITS >> GetCategory(ch)) & 1);
}
@@ -1691,13 +1748,8 @@ int
Tcl_UniCharIsSpace(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
/* Ignore upper 11 bits. */
ch &= 0x1FFFFF;
#else
/* Ignore upper 16 bits. */
ch &= 0xFFFF;
#endif
/*
* If the character is within the first 127 characters, just use the
@@ -1706,10 +1758,8 @@ Tcl_UniCharIsSpace(
if (ch < 0x80) {
return TclIsSpaceProc((char) ch);
#if TCL_UTF_MAX > 3
} else if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
#endif
} else if (ch == 0x0085 || ch == 0x180E || ch == 0x200B
|| ch == 0x202F || ch == 0x2060 || ch == 0xFEFF) {
return 1;
@@ -1738,11 +1788,9 @@ int
Tcl_UniCharIsUpper(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return (GetCategory(ch) == UPPERCASE_LETTER);
}
@@ -1766,11 +1814,9 @@ int
Tcl_UniCharIsWordChar(
int ch) /* Unicode character to test. */
{
#if TCL_UTF_MAX > 3
if (UNICODE_OUT_OF_RANGE(ch)) {
return 0;
}
#endif
return ((WORD_BITS >> GetCategory(ch)) & 1);
}
+573 -440
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -11,7 +11,7 @@
package require Tcl 8.6-
# Keep this in sync with pkgIndex.tcl and with the install directories in
# Makefiles
package provide http 2.8.12
package provide http 2.8.13
namespace eval http {
# Allow resourcing to not clobber existing data
@@ -602,7 +602,7 @@ proc http::geturl {url args} {
if {[info exists state(-myaddr)]} {
lappend sockopts -myaddr $state(-myaddr)
}
if {[catch {eval $defcmd $sockopts $targetAddr} sock]} {
if {[catch {eval $defcmd $sockopts $targetAddr} sock errdict]} {
# something went wrong while trying to establish the connection.
# Clean up after events and such, but DON'T call the command
# callback (if available) because we're going to throw an
@@ -611,7 +611,8 @@ proc http::geturl {url args} {
set state(sock) $sock
Finish $token "" 1
cleanup $token
return -code error $sock
dict unset errdict -level
return -options $errdict $sock
}
}
set state(sock) $sock
+1 -1
View File
@@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6-]} {return}
package ifneeded http 2.8.12 [list tclPkgSetup $dir http 2.8.12 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
package ifneeded http 2.8.13 [list tclPkgSetup $dir http 2.8.13 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
+2 -3
View File
@@ -19,7 +19,6 @@ catch [list package require -exact Tcltest [info patchlevel]]
# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
testConstraint testobj [llength [info commands testobj]]
testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}]
test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
lsort
@@ -154,10 +153,10 @@ test cmdIL-1.37 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} {
test cmdIL-1.38 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} {
lsort -ascii -nocase [list \0 \x7f \x80 \uffff]
} [list \0 \x7f \x80 \uffff]
test cmdIL-1.39 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} fullutf {
test cmdIL-1.39 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} {
lsort -ascii [list \0 \x7f \x80 \U01ffff \uffff]
} [list \0 \x7f \x80 \uffff \U01ffff]
test cmdIL-1.40 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} fullutf {
test cmdIL-1.40 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} {
lsort -ascii -nocase [list \0 \x7f \x80 \U01ffff \uffff]
} [list \0 \x7f \x80 \uffff \U01ffff]
test cmdIL-1.41 {lsort -stride and -index} -body {
+5 -5
View File
@@ -36,7 +36,7 @@ proc runtests {} {
testConstraint testencoding [llength [info commands testencoding]]
testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint teststringbytes [llength [info commands teststringbytes]]
testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}]
testConstraint tip389 [expr {[string length \U010000] == 2}]
testConstraint exec [llength [info commands exec]]
testConstraint testgetencpath [llength [info commands testgetencpath]]
@@ -323,16 +323,16 @@ test encoding-15.3 {UtfToUtfProc null character input} teststringbytes {
set z
} c080
test encoding-16.1 {UnicodeToUtfProc} {
test encoding-16.1 {UnicodeToUtfProc} -constraints tip389 -body {
set val [encoding convertfrom unicode NN]
list $val [format %x [scan $val %c]]
} "\u4e4e 4e4e"
test encoding-16.2 {UnicodeToUtfProc} -constraints fullutf -body {
} -result "\u4e4e 4e4e"
test encoding-16.2 {UnicodeToUtfProc} -constraints tip389 -body {
set val [encoding convertfrom unicode "\xd8\xd8\xdc\xdc"]
list $val [format %x [scan $val %c]]
} -result "\U460dc 460dc"
test encoding-17.1 {UtfToUnicodeProc} -constraints fullutf -body {
test encoding-17.1 {UtfToUnicodeProc} -constraints tip389 -body {
encoding convertto unicode "\U460dc"
} -result "\xd8\xd8\xdc\xdc"
+8 -8
View File
@@ -1317,33 +1317,33 @@ if {[package vsatisfies [package provide msgcat] 1.7]} {
interp bgerror {} $bgerrorsaved
# Tests msgcat-15.*: [mcutil]
# Tests msgcat-18.*: [mcutil]
test msgcat-15.1 {mcutil - no argument} -body {
test msgcat-18.1 {mcutil - no argument} -body {
mcutil
} -returnCodes 1\
-result {wrong # args: should be "mcutil subcommand ?arg ...?"}
test msgcat-15.2 {mcutil - wrong argument} -body {
test msgcat-18.2 {mcutil - wrong argument} -body {
mcutil junk
} -returnCodes 1\
-result {unknown subcommand "junk": must be getpreferences, or getsystemlocale}
test msgcat-15.3 {mcutil - partial argument} -body {
test msgcat-18.3 {mcutil - partial argument} -body {
mcutil getsystem
} -returnCodes 1\
-result {unknown subcommand "getsystem": must be getpreferences, or getsystemlocale}
test msgcat-15.4 {mcutil getpreferences - no argument} -body {
test msgcat-18.4 {mcutil getpreferences - no argument} -body {
mcutil getpreferences
} -returnCodes 1\
-result {wrong # args: should be "mcutil getpreferences locale"}
test msgcat-15.5 {mcutil getpreferences - DE_de} -body {
test msgcat-18.5 {mcutil getpreferences - DE_de} -body {
mcutil getpreferences DE_de
} -result {de_de de {}}
test msgcat-15.6 {mcutil getsystemlocale - wrong argument} -body {
test msgcat-18.6 {mcutil getsystemlocale - wrong argument} -body {
mcutil getsystemlocale DE_de
} -returnCodes 1\
-result {wrong # args: should be "mcutil getsystemlocale"}
@@ -1351,7 +1351,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} {
# The result is system dependent
# So just test if it runs
# The environment variable version was test with test 0.x
test msgcat-15.7 {mcutil getsystemlocale} -body {
test msgcat-18.7 {mcutil getsystemlocale} -body {
mcutil getsystemlocale
set ok ok
} -result {ok}
+1 -1
View File
@@ -340,7 +340,7 @@ test set-old-8.6 {array command} {
catch {unset a}
set a(22) 3
list [catch {array gorp a} msg] $msg
} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, get, names, nextelement, set, size, startsearch, statistics, or unset}}
} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, for, get, names, nextelement, set, size, startsearch, statistics, or unset}}
test set-old-8.7 {array command, anymore option} {
catch {unset a}
list [catch {array anymore a x} msg] $msg
+9 -2
View File
@@ -31,7 +31,7 @@ proc makeShared {s} {uplevel 1 [list lappend copy $s]; return $s}
testConstraint testobj [expr {[info commands testobj] ne {}}]
testConstraint testindexobj [expr {[info commands testindexobj] ne {}}]
testConstraint testevalex [expr {[info commands testevalex] ne {}}]
testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}]
testConstraint tip389 [expr {[string length \U010000] == 2}]
# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
@@ -487,6 +487,9 @@ test string-5.19.$noComp {string index, bytearray object out of bounds} {
test string-5.20.$noComp {string index, bytearray object out of bounds} {
run {string index [binary format I* {0x50515253 0x52}] 20}
} {}
test string-5.21.$noComp {string index, surrogates, bug [11ae2be95dac9417]} tip389 {
run {list [string index a\U100000b 1] [string index a\U100000b 2] [string index a\U100000b 3]}
} [list \U100000 {} b]
proc largest_int {} {
@@ -1481,7 +1484,7 @@ test string-12.22.$noComp {string range, shimmering binary/index} {
binary scan $s a* x
run {string range $s $s end}
} 000000001
test string-12.23.$noComp {string range, surrogates, bug [11ae2be95dac9417]} fullutf {
test string-12.23.$noComp {string range, surrogates, bug [11ae2be95dac9417]} tip389 {
run {list [string range a\U100000b 1 1] [string range a\U100000b 2 2] [string range a\U100000b 3 3]}
} [list \U100000 {} b]
@@ -1722,6 +1725,10 @@ test string-17.7.$noComp {string totitle, unicode} {
test string-17.8.$noComp {string totitle, compiled} {
lindex [run {string totitle [list aa bb [list cc]]}] 0
} Aa
test string-17.9.$noComp {string totitle, surrogates, bug [11ae2be95dac9417]} tip389 {
run {list [string totitle a\U118c0c 1 1] [string totitle a\U118c0c 2 2] \
[string totitle a\U118c0c 3 3]}
} [list a\U118a0c a\U118c0C a\U118c0C]
test string-18.1.$noComp {string trim} {
list [catch {run {string trim}} msg] $msg
+5 -5
View File
@@ -21,7 +21,7 @@ testConstraint testbytestring [llength [info commands testbytestring]]
catch {unset x}
# Some tests require support for 4-byte UTF-8 sequences
testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}]
testConstraint tip389 [expr {[string length \U010000] == 2}]
test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} testbytestring {
expr {"\x01" eq [testbytestring "\x01"]}
@@ -41,7 +41,7 @@ test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring {
test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring {
expr {[format %c -1] eq [testbytestring "\xef\xbf\xbd"]}
} 1
test utf-1.7 {Tcl_UniCharToUtf: 4 byte sequences} -constraints {fullutf testbytestring} -body {
test utf-1.7 {Tcl_UniCharToUtf: 4 byte sequences} -constraints {tip389 testbytestring} -body {
expr {"\U014e4e" eq [testbytestring "\xf0\x94\xb9\x8e"]}
} -result 1
@@ -66,10 +66,10 @@ test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestrin
test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring {
string length [testbytestring "\xE4\xb9\x8e"]
} {1}
test utf-2.8 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {fullutf testbytestring} -body {
test utf-2.8 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {tip389 testbytestring} -body {
string length [testbytestring "\xF0\x90\x80\x80"]
} -result {2}
test utf-2.9 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {fullutf testbytestring} -body {
test utf-2.9 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {tip389 testbytestring} -body {
string length [testbytestring "\xF4\x8F\xBF\xBF"]
} -result {2}
test utf-2.10 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, underflow} testbytestring {
@@ -228,7 +228,7 @@ bsCheck \U4e21 20001
bsCheck \U004e21 20001
bsCheck \U00004e21 20001
bsCheck \U0000004e21 78
if {[testConstraint fullutf]} {
if {[testConstraint tip389]} {
bsCheck \U00110000 69632
bsCheck \U01100000 69632
bsCheck \U11000000 69632
+226
View File
@@ -777,6 +777,22 @@ test var-13.1 {Tcl_UnsetVar2, unset array with trace set on element} -setup {
}
set x "If you see this, it worked"
} -result "If you see this, it worked"
test var-13.2 {unset array with search, bug 46a2410650} -body {
apply {{} {
array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
set s [array startsearch a]
unset a([array nextelement a $s])
array nextelement a $s
}}
} -returnCodes error -result {couldn't find search "s-1-a"}
test var-13.3 {unset array with search, SIGSEGV, bug 46a2410650} -body {
apply {{} {
array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
set s [array startsearch a]
unset a(ff)
array nextelement a $s
}}
} -returnCodes error -result {couldn't find search "s-1-a"}
test var-14.1 {array names syntax} -body {
array names foo bar baz snafu
@@ -820,6 +836,18 @@ test var-17.1 {TclArraySet [Bug 1669489]} -setup {
} -cleanup {
unset -nocomplain ::a ::elements
} -result {}
test var-17.2 {TclArraySet Dict shortcut only on pure value} -setup {
unset -nocomplain a d
set d {p 1 p 2}
dict get $d p
set foo 0
} -body {
trace add variable a write "[list incr [namespace which -variable foo]];#"
array set a $d
set foo
} -cleanup {
unset -nocomplain a d foo
} -result 2
test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
set already 0
@@ -931,6 +959,28 @@ test var-20.9 {[bc1a96407a] array set compiled w/ trace} -setup {
test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body {
apply {{} {set name foo(bar); array set $name {a 1}}}
} -returnCodes error -match glob -result *
test var-20.11 {array set don't compile bad initializer} -setup {
unset -nocomplain foo
trace add variable foo array {set foo(bar) baz;#}
} -body {
catch {array set foo bad}
set foo(bar)
} -cleanup {
unset -nocomplain foo
} -result baz
test var-20.12 {array set don't compile bad initializer} -setup {
unset -nocomplain ::foo
trace add variable ::foo array {set ::foo(bar) baz;#}
} -body {
catch {apply {{} {
set value bad
array set ::foo $value
}}}
set ::foo(bar)
} -cleanup {
unset -nocomplain ::foo
} -result baz
test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
proc linenumber {} {dict get [info frame -1] line}
@@ -996,6 +1046,182 @@ test var-22.2 {leak in parsedVarName} -constraints memory -body {
} -cleanup {
unset -nocomplain i x
} -result 0
unset -nocomplain a k v
test var-23.1 {array command, for loop, too many args} -returnCodes error -body {
array for {k v} c d e {}
} -result {wrong # args: should be "array for {key value} arrayName script"}
test var-23.2 {array command, for loop, not enough args} -returnCodes error -body {
array for {k v} {}
} -result {wrong # args: should be "array for {key value} arrayName script"}
test var-23.3 {array command, for loop, too many list args} -setup {
unset -nocomplain a
} -returnCodes error -body {
array for {k v w} a {}
} -result {must have two variable names}
test var-23.4 {array command, for loop, not enough list args} -setup {
unset -nocomplain a
} -returnCodes error -body {
array for {k} a {}
} -result {must have two variable names}
test var-23.5 {array command, for loop, no array} -setup {
unset -nocomplain a
} -returnCodes error -body {
array for {k v} a {}
} -result {"a" isn't an array}
test var-23.6 {array command, for loop, array doesn't exist yet but has compiler-allocated procedure slot} -setup {
catch {rename p ""}
} -returnCodes error -body {
apply {{x} {
if {$x==1} {
return [array for {k v} a {}]
}
set a(x) 123
}} 1
} -result {"a" isn't an array}
test var-23.7 {array enumeration} -setup {
unset -nocomplain a
set reslist [list]
} -body {
array set a {a 1 b 2 c 3}
array for {k v} a {
lappend reslist $k $v
}
lsort -stride 2 -index 0 $reslist
} -cleanup {
unset -nocomplain a
unset -nocomplain reslist
} -result {a 1 b 2 c 3}
test var-23.9 {array enumeration, nested} -setup {
unset -nocomplain a
set reslist [list]
} -body {
array set a {a 1 b 2 c 3}
array for {k1 v1} a {
lappend reslist $k1 $v1
set r2 {}
array for {k2 v2} a {
lappend r2 $k2 $v2
}
lappend reslist [lsort -stride 2 -index 0 $r2]
}
# there is no guarantee in which order the array contents will be
# returned.
lsort -stride 3 -index 0 $reslist
} -cleanup {
unset -nocomplain a
unset -nocomplain reslist
} -result {a 1 {a 1 b 2 c 3} b 2 {a 1 b 2 c 3} c 3 {a 1 b 2 c 3}}
test var-23.10 {array enumeration, delete key} -match glob -setup {
unset -nocomplain a
set reslist [list]
} -body {
set retval {}
try {
array set a {a 1 b 2 c 3 d 4}
array for {k v} a {
lappend reslist $k $v
if { $k eq "a" } {
unset a(c)
}
}
lsort -stride 2 -index 0 $reslist
} on error {err res} {
set retval [dict get $res -errorinfo]
}
set retval
} -cleanup {
unset -nocomplain a
unset -nocomplain reslist
unset -nocomplain retval
} -result {array changed during iteration*}
test var-23.11 {array enumeration, insert key} -match glob -setup {
unset -nocomplain a
set reslist [list]
} -body {
set retval {}
try {
array set a {a 1 b 2 c 3 d 4}
array for {k v} a {
lappend reslist $k $v
if { $k eq "a" } {
set a(e) 5
}
}
lsort -stride 2 -index 0 $reslist
} on error {err res} {
set retval [dict get $res -errorinfo]
}
} -cleanup {
unset -nocomplain a
unset -nocomplain reslist
} -result {array changed during iteration*}
test var-23.12 {array enumeration, change value} -setup {
unset -nocomplain a
set reslist [list]
} -body {
array set a {a 1 b 2 c 3}
array for {k v} a {
lappend reslist $k $v
if { $k eq "a" } {
set a(c) 9
}
}
lsort -stride 2 -index 0 $reslist
} -cleanup {
unset -nocomplain a
unset -nocomplain reslist
} -result {a 1 b 2 c 9}
test var-23.13 {array enumeration, number of traces} -setup {
set ::countarrayfor 0
proc ::tracearrayfor { args } {
incr ::countarrayfor
}
unset -nocomplain ::a
set reslist [list]
} -body {
array set ::a {a 1 b 2 c 3}
foreach {k} [array names a] {
trace add variable ::a($k) read ::tracearrayfor
}
array for {k v} ::a {
lappend reslist $k $v
}
set ::countarrayfor
} -cleanup {
unset -nocomplain ::countarrayfor
unset -nocomplain ::a
unset -nocomplain reslist
} -result 3
test var-23.14 {array for, shared arguments} -setup {
set vn {k v}
unset -nocomplain $vn
} -body {
array set $vn {a 1 b 2 c 3}
array for $vn $vn {}
} -cleanup {
unset -nocomplain $vn vn
} -result {}
test var-23.15 {array for, [Bug e87bcf819f]} -setup {
unset -nocomplain a
array set a {m 1 n 2}
upvar 0 a(n) l
set unset unset
} -body {
array for {k v} a {$unset l}
} -cleanup {
unset -nocomplain a
} -returnCodes error -result {array changed during iteration}
test var-23.15.1 {array for, [Bug e87bcf819f]} -setup {
unset -nocomplain a
array set a {m 1 n 2}
upvar 0 a(n) l
} -body {
array for {k v} a {unset l}
} -cleanup {
unset -nocomplain a
} -returnCodes error -result {array changed during iteration}
catch {namespace delete ns}
+2 -2
View File
@@ -844,8 +844,8 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \
done;
@echo "Installing package http 2.8.12 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.12.tm;
@echo "Installing package http 2.8.13 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.13.tm;
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/";
@for i in $(TOP_DIR)/library/opt/*.tcl ; \
do \
+2 -2
View File
@@ -653,8 +653,8 @@ install-libraries: libraries install-tzdata install-msgs
do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \
done;
@echo "Installing package http 2.8.12 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.12.tm;
@echo "Installing package http 2.8.13 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.13.tm;
@echo "Installing library opt0.4 directory";
@for j in $(ROOT_DIR)/library/opt/*.tcl; \
do \