diff options
| -rw-r--r-- | generic/tcl.h | 56 | ||||
| -rw-r--r-- | generic/tclEncoding.c | 12 | ||||
| -rw-r--r-- | generic/tclIO.c | 25 | ||||
| -rw-r--r-- | generic/tclIOCmd.c | 46 | ||||
| -rw-r--r-- | tests/encoding.test | 144 | ||||
| -rw-r--r-- | tests/io.test | 194 | ||||
| -rw-r--r-- | tests/ioCmd.test | 4 | ||||
| -rw-r--r-- | tools/regexpTestLib.tcl | 2 | ||||
| -rw-r--r-- | win/tclAppInit.c | 2 |
9 files changed, 296 insertions, 189 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index 4d7ff7d..c2dc70d 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -306,16 +306,30 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; # define TCL_Z_MODIFIER "" # endif #endif /* !TCL_Z_MODIFIER */ +#ifndef TCL_T_MODIFIER +# if defined(__GNUC__) && !defined(_WIN32) +# define TCL_T_MODIFIER "t" +# elif defined(_WIN64) +# define TCL_T_MODIFIER TCL_LL_MODIFIER +# else +# define TCL_T_MODIFIER TCL_Z_MODIFIER +# endif +#endif /* !TCL_T_MODIFIER */ + #define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val))) #define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val))) #define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val))) #define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val))) #if TCL_MAJOR_VERSION < 9 -typedef int Tcl_Size; + typedef int Tcl_Size; +# define TCL_SIZE_MODIFIER "" +# define TCL_SIZE_MAX INT_MAX #else -typedef size_t Tcl_Size; -#endif + typedef size_t Tcl_Size; +# define TCL_SIZE_MAX PTRDIFF_MAX +# define TCL_SIZE_MODIFIER TCL_T_MODIFIER +#endif /* TCL_MAJOR_VERSION */ #ifdef _WIN32 # if TCL_MAJOR_VERSION > 8 || defined(_WIN64) || defined(_USE_64BIT_TIME_T) @@ -450,38 +464,30 @@ typedef void (Tcl_ThreadCreateProc) (void *clientData); * string. */ -#if TCL_MAJOR_VERSION > 8 typedef struct Tcl_RegExpIndices { +#if TCL_MAJOR_VERSION > 8 Tcl_Size start; /* Character offset of first character in * match. */ Tcl_Size end; /* Character offset of first character after * the match. */ +#else + long start; + long end; +#endif } Tcl_RegExpIndices; typedef struct Tcl_RegExpInfo { Tcl_Size nsubs; /* Number of subexpressions in the compiled * expression. */ Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */ +#if TCL_MAJOR_VERSION > 8 Tcl_Size extendStart; /* The offset at which a subsequent match * might begin. */ -} Tcl_RegExpInfo; #else -typedef struct Tcl_RegExpIndices { - long start; /* Character offset of first character in - * match. */ - long end; /* Character offset of first character after - * the match. */ -} Tcl_RegExpIndices; - -typedef struct Tcl_RegExpInfo { - int nsubs; /* Number of subexpressions in the compiled - * expression. */ - Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */ - long extendStart; /* The offset at which a subsequent match - * might begin. */ + long extendStart; long reserved; /* Reserved for later use. */ -} Tcl_RegExpInfo; #endif +} Tcl_RegExpInfo; /* * Picky compilers complain if this typdef doesn't appear before the struct's @@ -1774,7 +1780,7 @@ typedef struct Tcl_Token { * TCL_TOKEN_OPERATOR - The token describes one expression operator. * An operator might be the name of a math * function such as "abs". A TCL_TOKEN_OPERATOR - * token is always preceeded by one + * token is always preceded by one * TCL_TOKEN_SUB_EXPR token for the operator's * subexpression, and is followed by zero or more * TCL_TOKEN_SUB_EXPR tokens for the operator's @@ -2006,11 +2012,11 @@ typedef struct Tcl_EncodingType { */ #ifndef TCL_UTF_MAX -#if TCL_MAJOR_VERSION > 8 -#define TCL_UTF_MAX 4 -#else -#define TCL_UTF_MAX 3 -#endif +# if TCL_MAJOR_VERSION > 8 +# define TCL_UTF_MAX 4 +# else +# define TCL_UTF_MAX 3 +# endif #endif /* diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 249c862..8137e8f 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -603,7 +603,7 @@ TclInitEncodingSubsystem(void) type.nullSize = 1; type.clientData = INT2PTR(ENCODING_UTF); Tcl_CreateEncoding(&type); - type.clientData = INT2PTR(0); + type.clientData = NULL; type.encodingName = "cesu-8"; Tcl_CreateEncoding(&type); @@ -615,7 +615,7 @@ TclInitEncodingSubsystem(void) type.clientData = INT2PTR(TCL_ENCODING_LE); Tcl_CreateEncoding(&type); type.encodingName = "ucs-2be"; - type.clientData = INT2PTR(0); + type.clientData = NULL; Tcl_CreateEncoding(&type); type.encodingName = "ucs-2"; type.clientData = INT2PTR(leFlags); @@ -629,7 +629,7 @@ TclInitEncodingSubsystem(void) type.clientData = INT2PTR(TCL_ENCODING_LE); Tcl_CreateEncoding(&type); type.encodingName = "utf-32be"; - type.clientData = INT2PTR(0); + type.clientData = NULL; Tcl_CreateEncoding(&type); type.encodingName = "utf-32"; type.clientData = INT2PTR(leFlags); @@ -640,13 +640,13 @@ TclInitEncodingSubsystem(void) type.freeProc = NULL; type.nullSize = 2; type.encodingName = "utf-16le"; - type.clientData = INT2PTR(TCL_ENCODING_LE|ENCODING_UTF); + type.clientData = INT2PTR(TCL_ENCODING_LE); Tcl_CreateEncoding(&type); type.encodingName = "utf-16be"; - type.clientData = INT2PTR(ENCODING_UTF); + type.clientData = NULL; Tcl_CreateEncoding(&type); type.encodingName = "utf-16"; - type.clientData = INT2PTR(leFlags|ENCODING_UTF); + type.clientData = INT2PTR(leFlags); Tcl_CreateEncoding(&type); #ifndef TCL_NO_DEPRECATED diff --git a/generic/tclIO.c b/generic/tclIO.c index f6414dc..72d568a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4189,7 +4189,6 @@ Tcl_WriteChars( } objPtr = Tcl_NewStringObj(src, len); - Tcl_IncrRefCount(objPtr); src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len); if (src == NULL) { Tcl_SetErrno(EILSEQ); @@ -4238,6 +4237,7 @@ Tcl_WriteObj( Channel *chanPtr; ChannelState *statePtr; /* State info for channel */ const char *src; + Tcl_Size srcLen; statePtr = ((Channel *) chan)->state; chanPtr = statePtr->topChanPtr; @@ -4245,8 +4245,6 @@ Tcl_WriteObj( if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) { return TCL_INDEX_NONE; } - - Tcl_Size srcLen; if (statePtr->encoding == NULL) { src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen); if (src == NULL) { @@ -4606,14 +4604,15 @@ Tcl_GetsObj( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - int inEofChar, skip, copiedTotal, oldFlags, oldRemoved; - Tcl_Size oldLength; + int inEofChar, skip, copiedTotal, oldFlags; + Tcl_Size oldLength, oldRemoved; Tcl_Encoding encoding; char *dst, *dstEnd, *eol, *eof; Tcl_EncodingState oldState; if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) { UpdateInterest(chanPtr); + ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_ENCODING_ERROR); Tcl_SetErrno(EILSEQ); return TCL_INDEX_NONE; } @@ -4996,11 +4995,12 @@ Tcl_GetsObj( UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR) && gs.bytesWrote == 0) { - bufPtr->nextRemoved = oldRemoved; - Tcl_SetErrno(EILSEQ); - if (copiedTotal == 0) { - copiedTotal = -1; + if (bufPtr->nextRemoved != oldRemoved) { + bufPtr->nextRemoved = oldRemoved; + ResetFlag(statePtr, CHANNEL_ENCODING_ERROR); } + Tcl_SetErrno(EILSEQ); + copiedTotal = -1; } return copiedTotal; } @@ -5463,8 +5463,7 @@ FilterInputBytes( if (result == TCL_CONVERT_UNKNOWN || result == TCL_CONVERT_SYNTAX) { SetFlag(statePtr, CHANNEL_ENCODING_ERROR); - ResetFlag(statePtr, CHANNEL_STICKY_EOF); - ResetFlag(statePtr, CHANNEL_EOF); + ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_STICKY_EOF); result = TCL_OK; } @@ -5932,7 +5931,7 @@ DoReadChars( /* State info for channel */ ChannelBuffer *bufPtr; Tcl_Size copied; - int result; + int result, copiedNow; Tcl_Encoding encoding = statePtr->encoding; int binaryMode; #define UTF_EXPANSION_FACTOR 1024 @@ -6008,7 +6007,7 @@ DoReadChars( ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; for (copied = 0; toRead > 0 || toRead == TCL_INDEX_NONE; ) { - int copiedNow = -1; + copiedNow = -1; if (statePtr->inQueueHead != NULL) { if (binaryMode) { copiedNow = ReadBytes(statePtr, objPtr, toRead); diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 03ca291..e113ad4 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -107,7 +107,7 @@ Tcl_PutsObjCmd( Tcl_Obj *string; /* String to write. */ Tcl_Obj *chanObjPtr = NULL; /* channel object. */ int newline; /* Add a newline at end? */ - size_t result; /* Result of puts operation. */ + Tcl_Size result; /* Result of puts operation. */ int mode; /* Mode in which channel is opened. */ switch (objc) { @@ -281,7 +281,7 @@ Tcl_GetsObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel chan; /* The channel to read from. */ - size_t lineLen; /* Length of line just read. */ + Tcl_Size lineLen; /* Length of line just read. */ int mode; /* Mode in which channel is opened. */ Tcl_Obj *linePtr, *chanObjPtr; int code = TCL_OK; @@ -304,7 +304,7 @@ Tcl_GetsObjCmd( TclChannelPreserve(chan); TclNewObj(linePtr); lineLen = Tcl_GetsObj(chan, linePtr); - if (lineLen == TCL_IO_FAILURE) { + if (lineLen == TCL_INDEX_NONE) { if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) { Tcl_DecrRefCount(linePtr); @@ -316,22 +316,14 @@ Tcl_GetsObjCmd( */ if (!TclChanCaughtErrorBypass(interp, chan)) { - goto getsError; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading \"%s\": %s", + TclGetString(chanObjPtr), Tcl_PosixError(interp))); } code = TCL_ERROR; goto done; } - lineLen = TCL_IO_FAILURE; - } else if (Tcl_InputEncodingError(chan)) { - Tcl_Obj *returnOpts = Tcl_NewDictObj(); - Tcl_DictObjPut(NULL, returnOpts, Tcl_NewStringObj("-data", TCL_INDEX_NONE), linePtr); - Tcl_SetReturnOptions(interp, returnOpts); - getsError: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error reading \"%s\": %s", - TclGetString(chanObjPtr), Tcl_PosixError(interp))); - code = TCL_ERROR; - goto done; + lineLen = TCL_INDEX_NONE; } if (objc == 3) { if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr, @@ -377,7 +369,7 @@ Tcl_ReadObjCmd( Tcl_Channel chan; /* The channel to read from. */ int newline, i; /* Discard newline at end? */ Tcl_WideInt toRead; /* How many bytes to read? */ - size_t charactersRead; /* How many characters were read? */ + Tcl_Size charactersRead; /* How many characters were read? */ int mode; /* Mode in which channel is opened. */ Tcl_Obj *resultPtr, *chanObjPtr; @@ -438,10 +430,10 @@ Tcl_ReadObjCmd( } TclNewObj(resultPtr); - Tcl_IncrRefCount(resultPtr); TclChannelPreserve(chan); charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0); - if (charactersRead == TCL_IO_FAILURE) { + if (charactersRead == TCL_INDEX_NONE) { + Tcl_DecrRefCount(resultPtr); /* * TIP #219. * Capture error messages put by the driver into the bypass area and @@ -449,15 +441,12 @@ Tcl_ReadObjCmd( * regular message if nothing was found in the bypass. */ - Tcl_DecrRefCount(resultPtr); if (!TclChanCaughtErrorBypass(interp, chan)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error reading \"%s\": %s", - TclGetString(chanObjPtr), Tcl_PosixError(interp))); - goto readError; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading \"%s\": %s", + TclGetString(chanObjPtr), Tcl_PosixError(interp))); } - TclChannelRelease(chan); - return TCL_ERROR; + goto readError; } else if (Tcl_InputEncodingError(chan)) { Tcl_Obj *returnOpts = Tcl_NewDictObj(); Tcl_DictObjPut(NULL, returnOpts, Tcl_NewStringObj("-data", TCL_INDEX_NONE), resultPtr); @@ -476,7 +465,7 @@ Tcl_ReadObjCmd( if ((charactersRead > 0) && (newline != 0)) { const char *result; - size_t length; + Tcl_Size length; result = Tcl_GetStringFromObj(resultPtr, &length); if (result[length - 1] == '\n') { @@ -485,7 +474,6 @@ Tcl_ReadObjCmd( } Tcl_SetObjResult(interp, resultPtr); TclChannelRelease(chan); - Tcl_DecrRefCount(resultPtr); return TCL_OK; } @@ -879,7 +867,7 @@ Tcl_ExecObjCmd( const char *string; Tcl_Channel chan; int argc, background, i, index, keepNewline, result, skip, ignoreStderr; - size_t length; + Tcl_Size length; static const char *const options[] = { "-ignorestderr", "-keepnewline", "--", NULL }; @@ -1140,7 +1128,7 @@ Tcl_OpenObjCmd( chan = Tcl_FSOpenFileChannel(interp, objv[1], modeString, prot); } else { int mode, seekFlag, binary; - size_t cmdObjc; + Tcl_Size cmdObjc; const char **cmdArgv; if (Tcl_SplitList(interp, what+1, &cmdObjc, &cmdArgv) != TCL_OK) { diff --git a/tests/encoding.test b/tests/encoding.test index 0d8fdfe..09f3e42 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -467,20 +467,20 @@ test encoding-15.25 {UtfToUtfProc CESU-8} { test encoding-15.26 {UtfToUtfProc CESU-8} { encoding convertfrom -profile tcl8 cesu-8 \xC0\x80 } \x00 -test encoding-15.27 {UtfToUtfProc CESU-8} { - encoding convertfrom cesu-8 \x00 +test encoding-15.27 {UtfToUtfProc -profile strict CESU-8} { + encoding convertfrom -profile strict cesu-8 \x00 } \x00 -test encoding-15.28 {UtfToUtfProc CESU-8} -body { - encoding convertfrom cesu-8 \xC0\x80 +test encoding-15.28 {UtfToUtfProc -profile strict CESU-8} -body { + encoding convertfrom -profile strict cesu-8 \xC0\x80 } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xC0'} test encoding-15.29 {UtfToUtfProc CESU-8} { encoding convertto cesu-8 \x00 } \x00 -test encoding-15.30 {UtfToUtfProc CESU-8} { - encoding convertto cesu-8 \x00 +test encoding-15.30 {UtfToUtfProc -profile strict CESU-8} { + encoding convertto -profile strict cesu-8 \x00 } \x00 -test encoding-15.31 {UtfToUtfProc CESU-8 (bytes F0-F4 are invalid)} -body { - encoding convertfrom cesu-8 \xF1\x86\x83\x9C +test encoding-15.31 {UtfToUtfProc -profile strict CESU-8 (bytes F0-F4 are invalid)} -body { + encoding convertfrom -profile strict cesu-8 \xF1\x86\x83\x9C } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xF1'} test encoding-16.1 {Utf16ToUtfProc} -body { @@ -504,11 +504,11 @@ test encoding-16.5 {Ucs2ToUtfProc} -body { list $val [format %x [scan $val %c]] } -result "\U460DC 460dc" test encoding-16.6 {Utf32ToUtfProc} -body { - set val [encoding convertfrom utf-32le NN\0\0] + set val [encoding convertfrom -profile strict utf-32le NN\0\0] list $val [format %x [scan $val %c]] } -result "乎 4e4e" test encoding-16.7 {Utf32ToUtfProc} -body { - set val [encoding convertfrom utf-32be \0\0NN] + set val [encoding convertfrom -profile strict utf-32be \0\0NN] list $val [format %x [scan $val %c]] } -result "乎 4e4e" test encoding-16.8 {Utf32ToUtfProc} -body { @@ -540,7 +540,7 @@ test encoding-16.16 {Utf16ToUtfProc} -body { encoding convertfrom -profile tcl8 utf-16le \x00\xDC\x00\xD8 } -result \uDC00\uD800 test encoding-16.17 {Utf32ToUtfProc} -body { - list [encoding convertfrom -failindex idx utf-32le \x41\x00\x00\x00\x00\xD8\x00\x00\x42\x00\x00\x00] [set idx] + list [encoding convertfrom -profile strict -failindex idx utf-32le \x41\x00\x00\x00\x00\xD8\x00\x00\x42\x00\x00\x00] [set idx] } -result {A 4} test encoding-16.18 { @@ -565,17 +565,17 @@ test encoding-16.18 { test encoding-16.19 {Utf16ToUtfProc, bug [d19fe0a5b]} -body { encoding convertfrom -profile tcl8 utf-16 "\x41\x41\x41" } -result \u4141\uFFFD -test encoding-16.20 {UnicodeToUtfProc, bug [d19fe0a5b]} -body { - encoding convertfrom -profile tcl8 utf-16 "\xD8\xD8" +test encoding-16.20 {Utf16ToUtfProc, bug [d19fe0a5b]} -constraints deprecated -body { + encoding convertfrom utf-16 "\xD8\xD8" } -result \uD8D8 -test encoding-16.21 {Utf16ToUtfProc, bug [d19fe0a5b]} -body { +test encoding-16.21 {Utf32ToUtfProc, bug [d19fe0a5b]} -body { encoding convertfrom -profile tcl8 utf-32 "\x00\x00\x00\x00\x41\x41" } -result \x00\uFFFD test encoding-16.22 {Utf16ToUtfProc, strict, bug [db7a085bd9]} -body { - encoding convertfrom utf-16le \x00\xD8 + encoding convertfrom -profile strict utf-16le \x00\xD8 } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\x00'} test encoding-16.23 {Utf16ToUtfProc, strict, bug [db7a085bd9]} -body { - encoding convertfrom utf-16le \x00\xDC + encoding convertfrom -profile strict utf-16le \x00\xDC } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\x00'} test encoding-16.24 {Utf32ToUtfProc} -body { encoding convertfrom -profile tcl8 utf-32 "\xFF\xFF\xFF\xFF" @@ -596,46 +596,46 @@ test encoding-17.3 {UtfToUtf16Proc} -body { test encoding-17.4 {UtfToUtf16Proc} -body { encoding convertto -profile tcl8 utf-16le "\uD8D8" } -result "\xD8\xD8" -test encoding-17.5 {UtfToUtf16Proc} -body { +test encoding-17.5 {UtfToUtf32Proc} -body { encoding convertto utf-32le "\U460DC" } -result "\xDC\x60\x04\x00" -test encoding-17.6 {UtfToUtf16Proc} -body { +test encoding-17.6 {UtfToUtf32Proc} -body { encoding convertto utf-32be "\U460DC" } -result "\x00\x04\x60\xDC" test encoding-17.7 {UtfToUtf16Proc} -body { - encoding convertto utf-16be "\uDCDC" + encoding convertto -profile strict utf-16be "\uDCDC" } -returnCodes error -result {unexpected character at index 0: 'U+00DCDC'} test encoding-17.8 {UtfToUtf16Proc} -body { - encoding convertto utf-16le "\uD8D8" + encoding convertto -profile strict utf-16le "\uD8D8" } -returnCodes error -result {unexpected character at index 0: 'U+00D8D8'} test encoding-17.9 {Utf32ToUtfProc} -body { - encoding convertfrom utf-32 "\xFF\xFF\xFF\xFF" + encoding convertfrom -profile strict utf-32 "\xFF\xFF\xFF\xFF" } -returnCodes error -result {unexpected byte sequence starting at index 0: '\xFF'} test encoding-17.10 {Utf32ToUtfProc} -body { encoding convertfrom -profile tcl8 utf-32 "\xFF\xFF\xFF\xFF" } -result \uFFFD test encoding-17.11 {Utf32ToUtfProc} -body { - encoding convertfrom utf-32le "\x00\xD8\x00\x00" + encoding convertfrom -profile strict utf-32le "\x00\xD8\x00\x00" } -returnCodes error -result {unexpected byte sequence starting at index 0: '\x00'} test encoding-17.12 {Utf32ToUtfProc} -body { - encoding convertfrom utf-32le "\x00\xDC\x00\x00" + encoding convertfrom -profile strict utf-32le "\x00\xDC\x00\x00" } -returnCodes error -result {unexpected byte sequence starting at index 0: '\x00'} test encoding-18.1 {TableToUtfProc on invalid input} -body { - list [catch {encoding convertto jis0208 \\} res] $res -} -result {1 {unexpected character at index 0: 'U+00005C'}} -test encoding-18.2 {TableToUtfProc on invalid input with} -body { - list [catch {encoding convertto jis0208 \\} res] $res + list [catch {encoding convertto -profile tcl8 jis0208 \\} res] $res +} -result {0 !)} +test encoding-18.2 {TableToUtfProc on invalid input with -profile strict} -body { + list [catch {encoding convertto -profile strict jis0208 \\} res] $res } -result {1 {unexpected character at index 0: 'U+00005C'}} -test encoding-18.3 {TableToUtfProc on invalid input with -failindex} -body { - list [catch {encoding convertto -failindex pos jis0208 \\} res] $res $pos +test encoding-18.3 {TableToUtfProc on invalid input with -profile strict -failindex} -body { + list [catch {encoding convertto -profile strict -failindex pos jis0208 \\} res] $res $pos } -result {0 {} 0} -test encoding-18.4 {TableToUtfProc on invalid input with -failindex} -body { - list [catch {encoding convertto -failindex pos jis0208 \\} res] $res $pos +test encoding-18.4 {TableToUtfProc on invalid input with -failindex -profile strict} -body { + list [catch {encoding convertto -failindex pos -profile strict jis0208 \\} res] $res $pos } -result {0 {} 0} test encoding-18.5 {TableToUtfProc on invalid input with -failindex} -body { - list [catch {encoding convertto -failindex pos jis0208 \\} res] $res $pos -} -result {0 {} 0} + list [catch {encoding convertto -profile tcl8 -failindex pos jis0208 \\} res] $res $pos +} -result {0 !) -1} test encoding-18.6 {TableToUtfProc on invalid input with -profile tcl8} -body { list [catch {encoding convertto -profile tcl8 jis0208 \\} res] $res } -result {0 !)} @@ -647,16 +647,16 @@ test encoding-19.2 {TableFromUtfProc} -body { encoding convertfrom -profile tcl8 ascii AÁ } -result AÁ test encoding-19.3 {TableFromUtfProc} -body { - encoding convertfrom ascii AÁ + encoding convertfrom -profile strict ascii AÁ } -returnCodes 1 -result {unexpected byte sequence starting at index 1: '\xC1'} test encoding-19.4 {TableFromUtfProc} -body { - list [encoding convertfrom -failindex idx ascii AÁ] [set idx] -} -result {A 1} + list [encoding convertfrom -profile tcl8 -failindex idx ascii AÁ] [set idx] +} -result [list A\xC1 -1] test encoding-19.5 {TableFromUtfProc} -body { - list [encoding convertfrom -failindex idx ascii AÁ] [set idx] + list [encoding convertfrom -failindex idx -profile strict ascii A\xC1] [set idx] } -result {A 1} test encoding-19.6 {TableFromUtfProc} -body { - list [encoding convertfrom -failindex idx ascii AÁB] [set idx] + list [encoding convertfrom -failindex idx -profile strict ascii AÁB] [set idx] } -result {A 1} test encoding-20.1 {TableFreefProc} { @@ -766,7 +766,7 @@ test encoding-24.3 {EscapeFreeProc on open channels} {stdio} { } [list 3 "乎乞也 (\\u4E4E\\u4E5E\\u4E5F)"] test encoding-24.4 {Parse valid or invalid utf-8} { - string length [encoding convertfrom -profile tcl8 utf-8 "\xC0\x80"] + string length [encoding convertfrom utf-8 "\xC0\x80"] } 1 test encoding-24.5 {Parse valid or invalid utf-8} { string length [encoding convertfrom -profile tcl8 utf-8 "\xC0\x81"] @@ -790,10 +790,10 @@ test encoding-24.11 {Parse valid or invalid utf-8} { string length [encoding convertfrom -profile tcl8 utf-8 "\xEF\xBF\xBF"] } 1 test encoding-24.12 {Parse valid or invalid utf-8} -body { - encoding convertfrom utf-8 "\xC0\x81" + encoding convertfrom -profile strict utf-8 "\xC0\x81" } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xC0'} test encoding-24.13 {Parse valid or invalid utf-8} -body { - encoding convertfrom utf-8 "\xC1\xBF" + encoding convertfrom -profile strict utf-8 "\xC1\xBF" } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xC1'} test encoding-24.14 {Parse valid or invalid utf-8} { string length [encoding convertfrom utf-8 "\xC2\x80"] @@ -810,8 +810,11 @@ test encoding-24.17 {Parse valid or invalid utf-8} -constraints testbytestring - test encoding-24.18 {Parse valid or invalid utf-8} -constraints testbytestring -body { encoding convertto utf-8 [testbytestring "Z\xE0\x80xxxxxx"] } -result "Z\xC3\xA0\xE2\x82\xACxxxxxx" -test encoding-24.19 {Parse valid or invalid utf-8} -body { - encoding convertto utf-8 "ZX\uD800" +test encoding-24.19.1 {Parse valid or invalid utf-8} -body { + encoding convertto -profile tcl8 utf-8 "ZX\uD800" +} -result ZX\xED\xA0\x80 +test encoding-24.19.2 {Parse valid or invalid utf-8} -body { + encoding convertto -profile strict utf-8 "ZX\uD800" } -returnCodes 1 -match glob -result "unexpected character at index 2: 'U+00D800'" test encoding-24.20 {Parse with -profile tcl8 but without providing encoding} -body { encoding convertfrom -profile tcl8 "\x20" @@ -825,26 +828,26 @@ test encoding-24.22 {Syntax error, two encodings} -body { test encoding-24.23 {Syntax error, two encodings} -body { encoding convertto iso8859-1 utf-8 "ZX\uD800" } -result {bad option "iso8859-1": must be -profile or -failindex} -returnCodes error -test encoding-24.24 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 "\xC0\x80\x00\x00" +test encoding-24.24 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 "\xC0\x80\x00\x00" } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xC0'} -test encoding-24.25 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 "\x40\x80\x00\x00" +test encoding-24.25 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 "\x40\x80\x00\x00" } -returnCodes 1 -result {unexpected byte sequence starting at index 1: '\x80'} -test encoding-24.26 {Parse valid utf-8 with} -body { - encoding convertfrom utf-8 "\xF1\x80\x80\x80" +test encoding-24.26 {Parse valid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 "\xF1\x80\x80\x80" } -result \U40000 -test encoding-24.27 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 "\xF0\x80\x80\x80" +test encoding-24.27 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 "\xF0\x80\x80\x80" } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xF0'} -test encoding-24.28 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 "\xFF\x00\x00" +test encoding-24.28 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 "\xFF\x00\x00" } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xFF'} test encoding-24.29 {Parse invalid utf-8} -body { encoding convertfrom utf-8 \xEF\xBF\xBF } -result \uFFFF -test encoding-24.30 {Parse noncharacter with} -body { - encoding convertfrom utf-8 \xEF\xBF\xBF +test encoding-24.30 {Parse noncharacter with -profile strict} -body { + encoding convertfrom -profile strict utf-8 \xEF\xBF\xBF } -result \uFFFF test encoding-24.31 {Parse invalid utf-8 with -profile tcl8} -body { encoding convertfrom -profile tcl8 utf-8 \xEF\xBF\xBF @@ -852,8 +855,8 @@ test encoding-24.31 {Parse invalid utf-8 with -profile tcl8} -body { test encoding-24.32 {Try to generate invalid utf-8} -body { encoding convertto utf-8 \uFFFF } -result \xEF\xBF\xBF -test encoding-24.33 {Try to generate noncharacter with} -body { - encoding convertto utf-8 \uFFFF +test encoding-24.33 {Try to generate noncharacter with -profile strict} -body { + encoding convertto -profile strict utf-8 \uFFFF } -result \xEF\xBF\xBF test encoding-24.34 {Try to generate invalid utf-8 with -profile tcl8} -body { encoding convertto -profile tcl8 utf-8 \uFFFF @@ -861,23 +864,26 @@ test encoding-24.34 {Try to generate invalid utf-8 with -profile tcl8} -body { test encoding-24.35 {Parse invalid utf-8} -constraints utf32 -body { encoding convertfrom -profile tcl8 utf-8 \xED\xA0\x80 } -result \uD800 -test encoding-24.36 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 \xED\xA0\x80 +test encoding-24.36 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 \xED\xA0\x80 } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xED'} test encoding-24.37 {Parse invalid utf-8 with -profile tcl8} -body { encoding convertfrom -profile tcl8 utf-8 \xED\xA0\x80 } -result \uD800 -test encoding-24.38 {Try to generate invalid utf-8} -body { - encoding convertto utf-8 \uD800 +test encoding-24.38.1 {Try to generate invalid utf-8} -body { + encoding convertto -profile tcl8 utf-8 \uD800 +} -result \xED\xA0\x80 +test encoding-24.38.2 {Try to generate invalid utf-8} -body { + encoding convertto -profile strict utf-8 \uD800 } -returnCodes 1 -result {unexpected character at index 0: 'U+00D800'} -test encoding-24.39 {Try to generate invalid utf-8 with} -body { - encoding convertto utf-8 \uD800 +test encoding-24.39 {Try to generate invalid utf-8 with -profile strict} -body { + encoding convertto -profile strict utf-8 \uD800 } -returnCodes 1 -result {unexpected character at index 0: 'U+00D800'} test encoding-24.40 {Try to generate invalid utf-8 with -profile tcl8} -body { encoding convertto -profile tcl8 utf-8 \uD800 } -result \xED\xA0\x80 -test encoding-24.41 {Parse invalid utf-8 with} -body { - encoding convertfrom utf-8 \xED\xA0\x80\xED\xB0\x80 +test encoding-24.41 {Parse invalid utf-8 with -profile strict} -body { + encoding convertfrom -profile strict utf-8 \xED\xA0\x80\xED\xB0\x80 } -returnCodes 1 -result {unexpected byte sequence starting at index 0: '\xED'} test encoding-24.42 {Parse invalid utf-8, fallback to cp1252 [885c86a9a0]} -body { encoding convertfrom -profile tcl8 utf-8 \xF0\x80\x80\x80 @@ -885,11 +891,11 @@ test encoding-24.42 {Parse invalid utf-8, fallback to cp1252 [885c86a9a0]} -body test encoding-24.43 {Parse invalid utf-8, fallback to cp1252 [885c86a9a0]} -body { encoding convertfrom -profile tcl8 utf-8 \x80 } -result \u20AC -test encoding-24.44 {Try to generate invalid ucs-2 with} -body { - encoding convertto ucs-2 \uD800 +test encoding-24.44 {Try to generate invalid ucs-2 with -profile strict} -body { + encoding convertto -profile strict ucs-2 \uD800 } -returnCodes 1 -result {unexpected character at index 0: 'U+00D800'} -test encoding-24.45 {Try to generate invalid ucs-2 with} -body { - encoding convertto ucs-2 \U10000 +test encoding-24.45 {Try to generate invalid ucs-2 with -profile strict} -body { + encoding convertto -profile strict ucs-2 \U10000 } -returnCodes 1 -result {unexpected character at index 0: 'U+010000'} file delete [file join [temporaryDirectory] iso2022.txt] diff --git a/tests/io.test b/tests/io.test index 7239d33..e5cde41 100644 --- a/tests/io.test +++ b/tests/io.test @@ -9264,29 +9264,27 @@ test io-75.5 {invalid utf-8 encoding read is ignored (-profile tcl8)} -setup { removeFile io-75.5 } -result 4181 -test io-75.6 {invalid utf-8 encoding, read is not ignored (-profile strict)} -setup { +test io-75.6 {invalid utf-8 encoding, gets is not ignored (-profile strict)} -setup { set fn [makeFile {} io-75.6] set f [open $fn w+] fconfigure $f -encoding binary - # \x81 is invalid in utf-8 + # \x81 is an incomplete byte sequence in utf-8 puts -nonewline $f A\x81 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict + fconfigure $f -encoding utf-8 -buffering none -eofchar {} \ + -translation lf -profile strict } -body { - try { - read $f - } on error {result options} { - set data [dict get $options -data] - } - lappend data $result + gets $f } -cleanup { close $f removeFile io-75.6 -} -match glob -result {A {error reading "*":\ - invalid or incomplete multibyte or wide character}} +} -match glob -returnCodes 1 -result {error reading "file*":\ + invalid or incomplete multibyte or wide character} -test io-75.7 {invalid utf-8 encoding eof handling (-profile strict)} -setup { +test io-75.7 { + invalid utf-8 encoding gets is not ignored (-profile strict) +} -setup { set fn [makeFile {} io-75.7] set f [open $fn w+] fconfigure $f -encoding binary @@ -9294,31 +9292,27 @@ test io-75.7 {invalid utf-8 encoding eof handling (-profile strict)} -setup { puts -nonewline $f A\x81 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict + fconfigure $f -encoding utf-8 -buffering none -eofchar {} -translation lf \ + -profile strict } -body { - try { - read $f - } on error {result options} { - set data [dict get $options -data] - } - lappend data $result - fconfigure $f -encoding iso8859-1 - lappend data [read $f] + read $f } -cleanup { close $f removeFile io-75.7 -} -match glob -result "A {error reading \"file*\":\ - invalid or incomplete multibyte or wide character} \x81" +} -match glob -returnCodes 1 -result {error reading "file*":\ + invalid or incomplete multibyte or wide character} test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup { set fn [makeFile {} io-75.8] set f [open $fn w+] fconfigure $f -encoding binary - # \x81 is invalid in utf-8, but since \x1A comes first, -eofchar takes precedence. + # \x81 is invalid in utf-8, but since \x1A comes first, -eofchar takes + # precedence. puts -nonewline $f A\x1A\x81 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A -translation lf -profile strict + fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A \ + -translation lf -profile strict } -body { set d [read $f] binary scan $d H* hd @@ -9330,6 +9324,30 @@ test io-75.8 {invalid utf-8 encoding eof handling (-profile strict)} -setup { removeFile io-75.8 } -result {41 1 {}} +test io-75.8.eoflater {invalid utf-8 encoding eof handling (-profile strict)} -setup { + set res {} + set fn [makeFile {} io-75.8] + set f [open $fn w+] + fconfigure $f -encoding binary + # \x81 is invalid in utf-8. -eofchar is not detected, because it comes later. + puts -nonewline $f A\x81\x1A + flush $f + seek $f 0 + fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A \ + -translation lf -profile strict +} -body { + after 1 + set status [catch {read $f} cres copts] + lappend res $status + lappend res [eof $f] + chan configure $f -encoding iso8859-1 + lappend res [read $f] + close $f + set res +} -cleanup { + removeFile io-75.8 +} -result "1 0 \x81" + test io-75.9 {unrepresentable character write passes and is replaced by ?} -setup { set fn [makeFile {} io-75.9] set f [open $fn w+] @@ -9342,27 +9360,33 @@ test io-75.9 {unrepresentable character write passes and is replaced by ?} -setu } -cleanup { close $f removeFile io-75.9 -} -match glob -result [list {A} {error writing "*": invalid or incomplete multibyte or wide character}] +} -match glob -result [list {A} {error writing "*":\ + invalid or incomplete multibyte or wide character}] test io-75.10 { incomplete multibyte encoding read is not ignored because "binary" sets profile to strict } -setup { + set res {} set fn [makeFile {} io-75.10] set f [open $fn w+] fconfigure $f -encoding binary puts -nonewline $f A\xC0 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -profile tcl8 -buffering none + fconfigure $f -encoding utf-8 -profile strict -buffering none } -body { set d [read $f] binary scan $d H* hd - set hd + lappend res $hd + return $res } -cleanup { close $f removeFile io-75.10 -} -result 41c0 + unset result +} -returnCodes 1 -match glob -result {error reading "file*":\ + invalid or incomplete multibyte or wide character} + # The current result returns the orphan byte as byte. # This may be expected due to special utf-8 handling. @@ -9377,30 +9401,45 @@ test io-75.11 {shiftjis encoding error read results in raw bytes} -setup { puts -nonewline $f A\x81\xFFA flush $f seek $f 0 - fconfigure $f -encoding shiftjis -buffering none -eofchar "" -translation lf -profile strict + fconfigure $f -encoding shiftjis -blocking 0 -eofchar {} -translation lf \ + -profile tcl8 } -body { - read $f + set d [read $f] + binary scan $d H* hd + lappend hd [catch {set d [read $f]} msg] + lappend hd $msg } -cleanup { close $f removeFile io-75.11 -} -match glob -returnCodes 1 -result {error reading "*": invalid or incomplete multibyte or wide character} +} -match glob -result {4181ff41 0 {}} -test io-75.12 {invalid utf-8 encoding read is ignored} -setup { +test io-75.12 { + invalid utf-8 encoding read is not ignored because setting the encoding to + "binary" also set the profile to strict +} -setup { + set res {} set fn [makeFile {} io-75.12] set f [open $fn w+] fconfigure $f -encoding binary puts -nonewline $f A\x81 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -profile tcl8 -buffering none -eofchar "" -translation lf + fconfigure $f -encoding utf-8 -buffering none -eofchar {} -translation lf } -body { + catch {read $f} errmsg + lappend res $errmsg + chan configure $f -profile tcl8 + seek $f 0 set d [read $f] binary scan $d H* hd - set hd + lappend res $hd + return $res } -cleanup { close $f removeFile io-75.12 -} -result 4181 + unset res +} -match glob -result {{error reading "file*":\ + invalid or incomplete multibyte or wide character} 4181} test io-75.13 { In nonblocking mode when there is an encoding error the data that has been successfully read so far is returned first and then the error is returned @@ -9413,13 +9452,78 @@ test io-75.13 { puts -nonewline $f A\x81 flush $f seek $f 0 - fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict + fconfigure $f -encoding utf-8 -blocking 0 -eofchar {} -translation lf \ + -profile strict } -body { - read $f + set d [read $f] + binary scan $d H* hd + lappend hd [catch {read $f} msg] + lappend hd $msg } -cleanup { close $f removeFile io-75.13 -} -match glob -returnCodes 1 -result {error reading "file*": invalid or incomplete multibyte or wide character} +} -match glob -result {41 1 {error reading "file*":\ + invalid or incomplete multibyte or wide character}} + +test io-75.14 { + [gets] succesfully returns lines prior to error + + invalid utf-8 encoding [gets] continues in non-strict mode after error +} -setup { + set chan [file tempfile] + fconfigure $chan -encoding binary + # \xc0\n is an invalid utf-8 sequence + puts -nonewline $chan a\nb\nc\xc0\nd\n + flush $chan + seek $chan 0 + fconfigure $chan -encoding utf-8 -buffering none -eofchar {} \ + -translation auto -profile strict +} -body { + lappend res [gets $chan] + lappend res [gets $chan] + set status [catch {gets $chan} cres copts] + lappend res $status $cres + chan configure $chan -profile tcl8 + lappend res [gets $chan] + lappend res [gets $chan] + close $chan + return $res +} -returnCodes 1 -match glob -result {error reading "*":\ + invalid or incomplete multibyte or wide character} + +test io-75.15 { + invalid utf-8 encoding strict + gets does not hang + gets succeeds for the first two lines +} -setup { + set res {} + set chan [file tempfile] + fconfigure $chan -encoding binary + # \xc0\x40 is an invalid utf-8 sequence + puts $chan hello\nAB\nCD\xc0\x40EF\nGHI + seek $chan 0 +} -body { + #Now try to read it with [gets] + fconfigure $chan -encoding utf-8 -profile strict + lappend res [gets $chan] + lappend res [gets $chan] + set status [catch {gets $chan} cres copts] + lappend res $status $cres + set status [catch {gets $chan} cres copts] + lappend res $status $cres + chan configure $chan -translation binary + set data [read $chan 4] + foreach char [split $data {}] { + scan $char %c ord + lappend res [format %x $ord] + } + fconfigure $chan -encoding utf-8 -profile strict -translation auto + lappend res [gets $chan] + lappend res [gets $chan] + return $res +} -cleanup { + close $chan +} -returnCodes 1 -match glob -result {error reading "*": invalid or incomplete multibyte or wide character} # ### ### ### ######### ######### ######### @@ -9474,7 +9578,8 @@ test io-76.4 {channel mode dropping} -setup { } -returnCodes error -cleanup { close $f removeFile dummy -} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"} +} -match glob -result {Tcl_RemoveChannelMode error:\ + Bad mode, would make channel inacessible. Channel: "*"} test io-76.5 {channel mode dropping} -setup { set datafile [makeFile {some characters} dummy] @@ -9495,7 +9600,8 @@ test io-76.6 {channel mode dropping} -setup { } -returnCodes error -cleanup { close $f removeFile dummy -} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"} +} -match glob -result {Tcl_RemoveChannelMode error:\ + Bad mode, would make channel inacessible. Channel: "*"} test io-76.7 {channel mode dropping} -setup { set datafile [makeFile {some characters} dummy] @@ -9528,7 +9634,8 @@ test io-76.9 {channel mode dropping} -setup { } -returnCodes error -cleanup { close $f removeFile dummy -} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"} +} -match glob -result {Tcl_RemoveChannelMode error:\ + Bad mode, would make channel inacessible. Channel: "*"} test io-76.10 {channel mode dropping} -setup { set datafile [makeFile {some characters} dummy] @@ -9539,7 +9646,8 @@ test io-76.10 {channel mode dropping} -setup { } -returnCodes error -cleanup { close $f removeFile dummy -} -match glob -result {Tcl_RemoveChannelMode error: Bad mode, would make channel inacessible. Channel: "*"} +} -match glob -result {Tcl_RemoveChannelMode error:\ + Bad mode, would make channel inacessible. Channel: "*"} # cleanup foreach file [list fooBar longfile script script2 output test1 pipe my_script \ diff --git a/tests/ioCmd.test b/tests/ioCmd.test index b3e29b1..366e3fb 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -1058,7 +1058,7 @@ test iocmd-23.1 {chan read, regular data return} -match glob -body { rename foo {} set res } -result {{read rc* 4096} {read rc* 4096} snarfsnarf} -test iocmd-23.2 {chan read, bad data return, to much} -match glob -body { +test iocmd-23.2 {chan read, bad data return, too much} -match glob -body { set res {} proc foo {args} { oninit; onfinal; track @@ -2369,7 +2369,7 @@ test iocmd.tf-23.1 {chan read, regular data return} -match glob -body { rename foo {} set res } -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf} -test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body { +test iocmd.tf-23.2 {chan read, bad data return, too much} -match glob -body { set res {} proc foo {args} { oninit; onfinal; track diff --git a/tools/regexpTestLib.tcl b/tools/regexpTestLib.tcl index 2687e67..c5c156e 100644 --- a/tools/regexpTestLib.tcl +++ b/tools/regexpTestLib.tcl @@ -42,7 +42,7 @@ proc readInputFile {} { # # strings with embedded @'s are truncated -# unpreceeded @'s are replaced by {} +# unpreceded @'s are replaced by {} # proc removeAts {ls} { set len [llength $ls] diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 077500a..126b3a7 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -141,7 +141,7 @@ _tmain( TclZipfs_AppHook(&argc, &argv); #endif - Tcl_Main((size_t)argc, argv, TCL_LOCAL_APPINIT); + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } |
